我将此格式用于MERGE子句:
DECLARE @Table (ColA int, ColB int, ID int)
INSERT @Table
SELECT changes.ColA,changes.ColB,Changes.Identity
FROM
(
MERGE Target
USING @SourceTable SOURCE
ON Target.ID=Source.ID
WHEN MATCHED AND target.ColA<>soruce.ColA or target.ColB<>source.ColB THEN
UPDATE SET
Target.ColA=source.ColA,
Target.ColB=source.ColB
WHEN NOT MATCHED BY TARGET
INSERT(ColA,ColB)
VALUES(Source.ColA,Source.ColB)
WHEN NOT MATCHED BY SOURCE THEN
DELETE
OUTPUT INSERTED.ColA,INSERTED.ColB,SOURCE.Identity
) AS changes(ColA,ColB,SOURCE.Identity)
然后我使用@Table
作为其他JOINS的来源。如果TARGET表没有插入/更新,那么@Table
为空,这导致整个查询的剩余部分出现问题,因为没有任何内容可以加入。
有没有办法捕获SOURCE
行,即使它们未被TARGET
方操纵?
我需要使用MERGE在INSERT / UPDATES上检索Identity列。
答案 0 :(得分:0)
最好将IF @@ROWCOUNT > 0
条件添加到脚本的其余部分,并在没有更新记录时跳过它。
如果无论Target
表格中的更新内容,@SourceTable
中的所有记录都需要进一步处理,最好只使用@SourceTable
代替OUTPUT
条款。 MERGE
语句中的OUTPUT
语句中的数据不是Target
的{{1}}。
如果您想将@SourceTable
中的记录过滤到OUTPUT
子句,即使不需要更新Target
表,您也可以对记录执行“虚拟更新”没有值会实际改变:
DECLARE @Table (ColA int, ColB int, ID int)
INSERT @Table
SELECT changes.ColA,changes.ColB,Changes.Identity
FROM (MERGE Target
USING (SELECT * FROM @SourceTable ) SOURCE
ON Target.ID=Source.ID
WHEN MATCHED /* AND target.ColA<>soruce.ColA or target.ColB<>source.ColB */
/* Remove condition and update even when no value would actually change */
THEN UPDATE SET Target.ColA=source.ColA,Target.ColB=source.ColB
WHEN NOT MATCHED BY TARGET INSERT(ColA,ColB) VALUES(Source.ColA,Source.ColB)
WHEN NOT MATCHED BY SOURCE THEN DELETE
OUTPUT INSERTED.ColA,INSERTED.ColB,SOURCE.Identity) AS changes(ColA,ColB,SOURCE.Identity)
答案 1 :(得分:0)
您可以通过捕获合并语句的OUTPUT
来捕获未修改的源记录。您需要引入虚拟更新:
DECLARE @dummy INT = 0;
MERGE ...
WHEN MATCHED THEN
UPDATE @dummy = @dummy
...
OUTPUT INSERTED.ColA,INSERTED.ColB,SOURCE.Identity