Oracle
 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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ORA-06502:PL/SQL:числова или стойностна грешка:буферът на символен низ е твърде малък, изключение от C# код

  2. Как да получите записи на случаен принцип от базата данни на Oracle?

  3. Намиране на разлика между два реда в таблица. Оракул

  4. Как мога да съхранявам байтове в Oracle Varchar2 и ASCII да се третира като текст

  5. Oracle sql - присъединяване с входен параметър