与许多开发人员一样,我使用数据执行大量合并操作,特别是SQL Server。
从历史上看,我使用了旧的技巧: -
1)对现有数据进行左连接,并插入任何我没有相应记录的内容。
2)1)之后,更新目标表中的行。
我必须在1)上取得成绩。这是不可避免的。然而,在2),我一直相当挥霍。我没有更新需要更新的内容,而是更新了我匹配的所有内容(基础数据是否已更改)。
事实证明,SQL Server对这种更新并不太聪明。它不执行预先检查以确定您要更新的内容与更新它的内容不同。因此,沿着这些行进行的更新会导致物理写入并影响引用该字段的任何索引。
所以,从我的POV来看,我的选择如下: -
1)正常进行,沉浸在我的日常工作的当前挥霍中(并且每天在大型数据库上刷新索引)
2)如果字段已更改,请编写更多更新特定字段的UPDATE语句。
e.g。
UPDATE
p2
SET
[SpecificField] = p1.[SpecificField]
FROM
@source p1,
Dest p2
WHERE
p2.ExternalKey = p1.ExternalKey
AND COALESCE(p1.[SpecificField],'') <> COALESCE(p2.[SpecificField],'')
3)Stack Overflow社区建议的东西无限好。
我真的很想去3)。我的选择真的限于1或2吗?注意。我已经研究过MERGE INTO。同样的问题,真的。
答案 0 :(得分:2)
使用MERGE INTO
,您可以选择向WHEN (NOT) MATCHED
子句添加其他搜索子句。例如,
MERGE INTO table_to_upsert AS target
USING source_table AS source
ON target.key1 = source.key1
AND target.key2 = source.key2
AND target.key3 = source.key3
WHEN MATCHED AND (target.value <> source.value) THEN
UPDATE SET target.value = source.value,
target.timestamp = source.timestamp
WHEN MATCHED AND (target.userid <> source.userid) THEN
UPDATE SET target.userid = source.userid,
target.timestamp = source.timestamp
WHEN NOT MATCHED THEN
INSERT (key1, key2, key3,
value, userid, timestamp)
VALUES (source.key1, source.key2, source.key3,
source.value, source.userid, source.timestamp)
但是,如果一次更新多个列,这并不能真正解决您的问题,MERGE
将采用评估为true的第一个WHEN (NOT) MATCHED
(类似于CASE
语句)。