出于事务目的,我将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
我使用的是SpringDataJPA的@Procedure(name = "some_procedure_name")
,这个过程在实体类中被声明为@NamedStoredProcedure
。问题是,这个注释仍然像PG版本11之前那样将其作为函数调用。
对此有任何帮助。
PostgreSQL 11之后,PostgreSQL JDBC驱动程序团队在PostgreSQL驱动程序42.2.16版本中引入了ENUM名称EscapeSyntaxCallMode。我们可以在创建数据库连接或DataSource
对象时使用此枚举。此枚举有3种类型的值:
- "
func
"-当我们总是想调用函数时,请设置此项 - "
call
"-当我们总是想调用Procedures时设置此项 - "
callIfNoReturn
"-如果返回类型存在,它会在调用函数/过程中检查返回类型。PostgreSQL将其视为一个函数,并以函数的方式调用它。否则,它将其称为过程方式。所以在我的项目中,我使用了这个";CCD_ 7";,因为我想让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,那么在创建数据源对象时,您需要将
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