使用階層式方法重新排列階層式資料表中的資料順序
重新組織階層是常見的維護工作。在這項工作中,我們將會使用 UPDATE 陳述式搭配 GetReparentedValue 方法,先將單一資料列移到階層中的新位置。然後,我們會將整個子樹移到新位置。
GetReparentedValue 方法會使用兩個引數。第一個引數描述要修改的階層部分。例如,如果階層為 /1/4/2/3/ 而您想要變更 /1/4/ 區段,讓該階層變成 /2/1/2/3/,留下最後兩個節點 (2/3/) 不變,您必須提供變更的節點 (/1/4/) 做為第一個引數。第二個引數會提供新的階層層級,在範例中為 /2/1/。兩個引數不必包含相同的層級數目。
將單一資料列移到階層中的新位置
目前 Wanida 回報給 Sariya。在此程序中,您會從目前的節點 /1/1/ 移動 Wanida,因此她會回報給 Jill。她的新節點將會變成 /3/1/,因此 /1/ 是第一個引數,而 /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 的所有部屬移到新的主管之下,我們會將 /3/ 當做其 OrgNode 的所有節點更新為新值。執行下列程式碼,將 Wanida 更新為回報給 Sariya,但是讓 Kevin 回報給 Wanida:
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 資料>的<移動子樹>一節。