【问题标题】:Does ODP.net close a ref cursor when the connection closes?当连接关闭时,ODP.net 会关闭引用游标吗?
【发布时间】:2010-09-26 08:48:16
【问题描述】:

我还没有在任何地方找到明确说明的这一点,但是我在网上找到的一堆示例遵循我一直在做的事情。

我有一个 C# 类,它使用 ODP.net 连接到 Oracle DB 并运行包中的过程。

我的包有存储过程,它采用 ref 游标输出参数。该过程所做的只是为特定的选择语句打开游标。

如果我直接在 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;

我只是害怕在 DB 上留下打开的游标。如果有人可以提供官方文档的链接,那就太好了!


更新:

感谢您的意见。我在打电话

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

但在我的示例中没有列出它们。

我发现这个论坛帖子,其中指出 OracleDataAdapter.Fill(Dataset) 方法在 Fill() 方法执行后确实释放了引用光标。
http://www.frontoracle.com/oracle-archive/140/386140-close-ref-cursor.html

我希望 Oracle 文档能更明确地描述这个过程。

【问题讨论】:

    标签: c# oracle odp.net


    【解决方案1】:

    ODP.NET 要求你清理东西。所以你:

    • 必须处理 OracleParameter 实例,因为它们包含非托管资源 (!) 而 Odp.net 不这样做
    • 必须释放 OracleCommand 对象,因为它们也包含非托管资源,并且关闭连接不会关闭这些资源
    • 如果没有打开的连接,打开的游标就无法生存,尽管在 odp.net 中,连接关闭(或被释放)后什么都不会被清理,所以你也必须清理这些(当然在连接关闭之前) .

    I.o.w.:清理你创造的东西。

    可能是 OracleDataAdapter 已经为您执行了此操作,但这尚不清楚(并且 odp.net 文档没有这么说,因此您必须使用反射器检查(不可读)代码以确保。虽然规则odp.net 的拇指:为避免内存泄漏,请始终按顺序对所有内容调用 dispose:参数、游标、命令、事务、连接。

    【讨论】:

    • 如果您使用它们,我会将 OracleDataReader 添加到要处理的对象列表中。它似乎解决了我们的“最大打开游标”问题。
    【解决方案2】:

    我不确定您是否偶然发现了this 文章,它并不直接适用于您的问题,但它说明了我在使用 ODP.Net 时学到的一些东西:如有疑问,请始终关闭 (连接)和处置。我编写的每个使用 ODP 连接、命令和/或游标实例的方法都有一个 finally 子句来处理所有内容。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-08
    • 1970-01-01
    • 2014-09-25
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多