【问题标题】:Is it possible to use PostgreSQL anonymous block (PL/pgSQL) within the @Query annotation of Spring Data JPA Repository?是否可以在 Spring Data JPA Repository 的 @Query 注释中使用 PostgreSQL 匿名块(PL/pgSQL)?
【发布时间】:2022-01-19 08:58:47
【问题描述】:

我需要调用一个带参数的匿名块。

@Repository
public interface FinAccountRepository extends JpaRepository<FinAccount, Long> {

    @Modifying
    @Query(nativeQuery = true, value =
            "DO $$ <<credit_account>>\n" +
            "DECLARE\n" +
            "    nNewBalance numeric(19,2);\n" +
            "    nNewId bigint;\n" +
            "BEGIN\n" +
            "    update fin_account set balance = balance + :amount where id = :account\n" +
            "    returning balance into nNewBalance;\n" +
            "    select nextval('seq_fin_account_def_id') into nNewId;\n" +
            "    insert into fin_account_definition(id, account, transaction, balance)\n" +
            "    values (nNewId, :account, :tx, nNewBalance); \n" +
            "END credit_account $$;")
    void credit(@Param("tx") UUID tx, @Param("account") Long account, @Param("amount") BigDecimal amount);

}

以下代码抛出错误

org.springframework.dao.DataIntegrityViolationException: could not execute native bulk manipulation query; SQL [DO $$
DECLARE
    nNewBalance numeric(19,2);
BEGIN
    update fin_account set balance = balance - :amount where id = :account 
    returning fa.balance into nNewBalance;
    insert into fin_account_definition(id, account, transaction, balance)
    values (nextval('seq_fin_account_def_id'), :account, :tx, nNewBalance);
END $$;]; nested exception is org.hibernate.exception.DataException: could not execute native bulk manipulation query

. . .

Caused by: org.hibernate.exception.DataException: could not execute native bulk manipulation query

. . .

Caused by: org.postgresql.util.PSQLException: The column index is out of range: 1, number of columns: 0.
    at org.postgresql.core.v3.SimpleParameterList.bind(SimpleParameterList.java:69) ~[postgresql-42.2.24.jar:42.2.24]
    at org.postgresql.core.v3.SimpleParameterList.setLiteralParameter(SimpleParameterList.java:128) ~[postgresql-42.2.24.jar:42.2.24]
    at org.postgresql.jdbc.PgPreparedStatement.bindLiteral(PgPreparedStatement.java:1042) ~[postgresql-42.2.24.jar:42.2.24]
    at org.postgresql.jdbc.PgPreparedStatement.setNumber(PgPreparedStatement.java:520) ~[postgresql-42.2.24.jar:42.2.24]
    at org.postgresql.jdbc.PgPreparedStatement.setBigDecimal(PgPreparedStatement.java:337) ~[postgresql-42.2.24.jar:42.2.24]
    at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.setBigDecimal(HikariProxyPreparedStatement.java) ~[HikariCP-4.0.3.jar:na]
    at org.hibernate.type.descriptor.sql.DecimalTypeDescriptor$1.doBind(DecimalTypeDescriptor.java:47) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
    at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:73) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:276) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:271) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
    at org.hibernate.loader.custom.sql.NamedParamBinder.bind(NamedParamBinder.java:34) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
    at org.hibernate.engine.query.spi.NativeSQLQueryPlan.performExecuteUpdate(NativeSQLQueryPlan.java:102) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
    ... 160 common frames omitted

我也尝试使用序数参数 - 结果是一样的。 但是,没有绑定参数的匿名块被正确调用。 我对从 Spring Data JPA Repository 的方法将参数传递给 postgresql 匿名块的能力感兴趣。

【问题讨论】:

    标签: postgresql spring-data-jpa spring-data plpgsql


    【解决方案1】:

    您不需要为此使用 PL/pgSQL。这可以在单个 SQL 语句中完成:

    with changed_account as (
       update fin_account 
          set balance = balance + :amount 
       where id = :account
       returning balance, id
    )            
    insert into fin_account_definition(id, account, transaction, balance)
    select nextval('seq_fin_account_def_id'), c.id, :tx, c.balance
    from changed_account c;
    

    【讨论】:

      猜你喜欢
      • 2020-11-28
      • 2019-11-30
      • 2014-08-31
      • 2014-05-21
      • 2018-01-19
      • 1970-01-01
      • 2016-04-27
      • 2019-05-12
      • 2021-02-01
      相关资源
      最近更新 更多