为啥流水线函数像普通表函数一样工作?
Posted
技术标签:
【中文标题】为啥流水线函数像普通表函数一样工作?【英文标题】:Why the pipelined function working like normal table function?为什么流水线函数像普通表函数一样工作? 【发布时间】:2020-11-25 19:00:10 【问题描述】:我创建了一个流水线函数和另一个非流水线函数。 但是从 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
【问题讨论】:
请编辑问题并显示正在执行 SELECT 的调用代码 【参考方案1】:您的流水线函数工作正常,但您的客户端的提取大小优化是在返回任何内容之前一次检索 N 行。禁用或降低提取大小,您应该开始看到返回的各个行。但是,在生产环境中,您确实不想禁用该优化。
在 SQL*Plus 中,您可以运行以下命令来查看一行一行:
set arraysize 1;
(实际上一次返回 两 行,原因我不记得了。有一个解决方法,但除非你正在编写某种进度条程序,否则你可能不会关心一次只得到一行。)
【讨论】:
一个我不记得的原因,原因是一行预取——显示行预取;默认1。以上是关于为啥流水线函数像普通表函数一样工作?的主要内容,如果未能解决你的问题,请参考以下文章