sql-server - 即使数据没有更新,MERGE 语句也会更新
问题描述
我有一个合并语句,我想在其中更新我的表行,以防任何列具有不同的值。但似乎即使源表中的大多数行都保持不变,该MERGE
语句执行 an UPDATE
on 至少计算它所做的一个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;
我在更新结束时(最后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
语句的条件。但我想知道它们是如何触发更新的。
解决方案
我想我发现了自己的错误,在我写的条件下:
OR TARGET.HasPhoneNumber = SOURCE.HasPhoneNumber
这几乎总是真实的!
推荐阅读
- django - django_celery_beat - “没有这样的表:main.django_celery_beat_solarschedule__old”同时更新“django_celery_beat_periodictask”
- c++ - 如何减少对大量纹理的绘图调用次数?
- python - 如何摆脱由 os.path.join 创建的转义字符?
- c# - 如何在招摇中排除请求有效负载中的属性
- python - 使用 shell scrapit 启动 pythonenvironment 并执行命令
- python - 为什么 BucketedRandomProjectionLSH 在 pyspark 中的 100 万张图像上花费这么多时间?
- c# - Selenium C# 选择 UL IL 和标签值
- javascript - 如何以 JSON 格式 PHP 返回 Javascript 变量?
- regex - 验证 Codeigniter 中的输入是否具有安全性和空格字母数字和特定字符
- android - 使用多窗口在部分屏幕中打开不同的应用程序