看这个溶液(解释可以波纹管找到):
DECLARE @Source TABLE
(
ID HIERARCHYID PRIMARY KEY
,Name NVARCHAR(50) NOT NULL
);
DECLARE @Target TABLE
(
ID HIERARCHYID PRIMARY KEY
,Name NVARCHAR(50) NOT NULL
,OldID HIERARCHYID
);
INSERT @Source
VALUES
('/1/','a'), ('/1/1/','aa'), ('/1/2/','ab'), ('/1/3/','ac')
,('/2/','b')
,('/3/','c'), ('/3/3/','cc')
,('/4/','d'), ('/4/1/','da'), ('/4/2/','db'), ('/4/2/1/','dba'), ('/4/2/1/5/','dbaf');
DECLARE @LastTargetRootNodeAsInteger INT;
SELECT @LastTargetRootNodeAsInteger = REPLACE(MAX(a.ID.GetAncestor(a.ID.GetLevel()-1)).ToString(), '/', '')
FROM @Target a;
WITH CteUpdate
AS
(
SELECT a.ID
,a.Name
,a.ID.GetAncestor(a.ID.GetLevel()-1) AS OldRootID
,CONVERT(HIERARCHYID,'/'+CONVERT(VARCHAR(256),@LastTargetRootNodeAsInteger+DENSE_RANK()OVER(ORDER BY a.ID.GetAncestor(a.ID.GetLevel()-1)))+'/') NewRootID
FROM @Source a
)
INSERT @Target(ID, Name, OldID)
SELECT a.ID.GetReparentedValue(a.OldRootID, a.NewRootID), a.Name, a.ID
FROM CteUpdate a;
SELECT *
,t.ID.ToString() AS CurrentNodeToString
,t.OldID.ToString() AS OldNodeToString
FROM @Target t
ORDER BY t.ID;
说明:
- 假设找到从目标表中最后一个根节点(
@LastTargetRootNodeAsInteger
)第一步。
- 然后,对于来自源表的每个ID,我们得到根节点(旧根节点:
a.ID.GetAncestor(a.ID.GetLevel()-1)
)。
- 对于每个旧的根节点,我们得到新的根节点(
'/'[email protected]+DENSE_RANK()OVER(ORDER BY old_root_node)+'/'
)。
- 最后,我们将插入具有新根节点的行(
a.ID.GetReparentedValue(old_root,new_root)
)。
,看看我们如何获得新的ID,您可以执行这个查询:
SELECT *
,c.ID.GetReparentedValue(c.OldRootNode,c.NewRootNode).ToString() AS NewCurrentNode
FROM
(
SELECT *
,'/'+CONVERT(VARCHAR(256),@LastTargetRootNodeAsInteger+DENSE_RANK() OVER(ORDER BY b.OldRootNode))+'/' AS NewRootNode
FROM
(
SELECT *
,a.ID.ToString() AS OldCurrentNode
,a.ID.GetAncestor(a.ID.GetLevel()-1).ToString() AS OldRootNode
FROM @Source a
) b
) c
结果:
当您从源表传输数据到目标表(1 ),那么你总是转移第一级别,或者(2)有些情况下,只导入次级别(例如,你开始从第二级导入数据=>你导入/ 101/1 /不导入/ 101/)?因此,/ 101 /和/ 101/1 /,/ 101/2 /,....../101/5 /,/ 101/2/1 /(第一种情况)或/ 101/2 /,/ 101/2/1 /? –