0

我创建了一个存储过程,如下所示:

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/

消息 6522,级别 16,状态 2,过程 aspnet_Users_ChangeHierarchy,第 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)

在这方面需要帮助。

4

1 回答 1

0

没有任何进一步的测试,我在您的查询中看到以下问题:

  1. 错误消息告诉您的是,您无法@HierarchyId@OldParentHierarchyIdto复制,@NewParentHierarchyId因为@HierarchyId它不是@OldParentHierarchyId(您已将其计算为新路径)的祖先。
  2. 您用于@HierarchyId.GetReparentedValue计算新位置而不是实际值。这将为所有行提供相同的结果。
  3. 您需要@OldParentHierarchyId从更新中排除。

UPDATE 查询应如下所示:

UPDATE [aspnet_Users]
SET    [Hierarchy] = [Hierarchy].GetReparentedValue(@OldParentHierarchyId, @NewParentHierarchyId)
WHERE  [Hierarchy].IsDescendantOf(@OldParentHierarchyId) = 1 AND [Hierarchy] <> @OldParentHierarchyId

PS:我知道我在这个问题上迟到了,但无论如何它可能会对某人有所帮助。

于 2015-06-08T17:42:28.013 回答