我可以使用 postgres JDBC 驱动程序从 java 调用 postgres "Procedure"(不是 "function")吗?



我是postgres的新手,但我正在尝试调用postgres 11中的一个过程(新的"过程"而不是"函数"(,从java调用作为spring SimpleJDBCCall(使用Postgresql-42.2.5 jdbc驱动程序(。然而,当我执行过程时,我遇到了以下异常:

org.springframework.jdbc.BadSqlGrammar异常:CallableStatement回调;错误的SQL语法〔{callpa_testrongchema.pr_dosomething(?(}];嵌套异常为org.postgresql.util.PSQL异常:错误:pa_testrongchema.pr_dosomething(bigint(是一个过程提示:要调用过程中,请使用CALL。位置:15org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExcessionTranslator.java:101(在org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLServerExceptionTranslater.java:72(在org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLServerExceptionTranslater.java:81(在org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLServerExceptionTranslater.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(AbstractJdbc Call.java:414(在org.springframework.jdbc.core.simple.AbstractJdbcCall.doExecute(AbstractJdbc Call.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);    

当我浏览代码时,我可以看到驱动程序正在将可调用语句的sql修改为调用postgres函数所需的语法:

从pa_testrongchema.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函数吗?

目前(从Postgres 11.1和驱动程序版本42.2.5开始(,使用CallableStatement的标准JDBC方法不能用于调用存储过程。

我并没有真正使用SpringJDBC模板,但以下代码可以在普通JDBC中工作,并且应该适用于SpringJDBC Tempalte:

Connection con = DriverManager.getConnection(...);
PreparedStatement pstmt = con.prepareStatement("call pa_test_schema.pr_DoSomething(?)");
pstmt.setInt(1, 42);
pstmt.execute();

请注意,这使用了Postgres的call命令。不要将其与CallableStatement"{call ...}"语法混淆。


关于CallableStatement当前不起作用的更多详细信息,可以在JDBC邮件列表的此处和此处找到

最新更新