我想写一个简单的 tail -f
实用程序来“跟踪”数据库中某些数字的进度:
create or replace function tail_f return varchar2_tab pipelined as
n number;
begin
loop
exit when ...
select count(*) into n from ... where ...;
pipe row(sysdate || ' n= ' || n);
dbms_lock.sleep(60);
end loop;
return;
end tail_f;
Run Code Online (Sandbox Code Playgroud)
然后我想select * from table(tail_f)
在 SQL*Plus 中。
为了一一获取行,我SET ARRAYSIZE 1
. 然而,记录(第一个除外)是成对获取的。
对此是否有解释,以及如何在通过管道传输后立即获取记录?
Metalink 错误 9103343 指出:
这是预期的行为。SQL*Plus 是用 oci 编写的,oci 的默认预取值为 1 行。然而,预取时(而不是执行时)仅在您不执行数组提取时发生,因此当 arraysize 为 1 时。无论数组大小如何,跟踪中的第一个提取始终为 1 行,因为 1 行是预取的执行。然后它要么执行标量提取,所以一个请求的行加上一个预取的行,或者它执行一个数组提取,所以你看到例如:a) arraysize = 1,提取是:1, 2, 2, ... b) arraysize = 2, fetches 是: 1, 2, 2, ... c) arraysize = 5, fetches 是: 1, 5, 5, ...
另请参阅 Metalink 文档 1265916.1
这似乎是 SQL*Plus 的一个怪癖,arraysize
而不是流水线函数 - 下面演示了相同的效果:
create or replace function pause return integer as
begin
dbms_lock.sleep(2);
return 1;
end;
/
select pause from dual connect by level<10;
Run Code Online (Sandbox Code Playgroud)
您可以(某种程度上)通过选择行两次并每隔一秒丢弃一次来解决该问题:
select /*+ ordered first_rows(1) */ *
from table(tail_f) cross join (select level from dual connect by level<=2);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1774 次 |
最近记录: |