删除行后更新层次结构
Update hierarchy after deletion of row
我有一个 table 包含 tree-like 数据(分层设计)。这是一个小样本:
+----+----------+-----------+-------+----------+---------+
| ID | ParentID | Hierarchy | Order | FullPath | Project |
+----+----------+-----------+-------+----------+---------+
| 1 | null | 1 | 1 | 1 | 1 |
| 2 | null | 2 | 2 | 2 | 1 |
| 3 | 1 | 1.1 | 1 | 1-3 | 1 |
| 4 | 1 | 1.2 | 2 | 1-4 | 1 |
| 5 | 4 | 1.2.1 | 1 | 1-4-5 | 1 |
| 6 | 2 | 2.1 | 1 | 2-6 | 1 |
| 7 | null | 3 | 1 | 1 | 2 |
+----+----------+-----------+-------+----------+---------+
Project
表示哪个项目拥有层次数据集
ParentID
是 parent 节点的 ID,它在 ID
上有一个外键。
Order
是元素在一个分支中的排名。例如,ID 1, 2 and 7
在同一个节点上,而 3 and 4
在另一个节点上。
FullPath
使用 ID 显示订单(出于系统使用和性能原因)。
Hierarchy
是显示给用户的列,它显示层次结构给UI。它会在每次插入、更新和删除后自动计算,这是我遇到的问题。
我在 table 中创建了一个删除元素的程序。它接收要删除的元素的 ID 作为输入并删除它,以及它的 children(如果有)。然后,它重新计算 FullPath
和 Order Column
。这有效。
当我尝试更新 Hierarchy
列时出现问题。我使用这个程序:
SELECT T.ID,
T.ParentID,
CASE WHEN T.ParentID IS NOT NULL THEN
CONCAT(T1.Hierarchy, '.', CAST(T.Order AS NVARCHAR(255)))
ELSE
CAST(T.Order AS NVARCHAR(255))
END AS Hierarchy
INTO #tmp
FROM t_HierarchyTable T
LEFT JOIN t_HierarchyTable T1
ON T1.ID = T.ParentID
WHERE Project = @Project --Variable to only update the current project for performance
ORDER BY T.FullPath
--Update the table with ID as key on tmp table
当我删除顺序低于其他项目且它们有 children 的项目时,这会失败。
例如,如果我删除项目 3,项目 4 Hierachy
将被更正 (1.1),但它的 child 不会(它将保持在 1.2.1,而它应该是 1.1.1 ).我添加了顺序以确保 parents 首先更新,但没有变化。
我的错误是什么,我真的不知道如何解决这个问题。
我设法用 CTE 更新了层次结构。由于我有订单,我可以根据已经更新的先前分支(父)将其附加到Hierarchy
。
;WITH CODES(ID, sCode, iLevel) AS
(
SELECT
T.[ID] AS [ID],
CONVERT(VARCHAR(8000), T.[Order]) AS [Hierarchy],
1 AS [iLevel]
FROM
[dbo].[data] AS T
WHERE
T.[ParentID] IS NULL
UNION ALL
SELECT
T.[ID] AS [ID],
P.[Hierarchy] + IIF(RIGHT(P.[Hierarchy], 1) <> '-', '-', '') + CONVERT(VARCHAR(8000), T.[Order]) AS [Hierarchy],
P.[iLevel] + 1 AS [iLevel]
FROM
[dbo].[data] AS T
INNER JOIN CODES AS P ON
P.[ID] = T.[ParentID]
WHERE
P.[iLevel] < 100
)
SELECT
[ID], [Hierarchy], [iLevel]
INTO
#CODES
FROM
CODES
我有一个 table 包含 tree-like 数据(分层设计)。这是一个小样本:
+----+----------+-----------+-------+----------+---------+
| ID | ParentID | Hierarchy | Order | FullPath | Project |
+----+----------+-----------+-------+----------+---------+
| 1 | null | 1 | 1 | 1 | 1 |
| 2 | null | 2 | 2 | 2 | 1 |
| 3 | 1 | 1.1 | 1 | 1-3 | 1 |
| 4 | 1 | 1.2 | 2 | 1-4 | 1 |
| 5 | 4 | 1.2.1 | 1 | 1-4-5 | 1 |
| 6 | 2 | 2.1 | 1 | 2-6 | 1 |
| 7 | null | 3 | 1 | 1 | 2 |
+----+----------+-----------+-------+----------+---------+
Project
表示哪个项目拥有层次数据集
ParentID
是 parent 节点的 ID,它在 ID
上有一个外键。
Order
是元素在一个分支中的排名。例如,ID 1, 2 and 7
在同一个节点上,而 3 and 4
在另一个节点上。
FullPath
使用 ID 显示订单(出于系统使用和性能原因)。
Hierarchy
是显示给用户的列,它显示层次结构给UI。它会在每次插入、更新和删除后自动计算,这是我遇到的问题。
我在 table 中创建了一个删除元素的程序。它接收要删除的元素的 ID 作为输入并删除它,以及它的 children(如果有)。然后,它重新计算 FullPath
和 Order Column
。这有效。
当我尝试更新 Hierarchy
列时出现问题。我使用这个程序:
SELECT T.ID,
T.ParentID,
CASE WHEN T.ParentID IS NOT NULL THEN
CONCAT(T1.Hierarchy, '.', CAST(T.Order AS NVARCHAR(255)))
ELSE
CAST(T.Order AS NVARCHAR(255))
END AS Hierarchy
INTO #tmp
FROM t_HierarchyTable T
LEFT JOIN t_HierarchyTable T1
ON T1.ID = T.ParentID
WHERE Project = @Project --Variable to only update the current project for performance
ORDER BY T.FullPath
--Update the table with ID as key on tmp table
当我删除顺序低于其他项目且它们有 children 的项目时,这会失败。
例如,如果我删除项目 3,项目 4 Hierachy
将被更正 (1.1),但它的 child 不会(它将保持在 1.2.1,而它应该是 1.1.1 ).我添加了顺序以确保 parents 首先更新,但没有变化。
我的错误是什么,我真的不知道如何解决这个问题。
我设法用 CTE 更新了层次结构。由于我有订单,我可以根据已经更新的先前分支(父)将其附加到Hierarchy
。
;WITH CODES(ID, sCode, iLevel) AS
(
SELECT
T.[ID] AS [ID],
CONVERT(VARCHAR(8000), T.[Order]) AS [Hierarchy],
1 AS [iLevel]
FROM
[dbo].[data] AS T
WHERE
T.[ParentID] IS NULL
UNION ALL
SELECT
T.[ID] AS [ID],
P.[Hierarchy] + IIF(RIGHT(P.[Hierarchy], 1) <> '-', '-', '') + CONVERT(VARCHAR(8000), T.[Order]) AS [Hierarchy],
P.[iLevel] + 1 AS [iLevel]
FROM
[dbo].[data] AS T
INNER JOIN CODES AS P ON
P.[ID] = T.[ParentID]
WHERE
P.[iLevel] < 100
)
SELECT
[ID], [Hierarchy], [iLevel]
INTO
#CODES
FROM
CODES