3

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列之间的相等性?什么方式会产生最快的执行?

4

2 回答 2

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)
于 2012-12-06T19:20:01.657 回答
2

你可以试试。。

ISNULL (targ. Name,'a magic string value') =ISNULL (src.ConstituentName,'a magic string value') 

当然,根据需要添加您自己的魔术字符串,例如使用 newid () 获取 guid 并使用它。

不确定这是否比 and or “更好”,但更具人类可读性;值得对这两种方法进行基准测试和测试。

于 2012-12-06T19:39:42.220 回答