2012-12-06 59 views
3

我執行MERGE兩者表在SQL中使用NULL列的最佳方式是什麼?

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列之間的平等?什麼方法會產生最快的執行?

回答

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) 
+0

有沒有其他的方式來做到這一點,或者是否有可能通過重寫謂詞來做到這一點?根據MSDN,設置ANSI_NULLS OFF似乎不是未來的證明。 –

+0

是的。根據我最近的編輯創建一個UDF。這樣你就可以獲得一個面向未來和可重用的函數,它比ANSI NULL或extra謂詞解決方案更具可讀性。 –

+0

添加了一個示例UDF作爲我正在談論的具體示例 –

2

你可以嘗試..

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

當然,增加自己的魔法字符串作爲適合於例如使用newid()獲得一個GUID並使用它。

不確定這是否比「和」更「好」,但是更具人類可讀性;雖然值得基準測試和測試兩種方法。

相關問題