6

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

我有一个 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;

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


更新:

感谢您的输入。我在打电话

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

但把它们排除在我的例子之外。

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

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

4

2 回答 2

10

ODP.NET 要求你清理东西。那么你:

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

Iow:清理你创造的东西。

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

于 2008-12-11T08:46:54.290 回答
0

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

于 2008-12-11T01:40:31.387 回答