階層的な手法を使用した階層テーブルのデータの並べ替え
階層の再編成は、一般的なメンテナンス タスクです。ここでは、UPDATE ステートメントを GetReparentedValue メソッドと共に使用して、まず 1 つの行を階層内の新しい位置に移動します。次に、サブツリー全体を新しい場所に移動します。
GetReparentedValue メソッドは 2 つの引数を受け取ります。最初の引数は、変更する階層の一部を表します。たとえば、階層が /1/4/2/3/ の場合に、最後の 2 つのノード (2/3/) はそのままで、/1/4/ セクションを変更して階層を /2/1/2/3/ にするときは、変更するノード (/1/4/) を最初の引数として指定する必要があります。2 番目の引数には、新しい階層レベルを指定します。この例では、/2/1/ です。2 つの引数には、異なるレベル数を指定することもできます。
1 つの行を階層内の新しい位置に移動するには
現在、Wanida は Sariya に直属しています。この手順では、Wanida を現在のノード /1/1/ から移動して、Jill に直属するようにします。Wanida の新しいノードは /3/1/ になるので、最初の引数は /1/、2 番目の引数は /3/ になります。これらは、Sariya と Jill の OrgNode 値に相当します。Wanida を Sariya の組織から Jill の組織に移動するには、次のコードを実行します。
DECLARE @CurrentEmployee hierarchyid , @OldParent hierarchyid, @NewParent hierarchyid SELECT @CurrentEmployee = OrgNode FROM HumanResources.EmployeeOrg WHERE EmployeeID = 269 ; SELECT @OldParent = OrgNode FROM HumanResources.EmployeeOrg WHERE EmployeeID = 46 ; SELECT @NewParent = OrgNode FROM HumanResources.EmployeeOrg WHERE EmployeeID = 119 ; UPDATE HumanResources.EmployeeOrg SET OrgNode = @CurrentEmployee. GetReparentedValue(@OldParent, @NewParent) WHERE OrgNode = @CurrentEmployee ; GO
結果を表示するには、次のコードを実行します。
SELECT OrgNode.ToString() AS Text_OrgNode, OrgNode, OrgLevel, EmployeeID, EmpName, Title FROM HumanResources.EmployeeOrg ; GO
Wanida がノード /3/1/ に移動しています。
階層のセクションを再編成するには
多数の人員を一度に移動する方法を示すため、まず次のコードを実行して Wanida に直属するインターンを追加します。
EXEC AddEmp 269, 291, 'Kevin', 'Marketing Intern' ; GO
Kevin が Wanida に直属するようになりました。Wanida は Jill に直属し、Jill は David に直属します。したがって、Kevin のレベルは、/3/1/1/ です。Jill の部下をすべて新しい管理者に移動するには、OrgNode として /3/ を持つすべてのノードを新しい値に更新します。Kevin を Wanida に直属させたまま、Wanida を Sariya に直属するように更新するには、次のコードを実行します。
DECLARE @OldParent hierarchyid, @NewParent hierarchyid SELECT @OldParent = OrgNode FROM HumanResources.EmployeeOrg WHERE EmployeeID = 119 ; -- Jill SELECT @NewParent = OrgNode FROM HumanResources.EmployeeOrg WHERE EmployeeID = 46 ; -- Sariya DECLARE children_cursor CURSOR FOR SELECT OrgNode FROM HumanResources.EmployeeOrg 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 HumanResources.EmployeeOrg WHERE OrgNode.GetAncestor(1) = @NewParent; UPDATE HumanResources.EmployeeOrg 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;
結果を表示するには、次のコードを実行します。
SELECT OrgNode.ToString() AS Text_OrgNode, OrgNode, OrgLevel, EmployeeID, EmpName, Title FROM HumanResources.EmployeeOrg ; GO
以下に結果セットを示します。
Text_OrgNode OrgNode OrgLevel EmployeeID EmpName Title
------------ ------- -------- ---------- ------- -----------------
/ Ox 0 6 David Marketing Manager
/1/ 0x58 1 46 Sariya Marketing Specialist
/1/1/ 0x5AC0 2 269 Wanida Marketing Assistant
/1/1//2 0x5AD0 3 291 Kevin Marketing Intern
/2/ 0x68 1 271 John Marketing Specialist
/2/1/ 0x6AC0 2 272 Mary Marketing Assistant
/3/ 0x78 1 119 Jill Marketing Specialist
Jill に直属していた組織のツリー全体 (Wanida と Kevin の両方) が Sariya に直属するようになりました。
階層のセクションを再編成するストアド プロシージャについては、「hierarchyid データの操作」の「サブツリーの移動」を参照してください。