2012-05-12 48 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