如何在 hql 中使用来自 select 的更新?

How to use update from select in hql?

我试过这个:

    using (var s = HibernateSessionFactory.OpenStatelessSession())
        s.CreateQuery(
            @"UPDATE Guild as gg SET gg.PersistentXPSum = el.XPSum 
              WHERE gg.Id=el.GuildId FROM 
                (SELECT SUM(XP) AS XPSum, GuildId FROM User 
                     WHERE GuildId != null GROUP BY GuildId 
                     ORDER BY XPSum desc LIMIT 50) el").ExecuteUpdate();

但是它在第 2 行第 41 列给出 Antlr.Runtime.MismatchedTokenException

如何让它发挥作用?

您可以尝试以下查询:

s.createQuery("UPDATE Guild as gg SET gg.PersistentXPSum = el.XPSum WHERE gg.Id in (SELECT el.GuildId FROM (SELECT SUM(XP) AS XPSum, GuildId FROM User WHERE GuildId != null GROUP BY GuildId ORDER BY XPSum desc LIMIT 50) el)").executeUpdate();

如此处所述

13.3. DML-style operations

...
The pseudo-syntax for UPDATE and DELETE statements is: ( UPDATE | DELETE ) FROM? EntityName (WHERE where_conditions)?. Some points to note:

  • ...
  • No joins (either implicit or explicit) can be specified in a bulk HQL query. Sub-queries may be used in the where-clause; the subqueries, themselves, may contain joins.

所以,我们知道,我们可以使用 SUBQUERY。但这确实 不是 表示此语法 (请参阅下面的有效语法)

... = el.GuildId  FROM (SELECT ...) el")`

另外,非常重要的一点。 没有办法,如何在内部 HQL(子)查询中指定 LIMIT。所以,让我们假设我们知道 50th 值:例如1000.

工作查询如下:

s.CreateQuery(
    @"UPDATE Guild as gg 
      SET gg.PersistentXPSum = el.XPSum 
      WHERE gg.Id IN
        (SELECT GuildId FROM User 
             WHERE GuildId != null 
             GROUP BY GuildId 
             HAVING SUM(XP) > 1000) el")
 .ExecuteUpdate();

注意:这肯定适用于 SQL 服务器。也许应该对 postgresql 进行一些调整...但不是那么重要...