2014-01-16 32 views
6
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; 

如果我的第二種情況是正確的,那麼上面的代碼是如何工作的?

回答

9

Pipelined功能,一個非常經典的例子就是您在SQL*Plus中做SELECT * FROM table name。會發生什麼事情呢,甲骨文從桌上流數據..

喜歡在YouTube上觀看視頻。

請注意這個詞,「」。而在我們的函數,我們定義我們有多少行流..每天行立即給調用者。 Pipelining意味着以平庸的態度,不要讓我等到你完成,給我你所擁有的,並且不斷地處理和更新我。

在你的最後一道工序,管道中的每一行之後,您啓動sleep呼籲10s,所以記錄是串流播放給調用者每10s。

而且,一個普通表函數將一直等待,直到完成所有處理工作,然後它將返回對結果集光標的引用。

流水線功能,他們聲稱節省內存,是由flushing內容立即,因此使用的緩衝區總是最小,而往返計數得到更高。

+1

精湛的解釋..很明顯.. – ramesh538

+0

謝謝,請接受,如果你滿意! :) –

+0

CREATE OR REPLACE FUNCTION FN_RET_COL RETURN TY_1_TABLE PIPELINED IS 在 BEGIN 對於i(SELECT名字,SALARY,HIRE_DATE FROM EMPLOYEES WHERE ROWNUM <11)環 PIPE ROW(TY_1(i.FIRST_NAME,i.SALARY, i.HIRE_DATE)); DBMS_LOCK.sleep(秒=> 1); end loop; END; SELECT A.FN,LOCALTIMESTAMP FROM TABLE(FN_RET_COL)A; 在這裏,我得到像表函數一樣的時間。爲什麼?其實它應該儘快返回一排管道。 – ramesh538