【问题标题】:SQL Case Statement in set; Does it always fire?集合中的 SQL 案例语句;总是火吗?
【发布时间】:2014-10-14 15:10:29
【问题描述】:

我想知道是否在以下语句中:

  UPDATE u 
  SET u.isactive = 
        (
        CASE WHEN e.LVStatus<>'B' AND u.IsActive=1 AND u.AutoUpdate=1 THEN 
              0
        WHEN e.LVStatus='B' AND u.IsActive=0 AND u.AutoUpdate=1 THEN 
              1 END
         ),
      u.UpdatedB y= 0 
  FROM tbl_e e                                        
       INNER JOIN tbl_Users u ON e.id=u.id

如果不满足case语句中的条件,例如u.IsActive=1和e.LVStatus='B',查询是否仍然设置u.UpdatedBy=0?我希望如果不满足 case 语句中的条件然后什么也不做,也许如果我想要这种行为,我只需要用不同的 where 子句分隔 update 语句。谢谢!

【问题讨论】:

    标签: sql sql-server tsql sql-server-2008-r2 sql-server-2012


    【解决方案1】:

    由于您的查询将u.UpdatedBy 无条件设置为零,因此答案是肯定的,无论CASE 表达式的结果如何,u.UpdatedBy 的值都将被设置,u.isactive 是通过该表达式设置的。

    要克服这个问题,您可以为u.UpdatedBy 字段添加单独的CASE 表达式,并在不满足其他CASE 语句的条件时使用当前值:

    UPDATE u 
    SET u.isactive = CASE
            WHEN e.LVStatus<>'B' AND u.IsActive=1 AND u.AutoUpdate=1 THEN 0
            WHEN e.LVStatus='B' AND u.IsActive=0 AND u.AutoUpdate=1 THEN 1
            ELSE u.isactive
        END
    ,   u.UpdatedBy= CASE
            WHEN (e.LVStatus<>'B' AND u.IsActive=1 AND u.AutoUpdate=1) OR
                 (e.LVStatus='B' AND u.IsActive=0 AND u.AutoUpdate=1)
            THEN 0
            ELSE u.UpdatedBy
        END 
    FROM tbl_e e                                        
         INNER JOIN tbl_Users u ON e.id=u.id
    

    或者,您可以将该条件移动到 WHERE 子句中,如下所示:

    UPDATE u 
    SET u.isactive = CASE
            WHEN e.LVStatus<>'B' AND u.IsActive=1 AND u.AutoUpdate=1 THEN 0
            WHEN e.LVStatus='B' AND u.IsActive=0 AND u.AutoUpdate=1 THEN 1
            -- No ELSE is needed, because WHERE filters out all other cases
        END
    ,   u.UpdatedBy=0
    FROM tbl_e e
    INNER JOIN tbl_Users u ON e.id=u.id
    WHERE (e.LVStatus<>'B' AND u.IsActive=1 AND u.AutoUpdate=1) OR
          (e.LVStatus='B' AND u.IsActive=0 AND u.AutoUpdate=1)
    

    【讨论】:

    • 替代方案正是我想做的,虽然我可以更新到相同的值,但替代解决方案对我来说是一种更清洁的方法。谢谢!
    【解决方案2】:

    两个设置条件都将始终有效。没有ELSE 子句的CASE 表达式具有隐含的ELSE NULL。见here

    如果u.isactive 具有NOT NULL 约束,您将违反约束并且该语句不会更新任何内容。

    【讨论】:

      【解决方案3】:

      只要SET u.isactive = (CASE... ELSE u.isactive end)

      这样,如果不满足您在案例陈述中的条件,只需将其保留为现有值。没有 else 声明你可能会侥幸逃脱,但我对此并不满意。

      【讨论】:

        【解决方案4】:

        一种方法是添加else 子句并返回列的原始值:

        UPDATE u 
          SET u.isactive=(CASE WHEN e.LVStatus<>'B' AND u.IsActive=1 AND u.AutoUpdate=1 THEN 0
                               WHEN e.LVStatus='B' AND u.IsActive=0 AND u.AutoUpdate=1 THEN 1 
                               ELSE u.isactive END),
              u.UpdatedBy=0 
          FROM tbl_e e                                        
               INNER JOIN tbl_Users u ON e.id=u.id
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-19
          相关资源
          最近更新 更多