Postgresql 11:存储过程调用错误 - 要调用过程,请使用 CALL,Java
Postgresql 11: Stored Procedure call error - To call a procedure, use CALL, Java
我出于交易目的将 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")
,并且此过程在实体 class 中声明为 @NamedStoredProcedure
。问题是,这个注释仍然像 PG 版本 11 之前那样以函数方式调用它。
这方面的任何帮助。
在 PostgreSQL 11 之后,PostgreSQL JDBC 驱动团队在 PostgreSQL 驱动版本 42.2.16 中引入了一个 ENUM 名称 EscapeSyntaxCallMode .我们可以在创建数据库连接或 DataSource
对象时使用此枚举。这个枚举有 3 种类型的值:
- "
func
" - 当我们总是想调用函数时设置这个。
- "
call
" - 当我们总是想调用过程时设置这个。
- "
callIfNoReturn
" - 它在调用 function/procedure 时检查 return 类型,如果存在 return 类型,PostgreSQL 将其视为函数并将其作为函数调用函数方式。否则它称它为过程方式。所以在我的项目中我使用了这个“callIfNoReturn
”,因为我希望 PostgreSQL 自动检测我是在调用函数还是过程。
因此,要解决此问题,您只需按照以下步骤操作:
在 pom.xml
或 gradle.
中将您的 PostgreSQL JDBC 驱动程序版本从任何旧版本升级到 42.2.16 或更高版本
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.16</version>
</dependency>
当然,您的机器上必须安装 PostgreSQL Server 版本 >= 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,您都不需要更改过程调用方式。
更多详情请关注这里linkhttps://github.com/pgjdbc/pgjdbc
我出于交易目的将 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")
,并且此过程在实体 class 中声明为 @NamedStoredProcedure
。问题是,这个注释仍然像 PG 版本 11 之前那样以函数方式调用它。
这方面的任何帮助。
在 PostgreSQL 11 之后,PostgreSQL JDBC 驱动团队在 PostgreSQL 驱动版本 42.2.16 中引入了一个 ENUM 名称 EscapeSyntaxCallMode .我们可以在创建数据库连接或 DataSource
对象时使用此枚举。这个枚举有 3 种类型的值:
- "
func
" - 当我们总是想调用函数时设置这个。 - "
call
" - 当我们总是想调用过程时设置这个。 - "
callIfNoReturn
" - 它在调用 function/procedure 时检查 return 类型,如果存在 return 类型,PostgreSQL 将其视为函数并将其作为函数调用函数方式。否则它称它为过程方式。所以在我的项目中我使用了这个“callIfNoReturn
”,因为我希望 PostgreSQL 自动检测我是在调用函数还是过程。
因此,要解决此问题,您只需按照以下步骤操作:
在
中将您的 PostgreSQL JDBC 驱动程序版本从任何旧版本升级到 42.2.16 或更高版本pom.xml
或 gradle.<dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.2.16</version> </dependency>
当然,您的机器上必须安装 PostgreSQL Server 版本 >= 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,您都不需要更改过程调用方式。
更多详情请关注这里linkhttps://github.com/pgjdbc/pgjdbc