与OUTPUT合并似乎没有做对的事情


8

我正在向表添加外键,并删除任何违反FK的行,然后将它们复制到ModifiedTable_invalid表中。作为脚本的一部分,我具有以下MERGE命令:

MERGE ModifiedTable t1
USING TargetTable tt
ON t1.JoinColumn = tt.JoinColumn
WHEN MATCHED THEN
    UPDATE SET t1.FkColumn = tt.FkSource
WHEN NOT MATCHED BY SOURCE THEN DELETE
OUTPUT DELETED.* INTO ModifiedTable_invalid;

但是,此命令似乎是将ModifiedTable中的每一行插入到ModifiedTable_invalid中,而不仅仅是由MERGE命令删除的行。这是怎么回事,以及如何将其删除的行仅放入ModifiedTable_invalid中?

Answers:


11

当您更新一行时,它将同时出现在inserted(更新后的值)和deleted(更新前的值)伪表中。如果这看起来很奇怪,请认为更新在逻辑上是删除操作,然后是插入操作(尽管实际上可能不会以这种方式执行更新)。

与一起使用时MERGE,该OUTPUT子句可以包含一个名为的额外列$action。添加该列,您的查询将显示被带到哪个动作('INSERT''UPDATE',或'DELETE')的每一行。

例如:

insert into ModifiedTable_invalid(Id /* And other columns */)
select
    Id
    /* And other columns */
from
(
    merge ModifiedTable t1
    using TargetTable t2 on t1.JoinColumn = t2.JoinColumn
    when matched then update set t1.FkColumn = t2.FkSource
    when not matched by source then delete
    output 
        $action as DMLAction,
        deleted.Id as Id /* And other columns... */
) outputs
where
    DMLAction = 'DELETE';

更新的行将具有$action= 'UPDATE'

另请参见Adam Machanic的关于将OUTPUT与MERGE语句一起使用的文章,还有其他一些不错的示例。


这种行为对我来说毫无意义。为什么未删除的行会出现在DELETED.*
thecoop 2012年

3
@thecoop-它允许您访问更新之前和之后的值。从概念上讲,您可能会认为更新是删除,然后是插入,即使实际上并非如此。
马丁·史密斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.