首页 > 解决方案 > JPA 存储库:无法为时区绑定参数

问题描述

我在 JPA 存储库中有以下代码,它可以工作。

  @Query(
      value =
          "SELECT EXTRACT(HOUR FROM STO.createddate\\:\\:timestamptz at time zone 'Asia/Seoul') AS hour,\n"
              + "        COUNT(STO.id) AS count, SUM(STO.grandtotalprice) AS sum, AVG(STO.grandtotalprice) AS average\n"
              + "FROM store.storeorder AS STO\n"
              + "WHERE STO.store_id=?1 AND STO.createddate >= ?2 AND STO.createddate < ?3 AND STO.orderstatus IN ('CLOSED')\n"
              + "GROUP BY EXTRACT(HOUR FROM STO.createddate\\:\\:timestamptz at time zone 'Asia/Seoul') \n"
              + "ORDER BY hour ASC;",
      nativeQuery = true)
  List<ReportHourly> hourlyReport(
      UUID storeId, LocalDateTime from, LocalDateTime to);

但是,当我尝试像下面这样输入时区作为参数时,它会失败并说

org.postgresql.util.PSQLException: ERROR: column "createddate" must appear in the GROUP BY clause or be used in an aggregate function
  @Query(
      value =
          "SELECT EXTRACT(HOUR FROM STO.createddate\\:\\:timestamptz at time zone ?4) AS hour,\n"
              + "        COUNT(STO.id) AS count, SUM(STO.grandtotalprice) AS sum, AVG(STO.grandtotalprice) AS average\n"
              + "FROM store.storeorder AS STO\n"
              + "WHERE STO.store_id=?1 AND STO.createddate >= ?2 AND STO.createddate < ?3 AND STO.orderstatus IN ('CLOSED')\n"
              + "GROUP BY EXTRACT(HOUR FROM STO.createddate\\:\\:timestamptz at time zone ?4) \n"
              + "ORDER BY hour ASC;",
      nativeQuery = true)
  List<ReportHourly> hourlyReport(
      UUID storeId, LocalDateTime from, LocalDateTime to, String timeZone);

我不确定为什么参数化不适用于这种情况。

标签: javaspringpostgresqlgroup-byspring-data-jpa

解决方案


我认为这里的问题是 JDBC 并不真正了解索引绑定参数,它只知道?用于绑定。

这意味着两次出现的 fo?4被转换为两个不同的绑定参数,因此 Postgres 在 select 子句中看到一个表达式,它不是GROUP BY聚合函数的一部分。

由于通过构造,两者实际上是相同的,因此您应该很好地将表达式 for hour inMAX(...)或任何其他在应用于单行时返回参数值的聚合函数。


推荐阅读