带有UPDATE SET CASE语句的T-SQL MERGE - 没有ELSE会发生什么?

时间:2014-03-12 12:12:26

标签: sql tsql sql-server-2012

我正在编写TSQL MERGE语句来处理UPDATE和INSERT的通常组合。我有几个选择列,只有在(例如)参数设置为TRUE时才应更新。例如:

...
UPDATE SET
    TARGET.[SomeColumn] =
        CASE
        WHEN @someParameter = 1 THEN SOURCE.[SomeColumn]
    END,
...

根据我能找到的所有文档,ELSE绝对是可选的(与大多数语言一样)但我不明白如果在此处省略会发生什么。

我当然可以做以下事情:

...
UPDATE SET
    TARGET.[SomeColumn] =
        CASE
        WHEN @someParameter = 1 THEN SOURCE.[SomeColumn]
        ELSE TARGET.[SomeColumn] --This is the new line
    END,
...

..但这似乎带来了在重写现有价值时感觉不必要的开销。

所以我的问题是如果省略ELSE并且@someParameter设置为0(FALSE)会发生什么,这会失败,设置为NULL,保持值不变,还是......?< / p>

3 个答案:

答案 0 :(得分:3)

答案 1 :(得分:3)

CASE中没有ELSE表示根据MSDN

的NULL

但是,MERGE提供了另一种方法,可以用于多列

WHEN MATCHED AND @someParameter = 1 THEN
    UPDATE SET
        TARGET.[SomeColumn] = SOURCE.[SomeColumn],
        TARGET.[SomeColumn2] = SOURCE.[SomeColumn2]

答案 2 :(得分:0)

我知道这是一个古老的问题,但这是我为实施的ETL作业整理的一个示例。它似乎确实需要else语句才能正常工作。这是在带有临时表的SQL Server 2017中。

-- match to target on id
merge into Flags with (tablock) as target
using #Flags as source
  on source.id = target.id
-- on match update row
when matched then
  update set
    -- flags 1-4 can't be switched back to false from a true state
    target.flag1 = (
      case when source.flag1 >= target.flag1
        then source.flag1 
        else target.flag1 
      end ),
    target.flag2 = (
      case when source.flag2 >= target.flag2
        then source.flag2 
        else target.flag2 
      end ),
    target.flag3 = (
      case when source.flag3 >= target.flag3
        then source.flag3 
        else target.flag3 
      end ),
    target.flag4 = (
      case when source.flag4 >= target.flag4
        then source.flag4 
        else target.flag4 
      end ),
    -- flag 5 can only be true if flag 4 is be false
    target.flag5 = (
      case when target.flag4 = 1 
          or source.flag4 = 1 
        then 0 
        when source.flag5 >= target.flag5
        then source.flag5
        else target.flag5 
      end ),
    -- flag 6 can only be true if flags 4 & 5 are both false
    target.flag6 = (
      case when (target.flag4 = 1 
          or target.flag5 = 1) or 
            (source.flag4 = 1 
          or source.flag5 = 1)
        then 0 
        when source.flag6 >= target.flag6
        then source.flag6
        else target.flag6 
      end ),
    -- flag 7 can only be true if flags 4-6 are all false
    target.flag7 = (
      case when (target.flag4 = 1 
          or target.flag5 = 1
          or target.flag6 = 1) or 
            (source.flag4 = 1 
          or source.flag5 = 1
          or source.flag6 = 1)
        then 0 
        when source.flag7 >= target.flag7
        then source.flag7
        else target.flag7 
      end ),
    -- normal updates
    target.flag8 = source.flag8,
    target.flag9 = source.flag9 
-- no match insert row
when not matched by target then
  insert (
    id,
    flag1,
    flag2,
    flag3,
    flag4,
    flag5,
    flag6,
    flag7,
    flag8,
    flag9
  ) values (
    source.id,
    source.flag1,
    source.flag2,
    source.flag3,
    source.flag4,
    source.flag5,
    source.flag6,
    source.flag7,
    source.flag8,
    source.flag9
 )
;