我正在两个表之间执行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
之间的相等性?什么方法可以产生最快的执行力?
你可以做这样的事情:(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)
你可以试试。
ISNULL (targ. Name,'a magic string value') =ISNULL (src.ConstituentName,'a magic string value')
当然,根据需要添加您自己的魔术字符串,例如使用 newid () 获取 guid 并使用它。
不太确定这是否比 and or "更好",但更易于阅读;值得对这两种方法进行基准测试和测试。