2012-05-12 3 views
0

Доброе утро всем!Получение таблицы (записей) для надлежащего обновления с использованием заявления MERGE

Ниже приведен фрагмент кода, который я сшивал: я использовал CTE, чтобы захватить записи (данные) из таблицы ссылок и преобразовать строки в даты, чем использовать оператор слияния для получения данных в локальной таблице:

У меня проблема с столбцом (полем) 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 s, что у вас нет, ничего не делает (если одно из значений равно 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

Спасибо Крис, Ваш первый пример такой же, как то, что я говорил:. ISNULL (Target.LAST_RACE_DATE, 'N/A') <> ISNULL (SOURCE.LAST_RACE_DATE, 'N/A '), и он рисует ошибки для дат, как я уже сказал. Так что, имея значение даты, имеет значение? Просто спрашиваю. – Asynchronous

+0

Да, «N/A» не является значением даты/времени, вам нужно, чтобы запасное значение имело тот же введите значение, которое вы проверяете против NULL. –

+0

Спасибо за ваше время и силы. Я предпочитаю второе решение и соглашаюсь с вами. Еще раз спасибо! – Asynchronous

Смежные вопросы