Postgresql 11:存储过程调用错误 - 要调用过程,请使用 CALL、Java
Posted
技术标签:
【中文标题】Postgresql 11:存储过程调用错误 - 要调用过程,请使用 CALL、Java【英文标题】:Postgresql 11: Stored Procedure call error - To call a procedure, use CALL, Java 【发布时间】:2021-04-18 04:03:38 【问题描述】:为了交易目的,我将 PGsql 函数转换为过程 (v11)。但是在从 Java 代码调用该过程时,Java 代码会抛出以下异常:
2021-01-10 21:52:56,604 WARN [ForkJoinPool.commonPool-worker-1] o.h.e.j.spi.SqlExceptionHelper(144) - SQL Error: 0, SQLState: 42809
2021-01-10 21:52:56,605 ERROR [ForkJoinPool.commonPool-worker-1] o.h.e.j.spi.SqlExceptionHelper(146) - ERROR: some_procedure_name(character varying, character varying) is a procedure
Hint: To call a procedure, use CALL.
Position: 15
我正在使用 Spring Data JPA 的 @Procedure(name = "some_procedure_name")
,并且此过程在实体类中声明为 @NamedStoredProcedure
。问题是,这个注解仍然像 PG 版本 11 之前一样将其作为函数方式调用。
任何帮助。
【问题讨论】:
【参考方案1】:在 PostgreSQL 11 之后,PostgreSQL JDBC 驱动团队在 PostgreSQL 驱动版本 42.2.16 中引入了一个 ENUM 名称EscapeSyntaxCallMode。我们可以在创建数据库连接或DataSource
对象时使用此枚举。这个枚举有 3 种类型的值:
-
"
func
" - 当我们总是想调用函数时设置它。
"call
" - 当我们总是想调用过程时设置它。
"callIfNoReturn
" - 它检查调用函数/过程中的返回类型,如果返回类型存在,PostgreSQL 将其视为函数并将其作为函数方式调用。否则将其称为过程方式。所以在我的项目中,我使用了这个“callIfNoReturn
”,因为我希望 PostgreSQL 自动检测我是在调用函数还是过程。
因此,要解决此问题,您只需按照以下步骤操作:
将您的 PostgreSQL JDBC 驱动程序版本从任何旧版本升级到 pom.xml
或 gradle 中的 42.2.16 或更高版本。
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.16</version>
</dependency>
当然,您的机器上必须安装 PostgreSQL 服务器版本 >= 11 才能创建过程。
如果您使用的是 Spring,那么在创建数据源对象时,您需要在 "jdbcUrl"
中附加 escapeSyntaxCallMode
作为查询字符串,如下所示:
<bean id="dataSource" parent="com.zaxxer.hikari.HikariDataSource">
<property name="jdbcUrl" value="jdbc:postgresql://localhost:5432/dev_db?escapeSyntaxCallMode=$cibase.db.app.procedureCallPolicy"/>
<property name="username" value="$cibase.db.app.user"/>
<property name="password" value="$cibase.db.app.password"/>
</bean>
?escapeSyntaxCallMode=$cibase.db.app.procedureCallPolicy
:这里我从属性文件中选择枚举值,但是你可以根据你的要求直接输入"func"/"call"/"callIfNoReturn"
中的任何枚举值。
现在你运行你的代码,它会正常工作。
注意: 无论您是使用纯 JDBC 代码还是 Spring Data Jpa 中的 @Procedure,您都无需更改过程调用方式。
更多详情请点击此链接https://github.com/pgjdbc/pgjdbc
【讨论】:
如果答案解决了您的问题,请接受。请不要将其保留为“未答复”。接受答案有助于以后可能遇到相同问题的提问者。以上是关于Postgresql 11:存储过程调用错误 - 要调用过程,请使用 CALL、Java的主要内容,如果未能解决你的问题,请参考以下文章
JPA 和 PostgreSQL:如何调用具有 void 返回类型的存储过程?
使用 Dapper (C#) 调用 PostgreSQL 存储过程