2012-05-12 41 views
0

大家早上好!使用MERGE語句獲取表格(記錄)正確更新

下面是我拼接在一起的一段代碼:我使用CTE從鏈接表中獲取記錄(數據),並將字符串轉換爲日期,而不是使用merge語句將數據獲取到本地表中:

我有問題的列(字段)LAST_RACE_DATE此字段設置爲NULL,並不是必需的,但它不會更新與我目前的設置。我試圖完成的是這個字段填充數據輸入時,但也更新,這意味着它也應該更新爲NULL。

因此,如果該字段具有特定的日期,並且在遠程數據庫中輸入了新日期,則該字段也應該更新,即使數據在後端被刪除,它也應該刪除本地表數據爲這個領域。

WITH CTE AS(

SELECT MEMBER_ID 
    ,[MEMBER_DATE] = MAX(CONVERT(DATE, MEMBER_DATE)) 
    ,RACE_DATE = MAX(CONVERT(DATE, RACE_DATE)) 
    ,LAST_RACE_DATE = MAX(CONVERT(DATE, LAST_RACE_DATE)) 

FROM [EXAMPLE].[dbo].[LINKED_MEMBER_DATA] 
WHERE (MEMBER_DATE IS NOT NULL) AND (ISDATE(MEMBER_DATE)<> 0) AND (RACE_DATE IS NOT NULL) AND (ISDATE(RACE_DATE)<> 0) 
     AND (LAST_RACE_DATE IS NULL) OR (ISDATE(LAST_RACE_DATE)<> 0) 

GROUP BY MEMBER_ID) 

MERGE dbo.LINKED_MEMBER_DATA AS Target 
USING (SELECT 
    MEMBER_ID, MEMBER_DATE, RACE_DATE, LAST_RACE_DATE 

FROM CTE 

GROUP BY MEMBER_ID, RACE_DATE, LAST_RACE_DATE)AS SOURCE ON (Target.MEMBER_ID = SOURCE.MEMBER_ID) 

WHEN MATCHED AND 
    (Target.MEMBER_DATE) <> (SOURCE.MEMBER_DATE) 
OR (Target.RACE_DATE) <> (SOURCE.RACE_DATE) 
OR ISNULL(TARGET.LAST_RACE_DATE , Target.LAST_RACE_DATE) <> ISNULL(SOURCE.LAST_RACE_DATE, SOURCE.LAST_RACE_DATE) 

THEN UPDATE SET 

Target.MEMBER_DATE = SOURCE.MEMBER_DATE 
,Target.RACE_DATE = SOURCE.RACE_DATE 
,Target.LAST_RACE_DATE = SOURCE.LAST_RACE_DATE 

WHEN NOT MATCHED BY TARGET THEN 
INSERT(
MEMBER_ID, MEMBER_DATE, RACE_DATE, LAST_RACE_DATE) 

VALUES (Source.MEMBER_ID, Source.MEMBER_DATE, Source.RACE_DATE, Source.LAST_RACE_DATE); 

我也試過這樣:

ISNULL(Target.LAST_RACE_DATE,'N/A') <> ISNULL(SOURCE.LAST_RACE_DATE,'N/A') 

但它產生下面的錯誤的日期轉換:從字符串轉換日期和/或時間時

轉換失敗。

非常感謝!

回答

1

由於ISNULL您沒有做任何事情(如果其中一個值爲NULL,表達式將計算爲NULL),您的當前語句失敗,並且NULL值不會進行比較。您的第二次嘗試不起作用,因爲ISNULL要求這兩個值的數據類型相同,所以您可以嘗試,例如ISNULL(Target.LAST_RACE_DATE, '1970-01-01') <> ISNULL(Source.LAST_RACE_DATE, '1970-01-01')。 (((Source.LAST_RACE_DATE IS NULL AND Target.LAST_RACE_DATE IS NOT NULL) OR (Source.LAST_RACE_DATE IS NOT NULL AND Target.LAST_RACE_DATE IS NULL) OR (Source.LAST_RACE_DATE <> Target.LAST_RACE_DATE)))枚舉不同的情況使得代碼更加冗長一些,但它可以帶來更好的性能(無論是明顯更好的實際上取決於如何實現你正在處理的數據很多)

+0

謝謝Chris, 你的第一個例子和我提到的一樣: ISNULL(Target.LAST_RACE_DATE,'N/A')<> ISNULL(SOURCE.LAST_RACE_DATE,'N/A '),並按照我的說法提取日期的錯誤,那麼日期值是否會產生影響?只需要詢問 – Asynchronous

+0

是的,'N/A'不是日期/時間值,您需要後退值具有相同的值鍵入您正在檢查的值爲NULL。 –

+0

謝謝你的時間和精力。我更喜歡第二種解決方案,並同意你的看法。再次感謝! – Asynchronous