我创建了一个存储过程,如下所示:
CREATE PROCEDURE [SPNAME]
@UserCode INT,
@ReportsTo INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @HierarchyId HIERARCHYID
DECLARE @NewParentHierarchyId HIERARCHYID
DECLARE @OldParentHierarchyId HIERARCHYID
SELECT @HierarchyId = [Hierarchy]
FROM [aspnet_Users]
WHERE [UserCode] = @UserCode
SELECT @OldParentHierarchyId = [Hierarchy].GetAncestor(1)
FROM [aspnet_Users]
WHERE [UserCode] = @UserCode
PRINT N'Old Root: ' + @OldParentHierarchyId.ToString()
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
SELECT @NewParentHierarchyId = [Hierarchy]
FROM [aspnet_Users]
WHERE [UserCode] = @ReportsTo
PRINT N'New Root: ' + @NewParentHierarchyId.ToString()
PRINT N'Old HierarchyId: ' + @HierarchyId.ToString()
SELECT @HierarchyId = @NewParentHierarchyId.GetDescendant(MAX([Hierarchy]), NULL)
FROM [aspnet_Users]
WHERE [Hierarchy].GetAncestor(1) = @NewParentHierarchyId
PRINT N'New HierarchyId: ' + @HierarchyId.ToString()
UPDATE [aspnet_Users]
SET [Hierarchy] = @HierarchyId.GetReparentedValue(@OldParentHierarchyId, @NewParentHierarchyId)
WHERE [Hierarchy].IsDescendantOf(@OldParentHierarchyId) = 1
COMMIT TRANSACTION
END
我按以下方式对数据进行了层次化:
imirza10 (UserCode 1)
-adil (UserCode 3)
--arif (UserCode 5)
---saqib (UserCode 6)
-farhan (UserCode 4)
上述存储过程是为了将arif从adil移动到farhan。
当我用语句执行sp时:
[aspnet_Users_ChangeHierarchy] 5, 4
它让我关注SSMS的消息选项卡:
Old Root: /1/1/
New Root: /1/2/
Old HierarchyId: /1/1/1/
New HierarchyId: /1/2/1/
Msg 6522,Level 16,State 2,Procedure aspnet_Users_ChangeHierarchy,Line 48
在执行用户定义的例程或聚合“hierarchyid”期间发生.NET Framework错误:
Microsoft.SqlServer.Types.HierarchyIdException:24009:SqlHierarchyId.GetReparentedValue失败,因为'oldRoot'不是'this'的祖先节点。 'oldRoot'是'/ 1/1 /','this'是'/ 1/2 / 1 /'。
Microsoft.SqlServer.Types.HierarchyIdException:
在Microsoft.SqlServer.Types.SqlHierarchyId.GetReparentedValue(SqlHierarchyId oldRoot,SqlHierarchyId newRoot)
需要帮助。
答案 0 :(得分:0)
在没有任何进一步测试的情况下,我在您的查询中看到以下问题:
@HierarchyId
从@OldParentHierarchyId
重新定位到@NewParentHierarchyId
因为@HierarchyId
不是@OldParentHierarchyId
的祖先(您有把它计算为新路径。)@HierarchyId.GetReparentedValue
来计算新位置而不是实际值。这将为所有行提供相同的结果。@OldParentHierarchyId
。UPDATE查询应如下所示:
UPDATE [aspnet_Users]
SET [Hierarchy] = [Hierarchy].GetReparentedValue(@OldParentHierarchyId, @NewParentHierarchyId)
WHERE [Hierarchy].IsDescendantOf(@OldParentHierarchyId) = 1 AND [Hierarchy] <> @OldParentHierarchyId
PS:我知道我在这个问题上迟到了,但无论如何它可能对某人有帮助。