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

时间:2014-01-16 19:44:15

标签: oracle plsql pipelined-function

CREATE OR REPLACE TYPE ty_1 AS OBJECT ( fn VARCHAR2(100),
                                        sl NUMBER,
                                        hd DATE );
CREATE OR REPLACE TYPE ty_1_table AS TABLE OF ty_1;

CREATE OR REPLACE FUNCTION FN_RET_COL
  RETURN ty_1_table
AS
  c ty_1_table := TY_1_TABLE();
  BEGIN
    c.extend;
    C(1) := TY_1('A', 1, '10-JUN-2013');
    c.extend;
    C(2) := TY_1('B', 2, '11-JUN-2013');
    c.extend;
    C(3) := TY_1('C', 3, '12-JUN-2013');

    RETURN c;
  END;

CREATE OR REPLACE FUNCTION FN_RET_PIPE RETURN ty_1_table PIPELINED IS
  BEGIN
    PIPE ROW (TY_1('A', 1, '10-JUN-2013'));
    PIPE ROW (TY_1('B', 2, '11-JUN-2013'));
    PIPE ROW (TY_1('C', 3, '12-JUN-2013'));
  END;

SELECT * FROM TABLE (fn_ret_col);

SELECT * FROM TABLE (fn_ret_pipe);

第一个FN_RET_COL是常规表函数,第二个FN_RET_PIPE是流水线函数。 我在一本书中学习过 常规表函数要求在将集合返回到PIPELINED FUNCTION之前完全填充集合 使用PIPE ROW调用在创建行时将行推出函数,而不是构建表集合。在生成所有行之前保存内存并允许后续处理。     我怀疑的是:PIPELINED Function如何节省记忆? 如果我没有错,它将管道所有行并将它们存储在内存区域中,然后在控制台中打印所有行。或者就是这样,只要在控制台中传输新记录而不将其存储在任何地方,就会直接逐行打印?

CREATE OR REPLACE FUNCTION FN_RET_COL RETURN TY_1_TABLE
 PIPELINED IS
 BEGIN   
    PIPE ROW(TY_1('A',1,'10-JUN-2013'));
    DBMS_LOCK.sleep(seconds => 10);
    PIPE ROW(TY_1('B',2,'11-JUN-2013'));
    DBMS_LOCK.sleep(seconds => 10);
    PIPE ROW(TY_1('C',3,'12-JUN-2013'));
 END;

如果我的第二个案例是对的,那么上面的代码是如何工作的?

1 个答案:

答案 0 :(得分:10)

Pipelined个函数,一个非常经典的示例是您在SELECT * FROM table name中执行SQL*Plus的操作。会发生什么,Oracle从表中传输数据..

  

喜欢在youtube上观看视频。

请注意“ Streaming ”这个词。在我们的函数中,我们定义了流的行数。每个流式行都可以立即供调用者使用。 Pipelining以非专业人的方式表示,不要让我等到你完成,给我你所拥有的一切,并继续处理并同时更新我。

在上一个程序中,在对每一行进行管道传输后,您为sleep发起10s调用,因此每隔10秒就会将 Streamed 记录到调用方。

并且,正常的表函数将一直等待所有处理工作完成,然后它将返回对结果集游标的引用。

流水线函数,他们声称保存内存,立即通过flushing内容,因此使用的缓冲区总是最小的,而往返计数则更高。