Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 MERGE для обновления  [new]
Fire83
Member

Откуда: Гомель-Минск
Сообщений: 474
Добрый день, коллеги!

Вопрос такой - для синхронизации таблиц в дата варехаузе (MS SQL 2008 R2 ) используем MERGE оператор, вида:

MERGE table1 as T
USING ( SELECT .. FROM S ) ON ( T.Key = S.Key)
      
WHEN MATCHED AND ( T.Field1 <> S.Field1 OR T.Field2 <> S.Field2 OR T.Field3 <> S.Field3...25 полей ) THEN 
  UPDATE 
   SET
       T.Field1 = S.Field1
      ,T.Field2 = S.Field2 
      ,T.Field3 = S.Field3
.. 
 25 полей
    
WHEN NOT MATCHED THEN 
  INSERT ...

Все работает, но если поля нуловые (суммы) то код получается следующий:

MERGE table1 as T
USING ( SELECT .. FROM S ) ON ( T.Key = S.Key)
      
WHEN MATCHED AND ( ( T.Field1 <> S.Field1 OR ( T.Field1 IS NOT NULL AND S.Field1 IS NULL) OR ( T.Field1 IS NULL AND S.Field1 IS NOT NULL)
                              OR  и т.д. 25 полей ) THEN 
  UPDATE 
   SET
       T.Field1 = S.Field1
      ,T.Field2 = S.Field2 
      ,T.Field3 = S.Field3
.. 
 25 полей
    
WHEN NOT MATCHED THEN 
  INSERT ...

Иными словами код приобретает ужасный вид.
Сначала думал для упрощения использовать SET ANSI_NULLS, но стремно т.к.
BOL
In a future version of SQL Server, ANSI_NULLS will always be ON and any applications that explicitly set the option to OFF will generate an error. Avoid using this feature in new development work, and plan to modify applications that currently use this feature.

Если ли красивое решение проблемы в текущей версии или только остается мирится таким кодом и ждать добавления
оператора IS NOT DISTINCT FROM ?
21 июн 11, 13:26    [10846319]     Ответить | Цитировать Сообщить модератору
 Re: MERGE для обновления  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
AND NOT EXISTS(SELECT T.Field1,T.Field2,...,T.Field25 INTERSECT SELECT S.Field1,S.Field2,...,S.Field25)
21 июн 11, 13:29    [10846373]     Ответить | Цитировать Сообщить модератору
 Re: MERGE для обновления  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Fire83,
SET ANSI_NULLS
влияет только на сравнение с литералом NULL и с переменной, равной NULL.
На сравнение полей между собой не влияет.
Да и в следующих версиях всегда будет иметь стандартное (по ANSI стандарту) неизменяемое значение.
21 июн 11, 13:32    [10846420]     Ответить | Цитировать Сообщить модератору
 Re: MERGE для обновления  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
iap
AND NOT EXISTS(SELECT T.Field1,T.Field2,...,T.Field25 INTERSECT SELECT S.Field1,S.Field2,...,S.Field25)
Для интереса можно попробовать и
AND EXISTS(SELECT T.Field1,T.Field2,...,T.Field25 EXCEPT SELECT S.Field1,S.Field2,...,S.Field25)
но здесь неоднократно отмечалось, что при INTERSECTе бывает, что сервер и индексы умеет использовать, если они есть.
Смотреть в плане надо.
21 июн 11, 13:34    [10846460]     Ответить | Цитировать Сообщить модератору
 Re: MERGE для обновления  [new]
Fire83
Member

Откуда: Гомель-Минск
Сообщений: 474
iap,

Спасибо, похоже что что нужно!
21 июн 11, 13:48    [10846607]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить