问题
I have a table that contains a set of values and a hierarchyid column. Looks something like this:
+-----+-------------+-----------+
| ID | HierarchyID | Name | HierarchyID.ToString() for clarity
+-----+-------------+-----------+
| 1 | 0x58 | Testing | /1/
| 2 | 0x5AC0 | TChild1 | /1/1
| 3 | 0x5AD6 | TChild1.1 | /1/1/1
| 4 | 0x5ADA | TChild1.2 | /1/1/2/
| 5 | 0x68 | Example | /2/
| 6 | 0x6AC0 | EChild1 | /2/1
| ... | ... | ... |
+-----+-------------+-----------+
However, we are introducing a new data set of that aligns side by side with the current tree and I'll need to shift all the values in my current tree down a level so it should look something like this now.
+-----+-------------+-----------+
| ID | HierarchyID | Name | HierarchyID.ToString() for clarity
+-----+-------------+-----------+
| | 0x58 | OldData | /1/
| 1 | 0x5AC0 | Testing | /1/1/
| 2 | 0x5AC6 | TChild1 | /1/1/1
| 3 | 0x5AD6B0 | TChild1.1 | /1/1/1/1
| 4 | 0x5AD6D0 | TChild1.2 | /1/1/1/2/
| 5 | 0x5B40 | Example | /1/2/
| 6 | 0x5B56 | EChild1 | /1/2/1
| 6 | 0x68 | NewData | /2
| 6 | 0x6AC0 | NChild1 | /2/1
| ... | ... | ... |
+-----+-------------+-----------+
Is there an easy way to update all of my hierarchyid values to shift them down a level or do I have to update each row one by one without overlapping values on updates?
回答1:
Just from looking up the documentation. There is an easy way to move a subtree.
Working with hierarchyid Data
Under Moving Subtree there is an example for an Employee hierarchy. You will have to adjust to your table structure.
CREATE PROCEDURE MoveOrg(@oldMgr nvarchar(256), @newMgr nvarchar(256) )
AS
BEGIN
DECLARE @nold hierarchyid, @nnew hierarchyid
SELECT @nold = OrgNode FROM HumanResources.EmployeeDemo WHERE LoginID = @oldMgr ;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
SELECT @nnew = OrgNode FROM HumanResources.EmployeeDemo WHERE LoginID = @newMgr ;
SELECT @nnew = @nnew.GetDescendant(max(OrgNode), NULL)
FROM HumanResources.EmployeeDemo WHERE OrgNode.GetAncestor(1)=@nnew ;
UPDATE HumanResources.EmployeeDemo
SET OrgNode = OrgNode.GetReparentedValue(@nold, @nnew)
WHERE OrgNode.IsDescendantOf(@nold) = 1 ;
COMMIT TRANSACTION
END ;
GO
来源:https://stackoverflow.com/questions/37051975/shifting-hierarchyid-set