gpt4 book ai didi

oracle - 为什么这个包会泄漏打开的游标?

转载 作者:行者123 更新时间:2023-12-01 13:55:47 25 4
gpt4 key购买 nike

在我们的应用程序中,我们调用以下列方式返回引用游标的各种存储过程:

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

最佳答案

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

但是,我找不到这方面的引用资料。任何人都可以支持这一点吗?

关于oracle - 为什么这个包会泄漏打开的游标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17919513/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com