2012-08-15 48 views
1

在我的存儲過程,我有一個代碼片段是這樣的:使用SYS_REFCURSOR填充一個Oracle集合類型和關閉遊標

OPEN p_result FOR 
SELECT * 
FROM TABLE (CAST (l_data AS Rpt_mapping_TableType)); 
COMMIT; 

p_resultSYS_REFCURSOR類型的IN OUT參數。 Rpt_mapping_TableType是用戶定義的集合類型。 所以這個遊標只會填充Rpt_mapping_TableType,然後調用這個proc的程序將讀取Rpt_mapping_TableType的結果。 我的問題是COMMIT在這段代碼中的用法是什麼?代碼作者說這是一種關閉遊標的方法。這樣對嗎?我的另一個問題是,如果我只想填充集合,我甚至需要做OPEN p_result FOR。畢竟我沒有從光標讀取任何東西,所以:

SELECT * FROM TABLE (CAST (l_data AS Rpt_mapping_TableType)); 

應該就足夠了。

不是?

回答

1

提交不會關閉遊標。如果是這樣,那麼你的代碼將無法工作。 (雖然它可能從FOR UPDATE解鎖行,引起其他問題。)下面是一個承諾不關閉遊標的例子:

SQL> variable test refcursor 
SQL> begin 
    2 open :test for select 1 from dual; 
    3 end; 
    4/

PL/SQL procedure successfully completed. 

SQL> commit; 

Commit complete. 

SQL> print test; 

     1 
---------- 
     1 

SQL> 

如果你只是要填充的集合,你可能會更好使用的東西像SELECT ... BULK COLLECT INTO ...代替。 (並可能使用LIMIT。)關鍵字CURSOR經常被過度使用。除非將數據傳遞給另一個程序,否則隱式遊標和批量收集通常更簡單快捷。