このアプリケーションでは、次の方法で参照カーソルを返すさまざまなストアド プロシージャを呼び出します。
SELECT foo_package.sp_Bar('arg1', 'arg2', 'arg3', 'arg4') FROM dual;
wrap_xml
関数が行うことは、カーソルの結果を XML 型に変換することです。XML 型はアプリケーションで使用されます。変換後、すぐにカーソルを閉じます (この手順により、以前はメモリの問題が解決されていました)。
FUNCTION wrap_xml (c_result SYS_REFCURSOR)
RETURN XMLTYPE
IS
xml_val XMLTYPE;
BEGIN
xml_val := xmltype.CreateXML (c_result);
IF c_result%ISOPEN
THEN
CLOSE c_result;
END IF;
RETURN xml_val;
END;
ほとんどの場合、これは正常に機能しているように見えます。XML が作成され、カーソルが閉じられます。ただし、動的クエリのカーソルを開くストアド プロシージャを導入して以来、開いているカーソルが急速に増加しており、最終的には次のような結果になっています。
ORA-01000: maximum open cursors exceeded
動的クエリは、テスト目的で、他のカーソルから返される結果を「シミュレート」するために作成されます。たとえば、ストアド プロシージャは次のような動的クエリを作成します。
SELECT '1' as "COLUMN1", '990' as "COLUMN2", 'N' as "COLUMN3", NULL as "COLUMN5" FROM dual;
次に、このクエリ文字列のカーソルを開き、カーソルを返します。
OPEN rc_return FOR v_sql_query;
RETURN rc_return;
結果の参照カーソルは再びwrap_xml
上記の関数に渡され、他のカーソルと同じようにカーソルを閉じます。ただし、開いているカーソルの数が増え続けているため、そうではないようです。この理由は何でしょうか?
追加調査:
wrap_xml
関数をステップ実行すると、プログラム フローがチェックの本体をスキップしていることがわかりますc_result%ISOPEN
。これは、カーソルが実際に閉じられたことを意味します。それでも、開いているカーソルの数はまだ増加しているようです!