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

时间:2015-02-05 08:50:33

标签: hibernate postgresql nhibernate 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

如何让它发挥作用?

2 个答案:

答案 0 :(得分:1)

如此处所述

13.3. DML-style operations

  

...
  UPDATE和DELETE语句的伪语法是:(UPDATE | DELETE)FROM? EntityName(WHERE where_conditions)?有些要点需要注意:

     
      
  • ...
  •   
  • 可以在批量HQL查询中指定无连接(隐式或显式)。 可以在where子句中使用子查询;子查询本身可能包含连接
  •   

因此,我们知道,我们可以使用SUBQUERY。但表示此语法(请参阅下面的有效语法)

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

而且,非常重要的说明。有 NO方式,如何在内部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 Server。也许应该有一些关于postgresql的调整......但不是那么重要......

答案 1 :(得分:-1)

您可以尝试以下查询:

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();