1

我正在将 .net 应用程序从 SqlServer 移植到 Oracle 12c。我正在使用非托管 64 位 ODAC 12c Release 2 (12.1.0.1.2) 客户端访问数据库。

Oracle 12c 引入了 DBMS_SQL.RETURN_RESULT(cur) 函数,它允许我按原样重用 .net 代码,而无需向 ado.net 命令添加特定的输出参数。这是我的代码的一个片段:

using (var command = CreateCommand("uspGetAllNumericUnits", CommandType.StoredProcedure))
        {
            using (var connectionScope = command.Connection.CreateConnectionScope())
            {
                using (var reader = command.ExecuteReader())
                {
                    if (reader.HasRows)
                    {
                        while (reader.Read())
                        {
                            ....
                        }
                    }
                }
            }
        }   

uspGetAllNumericUnits 存储过程就像:

PROCEDURE uspGetAllNumericUnits_RPT
AS
  cv_1 SYS_REFCURSOR;
BEGIN
  OPEN cv_1 FOR
      SELECT * FROM NumericUnit;

  DBMS_SQL.RETURN_RESULT(cv_1);
END;

我相信我正确地处理了 dbReader 和 dbCommand,并且连接也被 connectionScope 关闭和处理了。但是,如果我检查服务器上的 v$open_cursor 视图,我会看到“SELECT * FROM NumericUnit;”的光标 保持打开状态。我使用连接池,如果我禁用它(我不想这样做),光标会在 connectionScope 被释放时正确关闭。

我的问题是我有很多像这样的 ado.net 调用,我很快就达到了每个会话允许的最大游标限制,并引发了 ORA-01000 错误。

如果我使用旧的 Oracle 11g 方法,将结果集游标作为输出参数返回,并且不使用 DBMS_SQL.RETURN_RESULT(cv_1) 函数,则无论连接池与否,都会在释放 connectionScope 时正确关闭游标。

我需要一些额外的对象来处理隐式引用游标的关闭吗?这是一个已知的 ODAC 12cR2 错误吗?DBMS_SQL.RETURN_RESULT(cv_1) 的引入使得从 SqlServer 到 Oracle 的移植比几乎在任何地方都必须添加输出参数更容易,但我不想摆脱连接池。

4

0 回答 0