【发布时间】:2013-02-20 14:57:39
【问题描述】:
我们的数据库中有一个使用 hierarchyid 数据类型的表,我正在尝试找到一种方法将父级和所有子级重新分配给新的父级。我找到了只移动孩子的方法,但父母没有被重新分配。我的桌子是这样的:
LocationOrg
[OrgNode] [hierarchyid] NOT NULL,
[OrgLevel] AS ([OrgNode].[GetLevel]()),
[LocationID] [int] NOT NULL,
[LocationName] [varchar](20) NOT NULL
还有一些数据:
LocationID | LocationName
__________ |_____________
1 | Headquaters
2 | Location1
3 | Location2
4 | Location3
5 | Location4
6 | Location5
7 | Location6
8 | Location7
现在已设置(手动),因此 Location1 和 Location4 是总部的子代,Location2 和 Location3 是 Location1 的子代,而 Location5、Location6 和 Location7 是 Location2 的子代:
--Headquaters
--Location1
--Location2
--Location3
--Location4
--Location5
--Location6
--Location7
如何编写可以重新分配父级和子级的内容?例如,如果我想移动 Location4 和 Location3 下的所有子项:
--Headquaters
--Location1
--Location2
--Location3
--Location4
--Location5
--Location6
--Location7
请注意 Location4 的所有子代如何成为 Location3 的子代...我不想移动整个父/子结构,我需要将它们重新分配给新的父代。
这是我到目前为止所得到的,但同样,它只移动孩子,而不是它的父母:
ALTER PROC [dbo].[ReorderLocationOrg]
@LocationID int,
@NewParentLocationID int
AS
BEGIN
DECLARE @OldParent hierarchyid,
@NewParent hierarchyid
SELECT @OldParent = OrgNode
FROM LocationOrg
WHERE LocationID = @LocationID;
SELECT @NewParent = OrgNode
FROM LocationOrg
WHERE LocationID = @NewParentLocationID;
DECLARE children_cursor CURSOR FOR
SELECT OrgNode
FROM LocationOrg
WHERE OrgNode.GetAncestor(1) = @OldParent;
DECLARE @ChildId hierarchyid;
OPEN children_cursor
FETCH NEXT FROM children_cursor INTO @ChildId;
WHILE @@FETCH_STATUS = 0
BEGIN
START:
DECLARE @NewId hierarchyid;
SELECT @NewId = @NewParent.GetDescendant(MAX(OrgNode), NULL)
FROM LocationOrg
WHERE OrgNode.GetAncestor(1) = @NewParent;
UPDATE LocationOrg
SET OrgNode = OrgNode.GetReparentedValue(@ChildId, @NewId)
WHERE OrgNode.IsDescendantOf(@ChildId) = 1;
IF @@error <> 0 GOTO START -- On error, retry
FETCH NEXT FROM children_cursor INTO @ChildId;
END
CLOSE children_cursor;
DEALLOCATE children_cursor;
--Move Parent to new node.
--UPDATE LocationOrg
--SET OrgNode = @OldParent.GetReparentedValue(@OldParent2, @NewParent)
--WHERE OrgNode = @OldParent
END
如您所见(注释掉的部分),我尝试将父级移动到光标之后,但它会引发错误,指出无法插入重复记录。
我在Moving Subtrees 上查看了此链接,但该过程在移动父子节点的同时保持其结构,因此在我的情况下,Location4 将移动到 Location3 下,但 Locations 5、6 和 7 仍然是Location4 的孩子,而不是 3...这是我不想要的。
感谢任何帮助!
【问题讨论】:
标签: sql-server sql-server-2008 hierarchical-data