Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Kursor referensi hilang di XMLType.createxml

Tampaknya ada bug, Anda harus membuka permintaan layanan ke dukungan Oracle. Saya akan memposting kasus uji yang mereproduksi temuan Anda di 9i dan 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 tidak akan menutup kursor dengan benar saat dipanggil dengan fungsi di atas, sedangkan XMLType bekerja dengan baik dengan SQL statis:

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

Anda harus dapat menggunakan fungsi pembungkus untuk mencegah terjadinya ORA-01000 (diuji pada 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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Baca ARRAY dari STRUCT yang dikembalikan oleh prosedur tersimpan

  2. Misteri rownum di oracle

  3. Berdasarkan Hari Kolom yang digabungkan dengan Tanggal sebagai Judul

  4. Mengikat int64 (SQL_BIGINT) sebagai parameter kueri menyebabkan kesalahan selama eksekusi di Oracle 10g ODBC

  5. Bagaimana cara mendapatkan catatan secara acak dari database Oracle?