Domanda

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!

È stato utile?

Soluzione

We appear to have plugged the leak by removing the ISOPEN check from the wrap_xml function and just executing the close cursor command in all cases. Apparently the ISOPEN flag is not set on cursors opened for dynamic SQL queries.

I am, however, unable to find a reference for this. Can anyone back this up?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top