2008-12-11 108 views
5

我還沒有能夠在任何地方明確指出這一點,但我在網上找到的一些例子跟着我一直在做的事情。連接關閉時,ODP.net是否關閉了引用遊標?

我有一個C#類,它使用ODP.net連接到Oracle數據庫並運行包中的過程。

我的軟件包有存儲過程,需要一個參考光標輸出參數。所有的過程都是爲特定的選擇語句打開遊標。

如果我直接在oracle db上執行這個過程,那麼最終我會打最大數量的打開遊標錯誤。

所以我想知道ODP.net確實關閉了在我的程序中打開的這個遊標?

我正在使用OracleDataApaper.Fill(DataSet)方法。

例如。

DataSet ds = new DataSet(); 
OracleConnection conn = new OracleConnection(this.connStr); 
OracleCommand com = new OracleCommand("MYPKG.MYQUERY", conn); 
OracleDataAdapter adapter = new OracleDataAdapter(com); 
conn.Open(); 
com.Parameters.Add("searchParam", OracleDbType.Varchar2).Value = "myName"; 
com.Parameters.Add("outCursor", OracleDbType.RefCursor, ParameterDirection.Output); 
com.CommandType = CommandType.StoredProcedure; 

adapter.Fill(ds); 
conn.Close(); 




PROCEDURE GETALLEMAILS(searchParamIN VARCHAR2, outCursor OUT sys_refcursor) AS 
    BEGIN 
    open outCursor 
     select 
     EAEMAL as Email 
     from 
     EmailTable 
     where 
     EmailName = searchParam; 
    END GETALLEMAILS; 

我只是害怕在數據庫上留下打開的遊標是所有的。如果任何人都可以提供官方文檔的鏈接,那會很棒!


更新:

感謝您的輸入。我正在打電話

com.Dispose(); 
conn.Close(); 
conn.Dispose(); 

但讓他們不在我的例子中。

我發現這個論壇帖子,其中指出OracleDataAdapter.Fill(Dataset)方法在Fill()方法執行後釋放ref遊標。
http://www.frontoracle.com/oracle-archive/140/386140-close-ref-cursor.html

我希望Oracle文檔在描述這個過程時更加明確。

回答

9

ODP.NET要求你清理一些東西。所以你:

  • 來處置的OracleParameter的情況下,因爲它們包含非託管資源和Odp.net不這樣做
  • 來處置的OracleCommand對象,因爲它們也含有非託管資源和關閉(!)連接不關閉這些
  • 打開的遊標不能沒有打開的連接,雖然在odp.net連接關閉後(或處置)沒有得到清理,所以你也必須清理這些(以及之前當然連接關閉)。

I.o.w .:清理你創建的東西。

它可以是OracleDataAdapter已經這樣做了你,但目前還不清楚(和odp.net文檔不說這個了,所以,你檢查與反射器(不可讀)代碼,以確保。雖然規則與odp.net的拇指:爲了避免內存泄漏,總是調用處置,在所有的順序:參數,光標,命令,交易,連接。

+2

我會將OracleDataReader添加到要處置的對象列表,如果您使用它似乎解決了我們的「最大遊標光標」問題。 – Fueled 2011-12-02 16:07:36

0

我不確定您是否偶然發現了this文章,它並不直接適用於您的問題,但它說明了我在使用ODP.Net時學到的東西:如有疑問,請始終關閉(連接)並處置。我寫的每個使用ODP連接,命令和/或遊標實例的方法都有一個處理所有事情的finally子句。