3

このアプリケーションでは、次の方法で参照カーソルを返すさまざまなストアド プロシージャを呼び出します。

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。これは、カーソルが実際に閉じられたことを意味します。それでも、開いているカーソルの数はまだ増加しているようです!

4

1 に答える 1

1

ISOPEN関数からチェックを削除しwrap_xml、すべての場合でカーソルを閉じるコマンドを実行するだけで、リークを塞いだようです。明らかに、ISOPEN動的 SQL クエリ用に開かれたカーソルにはフラグが設定されていません。

ただし、これに関する参照を見つけることができません。誰もこれをバックアップできますか?

于 2013-08-08T06:32:14.723 に答える