为啥流水线函数像普通表函数一样工作?

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。

以上是关于为啥流水线函数像普通表函数一样工作?的主要内容,如果未能解决你的问题,请参考以下文章

Java函数式编程:流式计算

表函数和流水线函数的区别?

Oracle 流水线表函数并将结果插入到 Oracle 表中

如何使用光标创建流水线函数并返回表?

如何在“流水线表函数”、视图和显式游标之间进行选择

Java函数式编程之Stream流编程