DB に 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 が Headquarters の子で、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
ご覧のとおり (コメントアウトされたセクション)、カーソルの後に親を移動しようとしましたが、重複レコードを挿入できないというエラーがスローされます。
サブツリーの移動に関するこのリンクを見てきましたが、その手順は親と子を構造を維持したまま移動するため、私の場合、Location4 は Location3 の下に移動されますが、Locations 5、6、および 7 は Location4 の子のままです。 3ではありません...これは私が望んでいないことです。
どんな助けでも大歓迎です!