Abh*_*wat 1 java postgresql stored-procedures spring-data-jpa postgresql-11
我将 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's @Procedure(name = "some_procedure_name"),并且这个过程被声明为@NamedStoredProcedure实体类。问题是,这个注解仍然像 PG 版本 11 之前那样将其作为 Function 方式调用。
任何帮助。
PostgreSQL的11后,PostgreSQL JDBC驱动的团队已经推出了ENUM名EscapeSyntaxCallMode在Postgresql driver version 42.2.16。所以我们可以在创建数据库连接或DataSource对象时使用这个枚举。这个枚举有 3 种类型的值:
func" - 当我们总是想调用函数时设置它。call" - 当我们总是想调用程序时设置它。callIfNoReturn" - 它检查调用函数/过程中的返回类型,如果返回类型存在 postgres 将其视为函数并将其调用为函数方式。否则它称之为程序方式。所以在我的项目中,我使用了这个“ callIfNoReturn”,因为我希望 postgres 自动检测我是在调用函数还是过程。因此,要解决此问题,您只需执行以下步骤:
将您的 PostgreSQL JDBC 驱动程序版本从任何旧版本升级到 42.2.16 或更高版本pom.xml。
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.2.16</version>
</dependency>
当然,您必须在您的机器上安装 PostgreSQL 服务器版本 >= 11 才能创建程序。
如果您使用的是 Spring,那么在创建数据源对象时,您需要像这样附加escapeSyntaxCallMode为查询字符串"jdbcUrl":
<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