Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
T-SQL合并与更新集CASE语句-没有其他语句会发生什么?_Sql_Tsql_Sql Server 2012 - Fatal编程技术网

T-SQL合并与更新集CASE语句-没有其他语句会发生什么?

T-SQL合并与更新集CASE语句-没有其他语句会发生什么?,sql,tsql,sql-server-2012,Sql,Tsql,Sql Server 2012,我正在编写一个TSQL MERGE语句来处理通常的UPDATE和INSERT组合。我有几个select列,只有在(例如)参数设置为TRUE时才应该更新这些列。例如: ... UPDATE SET TARGET.[SomeColumn] = CASE WHEN @someParameter = 1 THEN SOURCE.[SomeColumn] END, ... 根据我能找到的所有文档,ELSE肯定是可选的(就像大多数语言一样),但我不明白如果省

我正在编写一个TSQL MERGE语句来处理通常的UPDATE和INSERT组合。我有几个select列,只有在(例如)参数设置为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、保持值不变还是…?

事实上,它在
合并中的
更新
中并不重要,尽管您不知道这一点。有关:

ELSE
ELSE\u结果\u表达式

如果否,表达式是否返回 比较操作的计算结果为
TRUE
。如果省略此参数 并且没有比较操作的计算结果为
TRUE
CASE
返回
NULL


根据MSDN,案例中的“无其他”表示为空

然而,MERGE提供了另一种方法,可以用于多个列

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

我知道这是一个老生常谈的问题,但这里有一个我为我实现的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
 )
;

如果省略了
else
,则
case
语句返回
NULL
。因此,该值被设置为
NULL
。正如@GordonLinoff所说,对于与WHEN语句不匹配的任何内容,您都会得到
NULL
,否则将提供一个全面信息,告诉它如何处理与WHEN语句之一不匹配的所有内容(记住,您可以有多个WHEN语句)“当你这样说的时候,@GordonLinoff是非常有道理的。非常感谢您的及时回复。@Bridge感谢您的确认。答案很简单,我开始觉得问这个问题有点傻了!这是一个很好的建议,在我这个简单的例子中,效果非常好。最初我想这样做,但实际上在我的例子中有一些参数需要这样做,当然单个MERGE语句不能多次更新同一条记录。有时我想知道在我的例子中,拆分INSERT和UPDATE是否会更好,以简化两者,但是我总是尝试寻找一次性执行所有任务的方法(如果可能)。感谢您指出这一部分。我读了同一页,但不知怎么的,我完全错过了那一部分!!!