我在两个表之间执行MERGE
MERGE indexdecomp.Constituent targ
USING (SELECT ic.ConstituentName
FROM indexdecomp.IndexConstituents ic) src
ON (((targ.Name = src.ConstituentName) OR (targ.Name IS NULL AND src.ConstituentName IS NULL)))
WHEN NOT MATCHED BY TARGET THEN
UPDATE SET
targ.Name = src.ConstituentName
;
在我的ON
子句中,我有以下谓词:
(targ.Name = src.ConstituentName) OR (targ.Name IS NULL AND src.ConstituentName IS NULL)
我有这个谓词,因为如果两个名称相等或者两个名称都是“null”,我认为它是匹配的。
是否有更好或更传统的方法来处理两个null
列之间的相等性?什么方式会产生最快的执行?
答案 0 :(得分:3)
您可以这样做:(SQL ref)
SET ANSI_NULLS OFF;
MERGE indexdecomp.Constituent targ
USING (SELECT ic.ConstituentName
FROM #IndexConstituents ic) src
ON (((targ.Name = src.ConstituentName)))
WHEN NOT MATCHED BY TARGET THEN
UPDATE SET
targ.Name = src.ConstituentName;
SET ANSI_NULLS ON;
但是,这似乎是一个非常重要的权衡,因为它不是一个谓词,也不是非常可读。实际上,您可以使用带有两个字符串参数并返回布尔值的UDF来抽象这个混乱。
类似的东西:
create function StrNullCompare(@a varchar(max), @b varchar(max))
returns int
as
begin
if ((@a = @b) or (@a is null and @b is null)) return 1;
return 0;
end
-- tests
select dbo.StrNullCompare('wer', 'were');
select dbo.StrNullCompare('wer', 'wer');
select dbo.StrNullCompare('hi', null);
select dbo.StrNullCompare(null, null);
你的谓词变为:
(dbo.StrNullCompare(targ.Name, src.ConstituentName)=1)
答案 1 :(得分:2)
你可以试试..
ISNULL (targ. Name,'a magic string value') =ISNULL (src.ConstituentName,'a magic string value')
当然,根据需要添加自己的魔术字符串,例如使用newid()获取guid并使用它。
不确定这是否比“和/或更具人性”更“好”;值得对这两种方法进行基准测试和测试。