简体   繁体   English

集合中的SQL Case语句; 总是火吗?

[英]SQL Case Statement in set; Does it always fire?

I was wondering if in the following statement: 我想知道是否在以下声明中:

  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

If the conditions in the case statement are not met, for example u.IsActive=1 and e.LVStatus='B', will the query still set u.UpdatedBy=0? 如果不满足case语句中的条件,例如u.IsActive = 1和e.LVStatus ='B',查询是否仍然设置为u.UpdatedBy = 0? I was hoping if the conditions in the case statement are not met then do nothing, perhaps if I want that behavior I need to just have to separate update statements with different where clauses. 我希望如果不满足case语句中的条件然后什么都不做,也许如果我想要这种行为,我需要只需要用不同的where子句分隔update语句。 Thanks! 谢谢!

Since your query sets u.UpdatedBy to zero unconditionally, the answer is yes, the value of u.UpdatedBy will be set regardless of the outcome of the CASE expression through which u.isactive is set. 由于您的查询无条件地将u.UpdatedBy设置为零,因此答案是肯定的,无论设置u.UpdatedByCASE表达式的结果如何,都将设置u.isactive的值。

To overcome this, you could add a separate CASE expression for the u.UpdatedBy field, and use the current value when the conditions of the other CASE statement are not met: 要解决此问题,您可以为u.UpdatedBy字段添加单独的CASE表达式,并在u.UpdatedBy其他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

Alternatively, you could move that condition into the WHERE clause, like this: 或者,您可以将该条件移动到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)

Both set conditions will always work. 两种设定条件始终有效。 A CASE expression without an ELSE clause has an implicit ELSE NULL . 没有ELSE子句的CASE表达式具有隐式ELSE NULL See here . 看到这里

If u.isactive has a NOT NULL constraint, you'll get a constraint violation and nothing will be updated by the statement. 如果u.isactive具有NOT NULL约束,则会出现约束违规,并且该语句不会更新任何内容。

Just do SET u.isactive = (CASE... ELSE u.isactive end) . 只做SET u.isactive = (CASE... ELSE u.isactive end)

That way, if your criteria in the case statment aren't met, just leave it as the existing value. 这样,如果未满足案例陈述中的条件,则将其保留为现有值。 You could probably get away with no else statement, but I am never comfortable with that. 你可能没有别的陈述,但我对此并不满意。

One way of doing this is to add an else clause and return the column's original value: 一种方法是添加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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM