sql >> データベース >  >> RDS >> Oracle

XMLType.createxmlで参照カーソルが失われます

    バグがあるようです。Oracleサポートへのサービスリクエストを開く必要があります。 9iと11.2.0.3での発見を再現するテストケースを投稿します:

    SQL> SHOW parameter open_cursors
    
    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    open_cursors                         integer     600
    
    SQL> CREATE OR REPLACE FUNCTION ret_cursor RETURN SYS_REFCURSOR IS
      2     l SYS_REFCURSOR;
      3  BEGIN
      4     OPEN l FOR
      5        SELECT * FROM dual;
      6     RETURN l;
      7  END;
      8  /
    
    Function created
    

    XMLTypeは、上記の関数で呼び出されたときにカーソルを正しく閉じませんが、静的SQLではうまく機能します:

    SQL> /* Works as expected with static cursor */
      2  DECLARE
      3     l XMLTYPE;
      4  BEGIN
      5     FOR i IN 1 .. 1e4 LOOP
      6        SELECT xmltype.createXML(CURSOR(SELECT * FROM DUAL)) INTO l FROM dual;
      7     END LOOP;
      8  END;
      9  /      
    
    PL/SQL procedure successfully completed
    
    SQL> /* Fails with call to dynamic cursor */
    SQL> DECLARE
      2     l XMLTYPE;
      3  BEGIN
      4     FOR i IN 1 .. 1e4 LOOP
      5        SELECT xmltype.createXML(ret_cursor) INTO l FROM dual;
      6     END LOOP;
      7  END;
      8  /
    DECLARE
    *
    ERROR at line 1:
    ORA-01000: maximum open cursors exceeded
    ORA-06512: at "APPS.RET_CURSOR", line 4
    ORA-06512: at line 5
    

    ラッパー関数を使用して、ORA-01000の発生を防ぐことができるはずです(9iR2、11gR2でテスト済み):

    SQL> CREATE OR REPLACE FUNCTION wrap_xml(p SYS_REFCURSOR) RETURN XMLTYPE IS
      2     l XMLTYPE;
      3  BEGIN
      4     l := xmltype.CreateXML(p);
      5     IF p%ISOPEN THEN
      6        CLOSE p;
      7     END IF;
      8     RETURN l;
      9  END;
     10  /
    
    Function created
    
    SQL> DECLARE
      2     l XMLTYPE;
      3  BEGIN
      4     FOR i IN 1 .. 1e4 LOOP
      5        l := wrap_xml(ret_cursor); -- a SELECT FROM dual will still fail here
      6                                   -- on 9i but not on 11g 
      7     END LOOP;
      8  END;
      9  /
    
    PL/SQL procedure successfully completed
    



    1. Scala Slick:MTable.getTablesは空のベクター/リストを返します

    2. postgres関数から一時テーブルを返す方法は?

    3. TSQL を使用してフォルダー内のすべてのファイルをループするにはどうすればよいですか?

    4. SQL Server(T-SQL)でテーブルを作成する