2014-09-29 67 views
1
MERGE DestinationTable AS D 
USING SourceTable AS S 
ON D.Alternate_ID = S.ID 
WHEN MATCHED AND 
(
     D.ID <> S.ID 
    OR D.col1 <> S.col1 
    OR D.col2 <> S.col2 
    OR D.col3 <> S.col3 
    OR D.col4 <> S.col4 
    OR D.col5 <> S.col5 
    OR D.col6 <> S.col6 
    OR D.col7 <> S.col7 
    OR D.col8 <> S.col8 
) 

大家好,我試圖更新DestinationTable,如果SourceTable中的任何列值已經使用上面的合併語句片段更改。但是,如果我在目標列中有一個NULL值並且源中有字符串或位值,則比較D.col8 <> S.col8將返回false,因爲SQL處理與NULL值的比較方式。因此,DestinationTable不會使用SourceTable中的新值更新。在SQL Server中比較NULL與字符串

解決此問題的更好方法是什麼?如果D.Col8是NULL並且S.Col8有一個字符串或位值,我仍然想要爲表達式返回true,如D.col8 <> S.col8

因此,如果我在S.Col8中具有「Test」的值並且NULL D.Col8,我想更新從空目標列 「測試」

+0

執行更新時,沒有列*實際*更改了您需要消除的可測量成本? – 2014-09-29 07:15:48

+0

d.col8不爲空,d.col8 <> s.col8 – DwB 2014-09-29 07:16:04

+0

@Damien_The_Unbeliever,是的,這是可取的。 – StackTrace 2014-09-29 07:19:23

回答

3
MERGE DestinationTable AS D 
USING SourceTable AS S 
ON D.Alternate_ID = S.ID 
WHEN MATCHED AND 
(
     D.ID <> S.ID 
    OR (D.col1 IS NULL AND S.col1 IS NOT NULL) 
     OR (D.col1 IS NOT NULL AND S.col1 IS NULL) 
     OR D.col1 <> S.col1 
    OR (D.col2 IS NULL AND S.col2 IS NOT NULL) 
     OR (D.col2 IS NOT NULL AND S.col2 IS NULL) 
     OR D.col2 <> S.col2 
    OR (D.col3 IS NULL AND S.col3 IS NOT NULL) 
     OR (D.col3 IS NOT NULL AND S.col3 IS NULL) 
     OR D.col3 <> S.col3 
    OR (D.col4 IS NULL AND S.col4 IS NOT NULL) 
     OR (D.col4 IS NOT NULL AND S.col4 IS NULL) 
     OR D.col4 <> S.col4 
    OR (D.col5 IS NULL AND S.col5 IS NOT NULL) 
     OR (D.col5 IS NOT NULL AND S.col5 IS NULL) 
     OR D.col5 <> S.col5 
    OR (D.col6 IS NULL AND S.col6 IS NOT NULL) 
     OR (D.col6 IS NOT NULL AND S.col6 IS NULL) 
     OR D.col6 <> S.col6 
    OR (D.col7 IS NULL AND S.col7 IS NOT NULL) 
     OR (D.col7 IS NOT NULL AND S.col7 IS NULL) 
     OR D.col7 <> S.col7 
    OR (D.col8 IS NULL AND S.col8 IS NOT NULL) 
     OR (D.col8 IS NOT NULL AND S.col8 IS NULL) 
     OR D.col8 <> S.col8 
) 
+0

此解決方案不會處理源表中空值的情況 – Paolo 2014-09-29 08:05:05

+0

將此標記爲答案,因爲如果列數據類型是uniqueidentifier,ISNULL(D.col1,'')<> S.col1將失敗。 – StackTrace 2014-09-29 08:05:17

+0

@Paolo SO表示可能Destination表有NULL,而不是Source。爲什麼要檢查這是不可能的事情? – 2014-09-29 09:03:09

0

試試這個:

... 
WHEN MATCHED AND 
(
    ISNULL(D.ID, '') <> S.ID 
    OR ISNULL(D.col1, '') <> S.col1 
    OR ISNULL(D.col2, '') <> S.col2 
    OR ISNULL(D.col3, '') <> S.col3 
    OR ISNULL(D.col4, '') <> S.col4 
    OR ISNULL(D.col5, '') <> S.col5 
    OR ISNULL(D.col6, '') <> S.col6 
    OR ISNULL(D.col7, '') <> S.col7 
    OR ISNULL(D.col8, '') <> S.col8 
) 
0

嘗試像

MERGE DestinationTable AS D 
USING SourceTable AS S ON D.Alternate_ID = S.ID 
WHEN MATCHED AND 
(
    ISNULL(D.ID, '') <> ISNULL(S.ID,'') 
    OR ISNULL(D.col1, '') <> ISNULL(S.col1,'') 
    OR ISNULL(D.col2, '') <> ISNULL(S.col2,'') 
    OR ISNULL(D.col3, '') <> ISNULL(S.col3,'') 
    OR ISNULL(D.col4, '') <> ISNULL(S.col4,'') 
    OR ISNULL(D.col5, '') <> ISNULL(S.col5,'') 
    OR ISNULL(D.col6, '') <> ISNULL(S.col6,'') 
    OR ISNULL(D.col7, '') <> ISNULL(S.col7,'') 
    OR ISNULL(D.col8, '') <> ISNULL(S.col8,'') 
) 

D.IDS.IDD.colxS.colx也可能是Null

0

INTERSECT and EXCEPT處理NULL你想要的方式。 (即NULL = NULL

... 
WHEN MATCHED 
    AND EXISTS (SELECT D.Col1, D.Col2, ... 
       EXCEPT S.Col1, S.Col2, ...) 
1

你可以做很多與BINARY_CHECKSUM簡單:

MERGE DestinationTable AS D 
USING SourceTable AS S 
ON D.Alternate_ID = S.ID 
WHEN MATCHED AND 
BINARY_CHECKSUM(d.col1, d.col2, ...,d.col8) <> BINARY_CHECKSUM(s.col1, ..., s.col8) 

存在具有假陰性的小衝突概率(值變化,但是校驗和是相同的),但是可以忽略不計。