2013-03-12 58 views
3

這些行通常第一次進入目標表的方式是使用大量文本數據填充的列的稀疏數量,其餘列設置爲NULL。在隨後的傳遞中,新數據填充現有已知(非空)和未知(NULL)數據。我確定新數據(#pld)確實包含不同的數據。數據似乎沒有改變。下面是我有:sql server:MERGE有意想不到的結果

BEGIN TRANSACTION 

    BEGIN TRY 


    MERGE INTO [metro].listings AS metroList 
    USING #pld as listnew 
     ON metroList.id = listnew.id 
     AND metroList.sid = listnew.sid 
     WHEN MATCHED AND (
     metroList.User != listnew.User 
     or metroList.Email != listnew.Email 
     or metroList.LocName != listnew.LocName 
    ) THEN 
    UPDATE SET 
    metroList.User = listnew.User, 
    metroList.Email = listnew.Email, 
    metroList.LocName = listnew.LocName, 
    WHEN NOT MATCHED THEN 
    INSERT 
    (User, 
    Email, 
    LocName 
    ) 
    VALUES 
    (
    listnew.User, 
    listnew.Email, 
     listnew.LocName 
    ); 

    COMMIT TRANSACTION 

END TRY 


IF @@TRANCOUNT > 0 
    ROLLBACK TRANSACTION; 

END CATCH 

我試着更換=該聲明的更新部分根據與<>!相同的結果。這必須與可能的(可能的)空值與字符串的比較相關 - 甚至可能是另一個空值?無論如何,我打電話給所有的sql-geeks來解決這個問題。

回答

3

此外,您可以使用NULLIF()功能的選項。

如果兩個表達式不相等,則NULLIF返回第一個表達式。如果表達式相等,則NULLIF返回第一個表達式類型的空值。

WHEN MATCHED AND (
        NULLIF(ISNULL(metroList.[User],''), listnew.[User]) IS NOT NULL 
        OR NULLIF(ISNULL(metroList.Email, ''), listnew.Email) IS NOT NULL 
        OR NULLIF(ISNULL(metroList.LocName, ''), listnew.LocName) IS NOT NULL 
       ) 
THEN 
+0

看起來不正確我。 – 2013-03-13 07:22:41

+0

ooops.My fault.NULLIF()函數在 的第一個值爲NULL時不起作用。在我的更新中,我使用ISNULL()進行了檢查。我再次對不起,感謝@Martin Smith +100500 – 2013-03-13 08:30:05

2

比較NULL與空字符串將不起作用。

如果任何一方都可以是NULL,你可以這樣做:

WHEN MATCHED AND (
     COALESCE(metroList.User, '') <> COALESCE(listnew.User, '') 
    or COALESCE(metroList.Email, '') <> COALESCE(listnew.Email, '') 
    or COALESCE(metroList.LocName, '') <> COALESCE(listnew.LocName, '') 
    ) THEN 

當然,這是假設你是罰款NULL意思等同於一個空字符串(這可能不適合) 。

看看this BOL articleNULL比較。

2

據我所知,你正在尋找一個模擬IS DISTINCT FROM表達的問題。

你接受的答案是不正確的,然後

WITH metroList([User]) 
    AS (SELECT CAST(NULL AS VARCHAR(10))), 
    listnew([User]) 
    AS (SELECT 'Foo') 
SELECT * 
FROM metroList 
     JOIN listnew 
     ON NULLIF(metroList.[User], listnew.[User]) IS NOT NULL 

返回零行。儘管比較值爲NULLFoo

我會使用的技術從這篇文章:Undocumented Query Plans: Equality Comparisons

WHEN MATCHED AND EXISTS (
         SELECT metroList.[User], metroList.Email,metroList.LocName 
         EXCEPT 
         SELECT listnew.[User], listnew.Email,listnew.LocName 
         )  
+0

選項,EXCEPT是最好的;) – 2013-03-13 08:54:42