In our application, we call various stored procedures that return reference cursors in the following fashion:
SELECT foo_package.sp_Bar('arg1', 'arg2', 'arg3', 'arg4') FROM dual;
What the wrap_xml
function does is to convert the cursor result to an XML type, which will then be used in the application. After the conversion, it immediately closes the cursor (this step has solved memory issues for us before).
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;
In most cases, this appears to work fine: the XML is created and the cursors are closed. However, since introducing a stored procedure that opens a cursor for a dynamic query, we are observing a rapid increase in open cursors, eventually leading to:
ORA-01000: maximum open cursors exceeded
The dynamic query is built in order to "simulate" the results returned from other cursors, for testing purposes. For example, the stored procedure would build a dynamic query like this:
SELECT '1' as "COLUMN1", '990' as "COLUMN2", 'N' as "COLUMN3", NULL as "COLUMN5" FROM dual;
It would then open a cursor for this query string, and return the cursor:
OPEN rc_return FOR v_sql_query;
RETURN rc_return;
The resulting reference cursor is again passed to the wrap_xml
function above, which I would expect to close the cursor – just like it does any other cursor. However, this doesn't seem to be the case, as the number of open cursors just keeps on growing. What could be the reason for this?
Additional investigation:
Stepping through the wrap_xml
function, I can see the program flow skipping over the body of the c_result%ISOPEN
check, implying that the cursor has indeed been closed. Yet it appears that the open cursor count still increases!