Sql Server 2008 MERGE就像操作一样,但是在不同的表上运行

时间:2012-03-16 09:16:56

标签: sql-server sql-server-2008

我一直在SQL Server 2008中使用MERGE操作,但现在遇到了类似的情况,我需要相同的“检测”行为(WHEN MATCHEDWHEN NOT MATCHED BY SOURCEWHEN NOT MATCHED BY TARGET),但希望生成的操作位于不同的表上,而不是源或目标。

换句话说,我有两个结果集,beforeTableafterTable,我想做一些事情:

MERGE afterTable AS dest
USING beforeTable AS source 
ON (dest.ID = source.ID)
WHEN MATCHED THEN 
    --INSERT tblModifiedItems (ID) VALUES (ID)
WHEN NOT MATCHED BY TARGET THEN
    --INSERT tblRemovedItems (ID) VALUES (ID)
WHEN NOT MATCHED BY SOURCE THEN
    --INSERT tblAddedItems (ID) VALUES (ID)

目前我通过两个表中的三个单独(尽管非常简单)查询来执行此操作,但MERGE方法将允许它作为单个操作完成。我只是看不出它是否可以用于针对不同的表而不是比较中的两个。

这是可能的,如果是这样的话?

[编辑]

我想要这样做的原因不是由于INSERTS的原子性问题被添加/删除/修改(整个事情已经在事务中)。这是因为我希望能够在一个查询中生成三组数据,或者至少一个语句,这也使得意图非常清晰。

1 个答案:

答案 0 :(得分:2)

简短的回答是:不,你不能。 MERGE是源表和目标表之间的操作,就是这样。但是,我建议一个解决方法(总有一个)。你将不得不写更多的代码,但它会做到这一点。

这样做:

DECLARE @AuxTable table(    
    id int,
    OLD_name varchar(50),
    new_name varchar(50)
    )

merge table2 as dest
using table1 as src
on (dest.id=src.id)
when not matched by target then
  insert (id, name) values (src.id, src.name)
when matched then
  UPDATE SET dest.NAME=src.name
when not matched by SOURCE then
   DELETE

  output inserted.id, DELETED.name, INSERTED.NAME
  into @AuxTable
  ;

  select * from @AuxTable

请参阅"output into @AuxTable"?这将通过临时表上的合并插入所有修改后的值。您需要做的是运行此表并构建一个字符串以在另一个表上执行SQL。

使用此逻辑:

  • 当OLD_NAME = NULL时 - > INSERT
  • 当OLD_NAME!= NEW_NAME - >更新
  • WH_NAME NEW_NAME = NULL - > DELETE