В нашем приложении мы вызываем различные хранимые процедуры, которые возвращают ссылочные курсоры следующим образом:
SELECT foo_package.sp_Bar('arg1', 'arg2', 'arg3', 'arg4') FROM dual;
Функция wrap_xml
преобразует результат курсора в тип XML, который затем будет использоваться в приложении. После преобразования он немедленно закрывает курсор (этот шаг решил для нас проблемы с памятью до).
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;
В большинстве случаев это работает нормально: создается XML, а курсоры закрываются. Однако с момента введения хранимой процедуры, которая открывает курсор для динамического запроса, мы наблюдаем быстрое увеличение числа открытых курсоров, что в конечном итоге приводит к:
ORA-01000: maximum open cursors exceeded
Динамический запрос построен для «имитации» результатов, возвращаемых другими курсорами, в целях тестирования. Например, хранимая процедура создаст динамический запрос, подобный этому:
SELECT '1' as "COLUMN1", '990' as "COLUMN2", 'N' as "COLUMN3", NULL as "COLUMN5" FROM dual;
Затем он откроет курсор для этой строки запроса и вернет курсор:
OPEN rc_return FOR v_sql_query;
RETURN rc_return;
Результирующий ссылочный курсор снова передается в функцию wrap_xml
выше, которая, как я ожидал, закроет курсор - точно так же, как и любой другой курсор. Однако, похоже, это не так, поскольку количество открытых курсоров продолжает расти. Что могло быть причиной этого?
Дополнительное расследование:
Проходя через функцию wrap_xml
, я вижу, как поток программы пропускает тело проверки c_result%ISOPEN
, подразумевая, что курсор действительно был закрыт. Тем не менее, похоже, что количество открытых курсоров все еще увеличивается!
v_sql_str
в функцииret_cursor
, у меня работает нормально, с 11gR2. Было бы интересно посмотреть, не сработает ли это для вас в 10g (?). Если этого не происходит, возможно, происходит что-то еще. Если да, то, возможно, это продолжение той же очевидной ошибки - вы сообщили об этом в Oracle? - person Alex Poole   schedule 29.07.2013