8

我需要将供体表中的数据合并到两个目标表中。结构如下。如果在跟踪表中找不到 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
4

1 回答 1

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 演示


* 更新活动列的部分:

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

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

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

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

于 2013-08-09T09:26:43.127 回答