PostgreSQL 11: 存储过程调用错误 - 调用存储过程时,请使用 CALL,Java

4

我将一个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。问题是,这个注解仍然以Function的方式调用它,就像在PG版本11之前一样。 请帮忙解决这个问题。
1个回答

16
在 PostgreSQL 11 后,PostgreSQL JDBC 驱动程序团队在 PostgreSQL 驱动程序版本42.2.16中引入了一个 ENUM 名称 EscapeSyntaxCallMode。我们可以在创建数据库连接或 DataSource 对象时使用此枚举。此枚举有3种类型的值:
  1. "func" - 当我们始终想调用函数时设置此项。
  2. "call" - 当我们始终想调用存储过程时设置此项。
  3. " callIfNoReturn " - 它检查调用函数/存储过程的返回类型,如果返回类型存在,则 PostgreSQL 将其视为函数并以函数方式调用它。否则,它将以存储过程方式调用它。因此,在我的项目中,我使用了 " callIfNoReturn " ,因为我希望 PostgreSQL 自动检测是否调用函数或存储过程。 要解决此问题,您只需按照以下步骤操作:
    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,则在创建 Data Source 对象时,需要将 escapeSyntaxCallMode 附加为查询字符串添加到 "jdbcUrl" 中,如下所示:

    4. <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


如果答案解决了您的问题,请接受它。请不要将其留作“未回答”。接受答案有助于后来可能遇到相同问题的提问者。 - Belayer
这绝对是我们遇到的情况,我可以确认所描述的解决方案正常运作。 - George Chou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接