删除行后更新层次结构

问题描述 投票:0回答:2

我有一个包含树状数据的表(分层设计)。这是一个小样本:

+----+----------+-----------+-------+----------+---------+
| 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
是父节点的ID,它在
ID
上有一个外键。
Order
是一个分支中元素的秩。例如,ID
1, 2 and 7
位于同一节点,而
3 and 4
位于另一个节点。
FullPath
使用 ID 显示订单(出于系统使用和性能原因)。

Hierarchy
是向用户显示的列,它向UI显示层次结构。它会在每次插入、更新和删除后自动计算,这就是我遇到的问题。

我创建了一个删除表中元素的过程。它接收要删除的元素的 ID 作为输入,并删除它及其子元素(如果有)。然后,它重新计算

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

当我删除顺序比其他项目低且有子项的项目时,此操作会失败。 例如,如果我删除项目 3,项目 4

Hierachy
将被更正 (1.1),但其子项目不会(它将保持在 1.2.1,而它应该是 1.1.1)。我添加了订单以确保父母首先更新,但没有改变。

我的错误是什么,我真的不知道如何解决这个问题。

sql-server stored-procedures hierarchy hierarchical-data
2个回答
0
投票

我设法使用 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

0
投票

有同样的问题

CREATE PROCEDURE DeleteDossierAndUpdateHierarchy
@SectionCode nvarchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

-- Start a new transaction
BEGIN TRANSACTION;

-- Update the SectionCode and OrderNumber of the remaining dossiers
WITH DossiersCTE AS (
    SELECT 
        ID, 
        ParentId, 
        OrderNumber, 
        CAST(OrderNumber AS nvarchar(50)) AS NewSectionCode
    FROM 
        Dossiers
    WHERE 
        ParentId IS NULL

    UNION ALL

    SELECT 
        d.ID, 
        d.ParentId, 
        d.OrderNumber, 
        CAST(c.NewSectionCode + '.' + CAST(d.OrderNumber AS nvarchar(50)) AS nvarchar(50)) AS NewSectionCode
    FROM 
        Dossiers d
    JOIN 
        DossiersCTE c ON d.ParentId = c.ID
)
UPDATE Dossiers
SET SectionCode = c.NewSectionCode,
    OrderNumber = c.OrderNumber
FROM Dossiers d
JOIN DossiersCTE c ON d.ID = c.ID
WHERE d.SectionCode >= @SectionCode;

-- Delete the dossier and all its children
DELETE FROM Dossiers
WHERE SectionCode LIKE @SectionCode + '%';

-- If no errors, commit the transaction
COMMIT TRANSACTION;
END

我正在 Entity Framework Core 中处理分层数据。每个记录或“达析报告”都有一个代表其在层次结构中的位置的SectionCode,以及链接到其父达析报告的ParentId。

当我删除达析报告时,我想更新同一层次结构级别的所有后续达析报告及其子达析报告的部分代码。但是,我面临一个问题,即层次结构的所有级别的 SectionCode 都没有正确更新。

我该怎么办才能解决这个问题?请帮忙

© www.soinside.com 2019 - 2024. All rights reserved.