使用Spring SimpleJdbcCall调用PostgreSQL存储过程报错求助
使用Spring SimpleJdbcCall调用PostgreSQL存储过程报错求助
我来帮你分析下这个问题~你遇到的情况是PostgreSQL JDBC驱动和Spring SimpleJdbcCall的调用语法不匹配导致的:驱动明确提示你要使用CALL语法来调用存储过程,但当前SimpleJdbcCall生成的SQL还是用了函数调用的格式,所以触发了语法错误。
下面给你几个排查和解决的方向:
1. 先修正参数名称的细节问题
看你的Java代码里,参数名后面多了空格:
SqlParameterSource parameters = new MapSqlParameterSource() .addValue("p_errcode ", 0) // 这里参数名末尾有空格 .addValue("p_errmessage ", "error"); // 这里也有空格
这个空格会导致参数和存储过程里的p_errcode、p_errmessage不匹配,驱动可能因此无法正确解析调用语句,修正成不带空格的参数名:
SqlParameterSource parameters = new MapSqlParameterSource() .addValue("p_errcode", 0) .addValue("p_errmessage", "error");
2. 确认JDBC URL参数是否生效
你已经在URL里加了escapeSyntaxCallMode=call,这个参数的作用是让PostgreSQL驱动把JDBC标准的{call ...}语法转换成PostgreSQL原生的CALL语句,要确保这个参数没有拼写错误,并且正确拼接到URL末尾(如果之前有其他参数,记得用&分隔)。
3. 调整SimpleJdbcCall的配置
虽然你已经设置了withoutProcedureColumnMetaDataAccess()和setAccessCallParameterMetaData(false),可以再尝试显式指定存储过程的schema(如果你的存储过程不在默认public schema下的话),比如:
SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(template) .withSchemaName("public") // 替换成你的存储过程所在schema .withProcedureName(procName) .withoutProcedureColumnMetaDataAccess() .setAccessCallParameterMetaData(false);
4. 尝试手动调用作为备选
如果上面的方法都不行,可以绕过SimpleJdbcCall,直接用CallableStatement手动调用存储过程,确保语法正确:
String callSql = "CALL myProc(?, ?)"; try (Connection conn = template.getDataSource().getConnection(); CallableStatement cs = conn.prepareCall(callSql)) { cs.setBigDecimal(1, BigDecimal.ZERO); cs.setString(2, "error"); // 注册输出参数 cs.registerOutParameter(1, Types.NUMERIC); cs.registerOutParameter(2, Types.VARCHAR); cs.execute(); // 获取返回值 BigDecimal errCode = cs.getBigDecimal(1); String errMsg = cs.getString(2); // 后续处理逻辑 } catch (SQLException e) { e.printStackTrace(); }
备注:内容来源于stack exchange,提问作者user3593086
相关产品推荐
相关产品推荐

