我有一个像这样的流水线功能:
pipe row(mytype('1','1','1'));
pipe row(mytype('2','2','2'));
pipe row(mytype('3','3','3'));
pipe row(mytype('4','4','4'));
return;
我还有另一个使用游标读取此过程的过程:
for c_cursor in(
SELECT field1 FROM table(mytable))
loop
v_Var1:=c_cursor.field1;
if((v_Var1 = '1')) then
return;
end if;
end loop;
我需要知道Oracle是否会在return
之后处理其他行(2,3和4),否则它将停止管道。
感谢。
答案 0 :(得分:2)
这很容易测试:
create function pipetest return sys.odcinumberlist pipelined as
begin
for i in 1..5 loop
pipe row(i);
dbms_output.put_line('Piped ' || i);
end loop;
return;
end;
/
set serveroutput on size unlimited
begin
for r in (select * from table(pipetest)) loop
dbms_output.put_line('Got ' || r.column_value);
return;
end loop;
end loop;
/
anonymous block completed
Piped 1
Piped 2
Piped 3
Piped 4
Piped 5
Got 1
但是有多少行取决于获取大小;如果你管道1000行代替:
create function pipetest return sys.odcinumberlist pipelined as
begin
for i in 1..1000 loop
...
然后(对我来说)它在第一次批量获取后停止:
anonymous block completed
Piped 1
Piped 2
Piped 3
... <snipped for brevity> ...
Piped 97
Piped 98
Piped 99
Got 1
因此,在调用块开始遍历它们之前,第一次获取有100行。如果我改变以后发生的回报:
if r.column_value = 101 then
return;
end if;
然后我看到了:
anonymous block completed
Piped 1
Piped 2
Piped 3
...
Piped 97
Piped 98
Piped 99
Got 1
Got 2
Got 3
...
Got 96
Got 97
Got 98
Got 99
Got 100
Piped 100
Piped 101
Piped 102
Piped 103
...
Piped 197
Piped 198
Piped 199
Got 101
因此函数可能会在调用者返回后处理更多行,但它不一定会处理所有行。
正如您在评论中提到的,如果您打开游标并一次获取一行,它的行为会有所不同:
set serveroutput on size unlimited
declare
cursor c is select * from table(pipetest);
n number;
begin
open c;
loop
fetch c into n;
exit when c%notfound;
dbms_output.put_line('Got ' || n);
if n = 3 then
return;
end if;
end loop;
close c;
end loop;
/
anonymous block completed
Got 1
Piped 1
Got 2
Piped 2
Got 3
停止提取时,该功能仍会停止处理。这里唯一的区别是获取大小为1.对于批量收集,它的行为类似于原始的'for'循环,但您可以使用limit子句来查看具有的效果;
set serveroutput on size unlimited
declare
cursor c is select * from table(pipetest);
t sys.odcinumberlist;
begin
open c;
loop
fetch c bulk collect into t limit 10;
for i in 1..t.count loop
dbms_output.put_line('Got ' || t(i));
if t(i) = 3 then
return;
end if;
end loop;
exit when t.count < 10;
end loop;
close c;
end loop;
/
anonymous block completed
Piped 1
Piped 2
Piped 3
Piped 4
Piped 5
Piped 6
Piped 7
Piped 8
Piped 9
Got 1
Got 2
Got 3
如果您担心该功能产生的副作用,那么阻止它处理超出调用者停止条件的唯一方法就是进行单行提取。