如何在Toad for Oracle中实现PL/SQL存储过程输出至数据网格?报错求助
解决ORA-01001无效游标错误并实现Toad数据网格输出
错误原因
ORA-01001是无效游标错误,你的代码中调用dbms_sql.return_result(c_entity_and_date)后,Oracle会接管该游标的完整生命周期(包括打开、读取、关闭),后续手动执行CLOSE c_entity_and_date时,游标已经被系统处理,导致关闭无效游标的错误。
解决方案
方案一:移除手动关闭游标语句
保留dbms_sql.return_result的用法,删除手动关闭游标的代码,让Oracle自动管理游标:
CREATE OR REPLACE PACKAGE test1 AS PROCEDURE get_date_range(new_date VARCHAR2, new_entity VARCHAR2); END; / CREATE OR REPLACE PACKAGE BODY test1 AS PROCEDURE get_date_range(new_date VARCHAR2,new_entity VARCHAR2) IS TYPE rc_entity_and_date IS REF CURSOR; c_entity_and_date rc_entity_and_date; BEGIN OPEN c_entity_and_date FOR SELECT * FROM my_table WHERE entity = new_entity AND report_date = new_date; dbms_sql.return_result(c_entity_and_date); -- 移除CLOSE语句,由Oracle自动处理游标关闭 END get_date_range; END; / -- 执行调用 EXECUTE test1.get_date_range('6/12/2023', 'MLPFS');
方案二:改用OUT参数的REF CURSOR(Toad推荐用法)
Toad对带OUT参数的REF CURSOR支持更友好,执行后结果会直接显示在数据网格中:
CREATE OR REPLACE PACKAGE test1 AS -- 定义包级别的REF CURSOR类型 TYPE rc_entity_and_date IS REF CURSOR; PROCEDURE get_date_range(new_date VARCHAR2, new_entity VARCHAR2, out_cursor OUT rc_entity_and_date); END; / CREATE OR REPLACE PACKAGE BODY test1 AS PROCEDURE get_date_range(new_date VARCHAR2,new_entity VARCHAR2, out_cursor OUT rc_entity_and_date) IS BEGIN OPEN out_cursor FOR SELECT * FROM my_table WHERE entity = new_entity AND report_date = new_date; -- 无需手动关闭,Toad获取结果后会自动处理 END get_date_range; END; /
在Toad中调用时,可使用匿名块,或直接通过Toad的「Execute Procedure」窗口选择该过程,输入参数后执行:
DECLARE v_cursor test1.rc_entity_and_date; BEGIN test1.get_date_range(TO_DATE('6/12/2023', 'MM/DD/YYYY'), 'MLPFS', v_cursor); END; /
额外注意事项
如果report_date是DATE类型,建议显式转换日期字符串为DATE类型(如上述代码中的TO_DATE),避免因会话NLS_DATE_FORMAT设置不同导致的隐式转换错误。
内容的提问来源于stack exchange,提问作者ns102030
相关产品推荐
相关产品推荐

