SqlServer から Oracle 12c に .net アプリケーションを移植しています。アンマネージド 64 ビット ODAC 12c リリース 2 (12.1.0.1.2) クライアントを使用してデータベースにアクセスしています。
Oracle 12c では DBMS_SQL.RETURN_RESULT(cur) 関数が導入され、ado.net コマンドに特定の出力パラメーターを追加しなくても、.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 エラーが発生することです。
DBMS_SQL.RETURN_RESULT(cv_1) 関数を使用せずに、結果セット カーソルを出力パラメーターとして返す古い Oracle 11g アプローチを使用すると、接続プールの有無に関係なく、connectionScope が破棄されるため、カーソルが正しく閉じられます。
暗黙の参照カーソルを閉じるために必要な追加のオブジェクトはありますか? これは ODAC 12cR2 の既知のバグですか? DBMS_SQL.RETURN_RESULT(cv_1) の導入により、SqlServer から Oracle への移植は、ほぼすべての場所に出力パラメーターを追加するよりも簡単になりますが、接続プールを取り除きたくありません。