我是Postgres的新手,但正尝试在Postgres 11(新的“过程”而不是“函数”)中调用过程,从java作为spring SimpleJDBCCall进行调用(使用Postgresql-42.2.5 jdbc驱动程序)。但是,当我执行该过程时,遇到以下异常:
org.springframework.jdbc.BadSqlGrammarException: CallableStatementCallback;错误的SQL语法[{call pa_test_schema.pr_dosomething(?)}];嵌套异常为 org.postgresql.util.PSQLException:错误: pa_test_schema.pr_dosomething(bigint)是一个过程提示:调用 程序,请使用CALL。位置:15, org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:101) 在 org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72) 在 org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) 在 org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) 在 org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1402) 在 org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:1065) 在 org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:1104) 在 org.springframework.jdbc.core.simple.AbstractJdbcCall.executeCallInternal(AbstractJdbcCall.java:414) 在 org.springframework.jdbc.core.simple.AbstractJdbcCall.doExecute(AbstractJdbcCall.java:397) 在 org.springframework.jdbc.core.simple.SimpleJdbcCall.execute(SimpleJdbcCall.java:193)
我的过程代码:
CREATE PROCEDURE pa_test_schema.pr_DoSomething
( P_input_ID IN inputs.input_ID%TYPE
) AS $$
BEGIN
-- do something
END;
$$ LANGUAGE plpgsql;
我的Java代码:
SimpleJdbcCallOperations pr_DoSomething = new SimpleJdbcCall(jdbcTemplate)
.withSchemaName("pa_test_schema")
.withProcedureName("pr_DoSomething");
Map<String, Object> inputs = Maps.newHashMap();
inputs.put("p_input_id", 123456);
pr_DoSomething.execute(inputs);
单步执行代码时,我可以看到驱动程序正在将callable语句的sql修改为调用postgres函数所需的语法:
从pa_test_schema.pr_dosomething(?)中选择*作为结果
这是驱动程序中执行此转换的方法: https://github.com/pgjdbc/pgjdbc/blob/faab499853c56f67cb70fb242f75b918452f2a6f/pgjdbc/src/main/java/org/postgresql/core/Parser.java#L766
我了解过程仅在Postgres 11中引入(以前曾使用过void返回函数),并且已阅读过postgres驱动程序文档,但看不到任何对调用过程的引用,而不是对函数的引用。
这是否意味着当前的postgres驱动程序尚不支持此功能,或者我应该使用其他方法吗?我应该只使用postgres函数吗?
答案 0 :(得分:3)
当前(从Postgres 11.1和驱动程序版本42.2.5起),使用CallableStatement
的标准JDBC方法不能用于调用存储过程。
我实际上并没有使用Spring JDBC模板,但是以下代码可在纯JDBC中工作,并且应适用于Spring JDBC Tempalte:
Connection con = DriverManager.getConnection(...);
PreparedStatement pstmt = con.prepareStatement("call pa_test_schema.pr_DoSomething(?)");
pstmt.setInt(1, 42);
pstmt.execute();
请注意,这使用了Postgres的call
命令。请勿将此与"{call ...}"
的{{1}}语法混淆。