调用带SYS_REFCURSOR输出参数的存储过程遇ORA-00604/ORA-01003错误求助
问题诊断与解决
核心问题:参数名称不匹配
你的Java代码中,注册输出参数时使用的是存储过程定义的参数名res,但获取游标结果时却误用了SQLDeveloper测试代码里的本地变量名resCur,这直接导致无法正确定位输出参数,触发ORA-01003(未解析的SQL语句)和ORA-00604(递归SQL层错误)。
修正后的Java代码
CallableStatement sql = connection.prepareCall("{call test( ?, ?)}"); sql.setInt("num", 1); // 注册输出参数时使用存储过程定义的参数名res sql.registerOutParameter("res", OracleTypes.CURSOR); sql.execute(); // 获取游标时必须与注册的参数名一致,使用res而非resCur ResultSet rs = (ResultSet) sql.getObject("res"); while (rs.next()) { log.debug(rs.getInt(1)); } // 按顺序释放资源:先关ResultSet,再关CallableStatement rs.close(); sql.close();
额外优化建议
- 规范资源释放:添加try-catch-finally块,确保异常场景下资源也能正确关闭,避免泄漏:
CallableStatement sql = null; ResultSet rs = null; try { sql = connection.prepareCall("{call test( ?, ?)}"); sql.setInt("num", 1); sql.registerOutParameter("res", OracleTypes.CURSOR); sql.execute(); rs = (ResultSet) sql.getObject("res"); while (rs.next()) { log.debug(rs.getInt(1)); } } catch (SQLException e) { e.printStackTrace(); } finally { if (rs != null) { try { rs.close(); } catch (SQLException ignored) {} } if (sql != null) { try { sql.close(); } catch (SQLException ignored) {} } } - 存储过程异常透传:当前存储过程仅将异常输出到DBMS_OUTPUT,Java端无法感知内部错误,建议添加
RAISE语句让异常传递到应用层:create or replace PROCEDURE test( num IN NUMBER, res out SYS_REFCURSOR ) AS query varchar2(500); BEGIN query := 'SELECT 1,2 FROM dual'; OPEN res FOR query; exception WHEN others then DBMS_OUTPUT.PUT_LINE(' ERROR '||SUBSTR(SQLERRM, 1 , 200)); -- 重新抛出异常,让Java端捕获 RAISE; END test;
内容的提问来源于stack exchange,提问作者Drazhan
相关产品推荐
相关产品推荐

