Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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? 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. Thanks!

like image 346
Angel Cloudwalker Avatar asked May 27 '26 16:05

Angel Cloudwalker


2 Answers

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.

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:

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:

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)
like image 99
Sergey Kalinichenko Avatar answered May 30 '26 02:05

Sergey Kalinichenko


Both set conditions will always work. A CASE expression without an ELSE clause has an implicit 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.

like image 23
Bacon Bits Avatar answered May 30 '26 02:05

Bacon Bits



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!