एक बग प्रतीत होता है, आपको 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