ORA-01001:无效游标问题排查——含SYS_REFCURSOR存储过程代码
ORA-01001: invalid cursor错误排查与解决
可能的核心原因
- 重复关闭游标:代码中
apex_json.write('bybranch', br_out_rec)会自动读取并关闭传入的REF CURSOR,之后你又手动执行CLOSE br_out_rec;,这会导致游标被重复关闭,触发无效游标错误。第一个存储过程未出现该问题,大概率是因为它没有这个重复关闭的操作。 - CASE表达式不完整:你提供的代码中CASE语句是省略状态,如果实际代码里CASE缺少
END,会导致查询语句语法错误,游标无法正常打开——虽然SQLPlus里验证的查询是完整的,但存储过程中的代码可能存在语法遗漏。 - 绑定变量转换异常:
inputbranch是CHAR类型,转换为to_number(inputbranch)时,如果传入的参数是空值或非数字字符,会引发转换异常,导致游标未成功打开。不过你说SQLPlus中查询正常,这个可能性相对较低,但仍需验证参数合法性。
解决步骤
- 移除手动关闭游标的代码:删掉
CLOSE br_out_rec;这一行,依赖apex_json.write的自动关闭逻辑即可。 - 检查并补全CASE语句:确保查询中的CASE表达式有对应的
END,保证SQL语法完整。 - 验证参数转换的合法性:在转换
inputbranch为数字前,增加参数校验,比如用REGEXP_LIKE(inputbranch, '^[0-9]+$')判断是否为有效数字,避免转换异常。
修改后的关键代码示例
PROCEDURE bybranch ( inputbranch IN CHAR, customerid IN CHAR, deftype IN CHAR, districtflag CHAR, br_out_rec OUT SYS_REFCURSOR ) IS BEGIN EXECUTE IMMEDIATE 'alter session set nls_date_format=''dd-mm-yyyy'''; OPEN br_out_rec FOR SELECT to_date(TO_DATE('01-01-1988 00:00', 'dd-mm-yyyy hh24:mi') + numtodsinterval(w.curdate, 'minute'), 'dd-mm-yyyy' ) AS qdate, TO_CHAR(TRUNC(sysdate) + h.stime / 24 / 60, 'hh24:mi') AS stime, -- 确保CASE语句完整,包含END CASE ... -- 你的逻辑 END AS some_column, ... WHERE macdent$mac_nearbranch.branch = to_number(inputbranch) ORDER BY qdate, stime; apex_json.open_object; apex_json.write('bybranch', br_out_rec); apex_json.close_object; -- 移除手动关闭游标的语句 EXCEPTION WHEN OTHERS THEN htp.print(sqlerrm); END bybranch;
内容的提问来源于stack exchange,提问作者liorke
相关产品推荐
相关产品推荐

