2013-07-29 21 views
3

在我们的应用程序,我们称之为以下列方式返回引用游标各种存储过程:为什么这个软件包泄露游标?

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检查身体,这意味着光标确实已被关闭。然而,似乎打开的光标数仍然增加!

+0

从你以前的问题重复Vincent的测试,但用'ret_cursor'函数中的'v_sql_str'对我来说工作正常,使用11gR2。可能很有趣,看看你在10g(?)中是否失败。如果没有,那么也许别的事情正在发生。如果确实如此,那么它可能是同一个明显错误的延伸 - 你是否向Oracle汇报过? –

+0

你的通话应用程序如何?它是否正确关闭连接? – OldProgrammer

+0

@AlexPoole:我还没有向Oracle报告可能存在的问题,因为我仍然在努力寻找我公司的“支持标识符”。 – Stephan

回答

1

我们似乎已通过从wrap_xml函数中删除ISOPEN检查并在所有情况下仅执行关闭游标命令来堵塞泄漏。显然,ISOPEN标志未在为动态SQL查询打开的游标上设置。

但是,我无法找到对此的参考。任何人都可以支持这个吗?

相关问题