在我们的应用程序,我们称之为以下列方式返回引用游标各种存储过程:为什么这个软件包泄露游标?
SELECT foo_package.sp_Bar('arg1', 'arg2', 'arg3', 'arg4') FROM dual;
什么wrap_xml
函数的作用是将光标结果转换为XML类型,然后将在使用应用。转换后,立即关闭游标(此步骤有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;
在大多数情况下,这似乎工作正常:创建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
检查身体,这意味着光标确实已被关闭。然而,似乎打开的光标数仍然增加!
从你以前的问题重复Vincent的测试,但用'ret_cursor'函数中的'v_sql_str'对我来说工作正常,使用11gR2。可能很有趣,看看你在10g(?)中是否失败。如果没有,那么也许别的事情正在发生。如果确实如此,那么它可能是同一个明显错误的延伸 - 你是否向Oracle汇报过? –
你的通话应用程序如何?它是否正确关闭连接? – OldProgrammer
@AlexPoole:我还没有向Oracle报告可能存在的问题,因为我仍然在努力寻找我公司的“支持标识符”。 – Stephan