为什么流水线函数像正常的 table 函数一样工作?

Why the pipelined function working like normal table function?

我创建了一个流水线函数和另一个非流水线函数。
但是当从 select 语句调用这两个函数时,所有结果仅在循环执行完成后显示。

为什么流水线函数没有在每一行的数据准备好后立即返回值?

SELECT * FROM TABLE(GET_TAB(10,1));--Normal function call
SELECT * FROM TABLE(GET_TAB_P(10,1));--Pipelined function call

create or replace TYPE T_TF_ROW AS OBJECT(CNT NUMBER, DESCRIPTION VARCHAR2(50));
create or replace TYPE T_TF_TAB AS TABLE OF T_TF_ROW;

create or replace FUNCTION GET_TAB(P_ROWS IN NUMBER, P_SLEEP IN NUMBER)
RETURN T_TF_TAB
AS
V_T_TF_TAB T_TF_TAB:=T_TF_TAB();
BEGIN
FOR I IN 1..P_ROWS LOOP
DBMS_LOCK.SLEEP(P_SLEEP);
V_T_TF_TAB.EXTEND;
V_T_TF_TAB(V_T_TF_TAB.LAST):=T_TF_ROW(I,'DESCRIPTION OF : '||I);
END LOOP;
RETURN V_T_TF_TAB;
END;


create or replace FUNCTION GET_TAB_P(P_ROWS IN NUMBER, P_SLEEP IN NUMBER)
RETURN T_TF_TAB PIPELINED
AS
BEGIN
FOR I IN 1..P_ROWS LOOP
DBMS_LOCK.SLEEP(P_SLEEP);
PIPE ROW(T_TF_ROW(I,'DESCRIPTION FOR ' || I));
END LOOP;
RETURN;
END;

Normal function result

Pipelined function result

您的流水线函数工作正常,但您的客户端的获取大小优化在 returns 之前一次检索 N 行。禁用或降低获取大小,您应该开始看到返回的单独行。但是,在生产环境中,您不想禁用该优化。

在 SQL*Plus 中,您将 运行 此命令一次查看一行:

set arraysize 1;

(实际上一次 returns 两行 行,原因我不记得了。有一个解决方法,但除非你正在写某种进度条程序,您可能不关心一次只获得一行。)