4

我有一个非常标准的关系数据情况,其中有一个带有子实体的根实体(和相应的表)。这些孩子有大约 6 个级别的孩子实体等等。每个级别都有许多孩子对一个父母的关系。我想编写一个有效地复制根实体及其所有子实体的过程(递归复制子实体的子实体),为每个实体创建新实体,同时将每个实体存储在其各自的表中。

我知道这可以通过嵌套游标来完成,但我不想那样做。我知道有一个更优雅的解决方案,我只需要帮助创建它。我有一种感觉,解决方案在于 OUTPUT 子句和 MERGE 语句的组合。

如果可以的话,请根据初级 SQL 开发人员级别调整您的答案。对于您使用的任何结构,在基本的 SELECT INSERT UPDATE 和 DELETE 之外,我需要解释或解释的链接。

感谢您的时间。

4

2 回答 2

0

您需要使用公用表表达式。检查这个:http: //blog.sqlauthority.com/2012/04/24/sql-server-introduction-to-hierarchical-query-using-a-recursive-cte-a-primer/

于 2013-09-20T06:23:17.967 回答
0

我假设您要复制表层次结构中的数据子集。我所说的层次结构是指通过外键在这个词的明显意义上相互关联的表。例如,Customers将是一个根表、Orders它的一个子表和OrderDetails另一个子表(在第 3 级)。

首先我们复制层次结构的根表:

MERGE RootTable as target
USING (
 SELECT *
 FROM RootTable
 WHERE SomeCondition
) AS src
ON 1=2 -- this is so that all rows that do not match will be added
WHEN NOT MATCHED THEN INSERT (AllColumns) VALUES (AllColumns)
OUTPUT src.ID as OldID, INSERTED.ID as NewID INTO #RootTableMapping

现在我们有一个 1 到 1 的复制源和复制目标 ID 的映射#RootTableMapping。此外,所有根行都被复制。

我们现在需要复制所有子表。这是一个声明:

MERGE ChildTable as target
USING (
 SELECT *, #RootTableMapping.NewID AS NewParentID
 FROM ChildTable
 JOIN #RootTableMapping ON ChildTable.RootID = #RootTableMapping.OldID
 WHERE SomeCondition
) AS src
WHEN NOT MATCHED THEN INSERT (AllColumns, RootID) VALUES (AllColumns, NewParentID)

在这里,我们为每个子行获取克隆的根表行的 ID,以便我们可以链接层次结构。为此,我们使用#RootTableMapping. NewID我们复制所有未修改的列,除了我们用映射替换的父 ID 之外。

每个子表都需要一个这样MERGE的语句。该概念还通过添加额外的连接扩展到具有超过 2 个级别的层次结构。除底层外的所有层级都必须记录copy-source ID到copy-target ID的映射,以允许下一层获取新的ID。

如果我没有把一切都说清楚,请随时提出进一步的问题。我知道这是一个粗略的草图。

于 2013-09-20T18:00:25.447 回答