Spring+Hibernate调用Oracle存储过程遇PLS-00306错误求排查
解决Spring+Hibernate调用Oracle存储过程的PLS-00306错误
你的报错PLS-00306: wrong number or types of arguments in call to 'STORED_PROCEDURE'是参数类型/数量不匹配导致的,结合你的场景,核心问题集中在PL/SQL BOOLEAN类型的JDBC映射以及INOUT参数的处理上,以下是具体排查和修复方案:
1. 修复PL/SQL BOOLEAN参数的映射问题
Oracle的PL/SQL BOOLEAN是数据库内部专属类型,JDBC不支持直接用Boolean.class或Integer.class做标准映射,这是你之前修改Integer无效的原因,需要用Oracle专属类型处理:
方案一:调整StoredProcedureQuery参数注册
导入oracle.jdbc.OracleTypes,修改第六个参数的注册逻辑:
// 替换原第六个参数注册代码 .registerStoredProcedureParameter("sixth", Boolean.class, ParameterMode.IN) // 改为: .registerStoredProcedureParameter("sixth", Integer.class, ParameterMode.IN) .setHint("org.hibernate.callable.inout.param.registered.type", OracleTypes.BOOLEAN)
方案二:改用原生CallableStatement(更可靠)
绕开Hibernate封装,直接用JDBC原生逻辑处理,避免框架层的类型转换问题:
Session session = entityManager.unwrap(Session.class); CallableStatement cs = session.doReturningWork(connection -> { String sql = "{call STORED_PROCEDURE(?, ?, ?, ?, ?, ?)}"; CallableStatement stmt = connection.prepareCall(sql); // 设置IN参数 stmt.setString(1, var1); stmt.setString(2, var2); stmt.setString(3, var3); // 处理INOUT参数:先设置输入值,再注册输出类型 stmt.setString(4, "value"); stmt.registerOutParameter(4, Types.VARCHAR); stmt.setString(5, "value"); stmt.registerOutParameter(5, Types.VARCHAR); // 处理BOOLEAN参数 stmt.setBoolean(6, true); stmt.registerOutParameter(6, OracleTypes.BOOLEAN); return stmt; }); cs.execute(); // 可选:获取INOUT参数的输出结果 String fourthResult = cs.getString(4); String fifthResult = cs.getString(5); cs.close();
2. 验证INOUT参数的正确性
虽然你注册的ParameterMode.INOUT和String.class逻辑正确,但需要注意:
- 传入的初始值长度不能超过存储过程中VARCHAR2的定义长度
- 执行后必须通过
query.getOutputParameterValue("fourth")获取输出值,避免参数处理不完整导致的隐式错误
3. 检查参数名大小写匹配
Oracle默认对标识符(包括存储过程参数名)不区分大小写,但如果存储过程定义时参数名带双引号(比如"FIRST"),则必须严格匹配大小写。从你的定义看参数都是小写,代码中也是小写,这部分无问题。
验证建议
- 先编写一个仅接收BOOLEAN参数的测试存储过程,单独验证参数映射是否生效
- 逐步添加其他参数,排除多参数组合导致的问题
内容的提问来源于stack exchange,提问作者clocke3
相关产品推荐
相关产品推荐

