将数据合并到两个目标表中

时间:2013-08-09 08:10:40

标签: sql sql-server sql-server-2008 merge

我需要将来自捐赠者表的数据合并到两个目标表中。结构如下。如果在跟踪表中找不到projid,我需要在组件表中创建新组件并使用新id插入到跟踪表中。此外,对于捐赠者表中不再存在的那些项,跟踪表“活动”列应标记为0.我可以在单个合并语句中实现此目的吗?

捐助者表

projid      | datestamp    | Ownerid
-------------------------------------------------
c_abc        1-jan-2013      name1
c_def        2-jan-2013      name3
c_ghi        3-jan-2013      name4

跟踪表

compid      |projid     |active | ... 
-----------------------------------------------
123           c_abc      1
124           c_xyz      1
125           c_def      1

组件表

compid      |ownerid
-------------------------
123      name1
124      name2
125      name3

合并后的输出表:

组件表

compid      |ownerid
-------------------------
123      name1
124      name2
125      name3
126      name4

跟踪表

compid      |projid     |active | ... 
-----------------------------------------------
123          c_abc       1
124          c_xyz       0
125          c_def       1
126          c_ghi       1

1 个答案:

答案 0 :(得分:5)

理论上,应该有一个解决方案,在单一声明中这样做,但我到目前为止未能找到它。 *

以下是两个MERGE语句的完成方式:

WITH CTE_trgt AS 
(
    SELECT c.compid, c.ownerid, t.projid, t.active 
    FROM component c
    INNER JOIN trace t ON c.compid = t.compid
)
MERGE CTE_trgt t
USING Donor s
ON t.projid = s.projid
WHEN NOT MATCHED BY TARGET
    THEN INSERT (ownerid)
    VALUES (s.ownerid)
OUTPUT
    INSERTED.compid, s.projid, 1 INTO trace;


MERGE trace t
USING Donor s
ON t.projid = s.projid
WHEN NOT MATCHED BY SOURCE 
    THEN UPDATE SET t.active = 0;

<强> SQLFiddle DEMO


* 部分更新活动列:

WHEN NOT MATCHED BY SOURCE 
    THEN UPDATE SET t.active = 0

应该能够适应上层查询为所有操作创建single merge statement,但它会引发错误:

  

查看或功能&#39; t&#39;不可更新,因为修改会影响多个基表

即使它显然是单列,也是regular non-merge update works fine。也许有人知道原因和/或解决方法。