Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何在数据库中复制实体树_Sql_Sql Server_Tsql - Fatal编程技术网

Sql 如何在数据库中复制实体树

Sql 如何在数据库中复制实体树,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一个非常标准的关系数据场景,其中有一个根实体和对应的表以及子实体。这些子对象有子实体等等,大约有6个级别。每个级别都有多个子级到一个父级的关系。我想编写一个过程,有效地复制根实体及其所有子实体,递归地复制子实体的子实体,为每个实体创建新实体,同时将每个实体存储在各自的表中 我知道这可以通过嵌套游标来完成,但我不想这样做。我知道有一个更优雅的解决方案,我只是需要帮助创建它。我觉得解决方案在于输出子句和合并语句的组合 如果可以,请根据初学者SQL开发人员级别定制您的答案。我将需要一个解释或一个链

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

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

如果可以,请根据初学者SQL开发人员级别定制您的答案。我将需要一个解释或一个链接到任何结构的解释,你使用的是基本以外的选择插入更新和删除


谢谢您的时间。

您需要使用公共表表达式。选中此项:

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

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

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
现在我们在RootTableMapping中有了根表的复制源ID和复制目标ID的1对1映射。此外,还复制了所有根行

我们现在需要复制所有子表。以下是其中一项声明:

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。我们复制所有未修改的列,除了父项的ID,我们用映射中的NewID替换它

每个子表都需要一个这样的MERGE语句。通过添加附加联接,该概念还扩展到具有2个以上级别的层次结构。除底层之外的所有层都必须记录复制源ID到复制目标ID的映射,以允许下面的下一层获得新ID


如果我没有把每件事都说清楚的话,请随时提问。我知道这是一个粗略的草图。

这是什么SQL版本?另外,请注意,这是一个非常高级的任务,您正在尝试,它并不真的适合新手合并和输出非常好地解决了这个问题。您可能需要一个MERGE语句加上每个表一个temp表来进行复制,并按照从上到下的拓扑顺序执行。您是否可以一次手动键入所有语句,还是希望使用基于反射的方法在运行时构造SQL?我想知道@RBarryYoung在想什么。递归公共表表达式,有人吗?还是这还不足以解决问题?@Guttsy这在很大程度上取决于实际的细节。从描述中不清楚这是一个自引用表还是涉及其他表以及它们是如何涉及的。OP需要以表定义和/或关系图的形式提供其中一些信息。@usr:我完全可以手动键入每条语句一次,并且不需要基于反射的方法。谢谢您的回答。我通读了这篇文章,仍然很难拼凑出如何将其应用于我需要做的事情。如果您需要更多信息,请告诉我。我经常使用CTE,我有一个表,它是一个正确的树,没有循环,有列:ID,parentID,otherInfo1,otherInfo2,。。。在这种结构中,编写这样的查询很容易:例如,上面的GetAllCildrensOfXRecursiveX GetAllAncestorsOfXRecursiveX函数运行到退出条件没有子函数为止。让我知道您的表的列,您到底需要查询什么,以及您的表是否有循环。