2016-11-24 2 views
0

Привет и хороший день всем. Я пытаюсь выполнить следующую последовательность на двух таблицах table2 и table1.SQL - Объединить попытку INSERT вместо UPDATE из-за столбцов NULL

MERGE INTO table2 WITH (HOLDLOCK) AS target 
    USING 
    (
     SELECT column1, 
      MAX(AccessDate) AS AccessDate, 
      SUM(AccessCount) AS AccessCount, 
      column4, 
      column5, 
      column6, 
      column7, 
      column8 
     FROM table1 
     GROUP BY column1, column4, column5, column6, column7, column8 
    ) AS source 
    ON target.column1 = source.column1 AND 
     target.column5 = source.column5 AND 
     target.column6 = source.column6 AND 
     target.column7 = source.column7 AND 
     target.column8 = source.column8 
    WHEN MATCHED THEN 
    UPDATE SET target.LastAccessDate = source.AccessDate, 
     target.LastWeeklyAccessCount = source.AccessCount 
    WHEN NOT MATCHED BY TARGET THEN 
     INSERT (column1, LastAccessDate, LastWeeklyAccessCount, column4, column5, column6, column7, column8) 
     VALUES (source.column1, source.AccessDate, source.AccessCount, source.column4, source.column5, source.column6, source.column7, source.column8); 

С существующими датами в table1 он делает то, что он должен делать. Если вставить еще одну запись в table1 с РЕГИСТРИРУЙТЕСЬ условия выполнены, он пытается вставить вместо UPDATE из-за NULL <> NULL при сравнении двух таблиц, и это приходит из-за уникального ограничения у меня есть:

Невозможно вставить дубликат ключа в объект 'dbo.table2'.

Может ли кто-нибудь помочь мне исправить эту проблему?

+0

Какие поля могут быть «NULL»? – gotqn

+0

'column5',' column6', 'column8' –

+0

Будет ли он работать корректно, если вы сопоставляете' null' с 'null':' ((target.column5 = source.column5) OR (target.column5 IS NULL AND source.column5 IS NULL)) AND'. Simlarly для других столбцов, которые могут быть null ... – user1429080

ответ

1

Один из способов сделать это:

ON target.column1 = source.column1 AND 
    ISNULL(NULLIF(target.column5, source.column5), 
      NULLIF(source.column5, target.column5)) IS NULL AND 
    ISNULL(NULLIF(target.column6, source.column6), 
      NULLIF(source.column6, target.column6)) IS NULL AND 
    target.column7 = source.column7 AND 
    ISNULL(NULLIF(target.column8, source.column8), 
      NULLIF(source.column8, target.column8)) IS NULL 

NULLIF возвратит NULL, если два значения совпадают, ISNULL будет выбрать первый ненулевое значение (или NULL, если оба значения равны нулю), так что если в результате из ISNULL is NULL означает, что два значения одинаковы (оба NULL или одинаковое значение).

0

Существует большое обсуждение этого вопроса на www.made2mentor.com. Он предлагает использовать EXCEPT, поскольку он обрабатывает NULL лучше, чем все альтернативы. Фрагмент:

WHEN MATCHED AND EXISTS 
    (SELECT Source.CustomerName, Source.Planet 
    EXCEPT 
    SELECT Target.CustomerName, Target.Planet) 

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

  • Нет связанных вопросов^_^