2008-12-11 236 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子句。