2016-08-17 41 views
1

我有一個過程,它將光標作爲輸出參數返回。在SP內部,輸出遊標變量作爲SELECT語句打開。我將重複使用此遊標中的記錄來獲取SP中的以下邏輯,並使用BULK COLLECT子句將它們存儲在嵌套表中。但是發現,沒有任何異常,這個嵌套表沒有被填充。 我寫了一個簡單的例子來說明這個問題:BULK COLLECT INTO OPEN cursor FOR SELECT ...不填充集合

create table temp_table as 
select 1 as col1 from dual 
union all 
select 2 as col1 from dual; 

declare 
    v_cur sys_refcursor; 
    v_rec temp_table%rowtype; 
    procedure get_cursor(v_cur OUT sys_refcursor) is 
    type typ_temp_tab_tab is table of temp_table%rowtype; 
    v_tab typ_temp_tab_tab; 
    begin 
    v_tab:=typ_temp_tab_tab(); 
    open v_cur for 
     select * 
     bulk collect into v_tab 
     from temp_table; 
    dbms_output.put_line('nested table''s records num: '||v_tab.count); 
    end; 
begin 
    get_cursor(v_cur); 
    dbms_output.put_line('values in cursor: '); 
    loop 
    fetch v_cur into v_rec; 
    exit when v_cur%NOTFOUND; 
    dbms_output.put_line('>>'||v_rec.col1); 
    end loop; 
end; 
/
drop table temp_table; 

和輸出是:

nested table's records num: 0 
values in cursor: 
>>1 
>>2 

你有爲什麼它不工作,什麼是重複使用的最佳實踐的任何想法遊標在SP內的記錄?

+0

你不能這樣做。 (我很驚訝它不會抱怨這種語法)。如果您不使用遊標內容,則無法獲取遊標內容,因此如果您打算填充嵌套表格,調用程序將看不到遊標中剩下的任何內容。你爲什麼需要兩個?嵌套表可以在模式級聲明,而不是作爲本地PL/SQL類型聲明? –

+0

@AlexPoole,謝謝!是的,似乎是這樣。不消耗循環遊標的光標不能填充嵌套表格。我也想知道爲什麼這樣的語法不會導致錯誤。我需要它,因爲第一我應該返回一個遊標到應用程序,第二我需要使用相同的結果集來插入它。我可以將這個查詢包裝在一個表函數中,但它會看起來更復雜一點,我需要實現獨立的嵌套表類型。 –

+0

如果要創建獨立表類型,則只需執行一次查詢 - 批量收集查詢,然後針對集合打開遊標。 –

回答

3

你不寫:

open v_cur for 
     select * 
     bulk collect into v_tab 
     from temp_table; 

你只需要:

select * 
    bulk collect into v_tab 
    from temp_table; 

否 「open v_cur for」。

不幸的是,我認爲這意味着你不能同時擁有嵌套表中的數據和(B)將打開的遊標返回給調用者而不運行查詢兩次。 Oracle必須獲取光標中的所有行才能執行BULK COLLECT,此後光標將無用回傳給調用者。

+0

謝謝!當我寫代碼時,甲骨文沒有抱怨,我很高興我找到了一種方法來同時執行A和B.不幸的是我錯了:)我將實現一個獨立的表類型並重寫這段代碼。 –

+0

如果你真的想要在PL/SQL集合中填充(A)和(B)作爲打開的遊標返回給調用者的結果,那麼可以通過首先將BULK COLLECT放入集合中而不執行查詢兩次,正如我在回答中所顯示的,然後執行'OPEN v_cur FOR SELECT * FROM TABLE(temp_table)'。爲此,您需要在數據庫中將'typ_temp_tab_tab'設置爲'OBJECT'。或者,如果您正在運行12c,則可以在包規範中定義'TYPE'並使用它。 –

+0

謝謝,我已經完全按照您所描述的方式執行該操作。我希望我們都有12c :) –