T-SQL合并与更新集CASE语句-没有其他语句会发生什么?
我正在编写一个TSQL MERGE语句来处理通常的UPDATE和INSERT组合。我有几个select列,只有在(例如)参数设置为TRUE时才应该更新这些列。例如: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肯定是可选的(就像大多数语言一样),但我不明白如果省
...
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是否会更好,以简化两者,但是我总是尝试寻找一次性执行所有任务的方法(如果可能)。感谢您指出这一部分。我读了同一页,但不知怎么的,我完全错过了那一部分!!!