【问题标题】:FETCH FIRST n ROWS ONLY within subquery using Java Persistence Query Language使用 Java Persistence Query Language 仅在子查询中 FETCH FIRST n ROWS
【发布时间】:2012-06-01 03:04:06
【问题描述】:

我正在尝试使用 Java 持久性查询语言对 DB2 表进行批量更新:

UPDATE Account  a
SET a.Status = 'r', a.Code = :code, a.Timestamp = CURRENT_TIMESTAMP
WHERE ClientNumber IN  (SELECT ClientNumber FROM Account
                        WHERE a.Status = '' AND a.Type = :type 
                        ORDER BY a.Code ASC
                        FETCH FIRST 5 ROWS ONLY)

但是,JPQL 似乎不支持 FETCH FIRST n ROWS ONLY

还有哪些其他选择可以做到这一点?

【问题讨论】:

  • 您遇到的错误是什么?对于大型机 DB2,子查询中的FETCH FIRST 仅在 9.1 之后才存在(但如果您使用的是比这更早的东西,那么您现在已经不再支持了),我相信它已经存在于 Linux/Unix 中/Windows 现在有一段时间了。我看到的一个快速错误是您在:code 之后、a.Timestamp 之前缺少一个逗号
  • @galador 它肯定受数据库支持...我得到的错误是 org.apache.openjpa.persistence.ArgumentException 带有保留字列表
  • 正如@JBNizet 提到的,你的ORDER BY 子句在哪里?即使这可行,您实际上也得到了 5 个 随机 行,这不是您想要的。请记住,SQL 本质上是无序的,你必须告诉它你想要什么。实际上,子查询中的条件应该包含在主WHERE 子句中,以防止更新幻像行(取决于锁定级别)。另外,如果您只更新 5 行,这怎么是“批量更新”?如果您因为事务而批处理,请使用更大的行数。
  • @X-Zero 5 rows 只是一个简单的例子,我实际上需要随机帐户
  • 获取随机行是一个完全不同的用例。一方面,您不会获得足够随机的行(因为它们将根据某些索引进行排序,通常您只是无法选择哪一个)。生成一些随机的ClientNumbers 应用程序端,并在它们上运行更新。

标签: java jpa db2 jpql


【解决方案1】:

在 JPQL 中无法执行这样的查询。您必须使用 SQL。

或者您可以执行以下查询:

SELECT a FROM Account a WHERE a.Status = '' AND a.Type = :type

并在执行查询之前调用setMaxResults(5)。结果,您将获得 5 个帐户(最多),您可以更改 5 个返回帐户的状态、代码和时间戳。

不过,我发现获取没有任何 order by 子句的查询的前 5 行很奇怪。

【讨论】:

  • 将有 1 个选择查询和 0 到 5 个更新查询,具体取决于实体的数量和实体的当前状态。 JPA 引擎可以将 5 个更新放在一个批次中。这是修改一小组实体的典型方式。
猜你喜欢
  • 2018-08-22
  • 2022-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多