Оператор MERGE обновляется, даже если данные не обновляются - PullRequest
0 голосов
/ 06 марта 2019

У меня есть оператор слияния, в котором я хотел бы обновить строки моей таблицы в случае, если какой-либо из столбцов имеет другое значение.Но похоже, что хотя большинство строк в исходной таблице остались нетронутыми, оператор MERGE выполняет UPDATE, по крайней мере, подсчитывает, что он делает UPDATE.

DECLARE @SummaryOfChanges TABLE(Change VARCHAR(50));

MERGE MyTarget AS TARGET
USING MySource AS SOURCE
ON (SOURCE.customeridHash = TARGET.Id)
WHEN MATCHED AND (TARGET.IsCompany <> SOURCE.company
    OR TARGET.Gender <> SOURCE.gender
    OR TARGET.BirthDate <> CONVERT(DATE, SOURCE.dateofbirth)
    OR TARGET.ZipCode <> SOURCE.ZipCode
    OR TARGET.City <> SOURCE.City
    OR TARGET.WantsEmail <> (CASE WHEN SOURCE.noemail = 0 THEN 1 ELSE 0 END)
    OR TARGET.WantsSMS <> (CASE WHEN SOURCE.nosms = 0 THEN 1 ELSE 0 END)
    OR TARGET.WantsDM <> (CASE WHEN SOURCE.nodirectmarketing = 0 THEN 1 ELSE 0 END)
    OR TARGET.WantsTM <> (CASE WHEN SOURCE.notelemarketing = 0 THEN 1 ELSE 0 END)
    OR TARGET.HasEmail <> SOURCE.HasEmail
    OR TARGET.HasMobilePhoneNumber <> SOURCE.HasMobilePhoneNumber
    OR TARGET.HasPhoneNumber = SOURCE.HasPhoneNumber
    OR TARGET.Created <> SOURCE.Created
    OR TARGET.Updated <> SOURCE.changed)
THEN
UPDATE SET TARGET.IsCompany = SOURCE.company,
    TARGET.Gender = SOURCE.gender,
    TARGET.BirthDate = CONVERT(DATE, SOURCE.dateofbirth),
    TARGET.ZipCode = SOURCE.ZipCode,
    TARGET.City = SOURCE.City,
    TARGET.WantsEmail = (CASE WHEN SOURCE.noemail = 0 THEN 1 ELSE 0 END),
    TARGET.WantsSMS = (CASE WHEN SOURCE.nosms = 0 THEN 1 ELSE 0 END),
    TARGET.WantsDM = (CASE WHEN SOURCE.nodirectmarketing = 0 THEN 1 ELSE 0 END),
    TARGET.WantsTM = (CASE WHEN SOURCE.notelemarketing = 0 THEN 1 ELSE 0 END),
    TARGET.HasEmail = SOURCE.HasEmail,
    TARGET.HasMobilePhoneNumber = SOURCE.HasMobilePhoneNumber,
    TARGET.HasPhoneNumber = SOURCE.HasPhoneNumber,
    TARGET.Created = SOURCE.Created,
    TARGET.Updated = SOURCE.changed
WHEN NOT MATCHED BY TARGET THEN
INSERT (
    Id, 
    IsCompany, 
    Gender, 
    BirthDate, 
    ZipCode, 
    City, 
    WantsEmail, 
    WantsSMS,
    WantsDM, 
    WantsTM, 
    HasEmail, 
    HasMobilePhoneNumber, 
    HasPhoneNumber, 
    Created, 
    Updated
)
VALUES (
    SOURCE.customeridHash,
    SOURCE.company,
    SOURCE.gender,
    CONVERT(DATE, SOURCE.dateofbirth),
    SOURCE.ZipCode,
    SOURCE.City,
    (CASE WHEN SOURCE.noemail = 0 THEN 1 ELSE 0 END),
    (CASE WHEN SOURCE.nosms = 0 THEN 1 ELSE 0 END),
    (CASE WHEN SOURCE.nodirectmarketing = 0 THEN 1 ELSE 0 END),
    (CASE WHEN SOURCE.notelemarketing = 0 THEN 1 ELSE 0 END),
    SOURCE.HasEmail,
    SOURCE.HasMobilePhoneNumber,
    SOURCE.HasPhoneNumber,
    SOURCE.Created,
    SOURCE.changed
)
WHEN NOT MATCHED BY SOURCE THEN DELETE
OUTPUT $action INTO @SummaryOfChanges;

SELECT Change, COUNT(*) CountPerChange
FROM @SummaryOfChanges
GROUP BY Change;

Iсделайте некоторую бухгалтерию в конце обновления (финальная SELECT), и кажется, что почти все строки, которые не являются новыми, были обновлены.Это обычное поведение или в моем <> сравнении для WHEN MATCHED AND... есть какое-то значение, которое обновляется?

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

-- TEST MERGE
select count(*) 
from MyTarget TARGET join MySource SOURCE on TARGET.Id=SOURCE.customeridHash
where TARGET.IsCompany <> SOURCE.company
    OR TARGET.Gender <> SOURCE.gender
    OR TARGET.BirthDate <> CONVERT(DATE, SOURCE.dateofbirth)
    OR TARGET.ZipCode <> SOURCE.ZipCode
    OR TARGET.City <> SOURCE.City
    OR TARGET.WantsEmail <> (CASE WHEN SOURCE.noemail = 0 THEN 1 ELSE 0 END)
    OR TARGET.WantsSMS <> (CASE WHEN SOURCE.nosms = 0 THEN 1 ELSE 0 END)
    OR TARGET.WantsDM <> (CASE WHEN SOURCE.nodirectmarketing = 0 THEN 1 ELSE 0 END)
    OR TARGET.WantsTM <> (CASE WHEN SOURCE.notelemarketing = 0 THEN 1 ELSE 0 END)
    OR TARGET.HasEmail <> SOURCE.HasEmail
    OR TARGET.HasMobilePhoneNumber <> SOURCE.HasMobilePhoneNumber
    OR TARGET.HasPhoneNumber = SOURCE.HasPhoneNumber
    OR TARGET.Created <> SOURCE.Created
    OR TARGET.Updated <> SOURCE.changed;

Я понял, что этот запрос возвращает такое же количество обновлений.Так что это как-то больше о том условии, что оператор MERGE.Но мне интересно, как они вызывают обновления.

1 Ответ

0 голосов
/ 06 марта 2019

Я думаю, что нашел свою ошибку, в условиях, которые я пишу:

OR TARGET.HasPhoneNumber = SOURCE.HasPhoneNumber

Что почти всегда становится правдой!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...