Postgresql 11:存储过程调用错误 - 要调用过程,请使用 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"),并且此过程在实体类中声明为 @NamedStoredProcedure。问题是,这个注解还是像 PG 11 版之前一样,以 Function 方式调用

这方面的任何帮助。

解决方法

在 Postgresql 11 之后,PostgreSQL JDBC 驱动程序团队在 Postgresql driver version 42.2.16 中引入了 ENUM 名称 EscapeSyntaxCallMode。所以我们可以在创建数据库连接或 DataSource 对象时使用这个枚举。这个枚举有 3 种类型的值:

  1. "func" - 当我们总是想调用函数时设置它。
  2. "call" - 当我们总是想调用程序时设置它。
  3. "callIfNoReturn" - 它在调用函数/过程时检查返回类型,如果返回类型存在 postgres 将其视为函数并将其调用为函数方式。否则它称之为程序方式。所以在我的项目中,我使用了这个“callIfNoReturn”,因为我想让 postgres 自动检测我是在调用函数还是过程。

因此,要解决此问题,您只需执行以下步骤:

  1. pom.xml 或 gradle 中将您的 PostgreSQL JDBC 驱动程序版本从任何旧版本升级到 42.2.16 或更高版本。

    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.2.16</version>
    </dependency>
    
  2. 当然,您必须在您的机器上安装 PostgreSQL 服务器版本 >= 11 才能创建程序。

  3. 如果您使用的是 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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...