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

mhn*_*mhn 5 sql sql-server merge sql-server-2008

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

捐助者表

projid      | datestamp    | Ownerid
-------------------------------------------------
c_abc        1-jan-2013      name1
c_def        2-jan-2013      name3
c_ghi        3-jan-2013      name4
Run Code Online (Sandbox Code Playgroud)

跟踪表

compid      |projid     |active | ... 
-----------------------------------------------
123           c_abc      1
124           c_xyz      1
125           c_def      1
Run Code Online (Sandbox Code Playgroud)

组件表

compid      |ownerid
-------------------------
123      name1
124      name2
125      name3
Run Code Online (Sandbox Code Playgroud)

合并后的输出表:

组件表

compid      |ownerid
-------------------------
123      name1
124      name2
125      name3
126      name4
Run Code Online (Sandbox Code Playgroud)

跟踪表

compid      |projid     |active | ... 
-----------------------------------------------
123          c_abc       1
124          c_xyz       0
125          c_def       1
126          c_ghi       1
Run Code Online (Sandbox Code Playgroud)

Nen*_*vic 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;
Run Code Online (Sandbox Code Playgroud)

SQLFiddle DEMO


*部分更新活动列:

WHEN NOT MATCHED BY SOURCE 
    THEN UPDATE SET t.active = 0
Run Code Online (Sandbox Code Playgroud)

应该能够适应上层查询为所有操作创建单个合并语句,但它会引发错误:

视图或函数't'不可更新,因为修改会影响多个基表

即使它显然是单列,并且常规的非合并更新工作正常.也许有人知道原因和/或解决方法.