Удалить всех детей на столе, который ссылается на себя - PullRequest
2 голосов
/ 21 сентября 2019

Допустим, у нас есть таблица, которая выглядит следующим образом:

CREATE TABLE Test
(
    Id INT NOT NULL PRIMARY KEY IDENTITY(1,1),
    [Name] NVARCHAR(50) NOT NULL,
    ParentId INT NULL FOREIGN KEY REFERENCES Test(Id)
)

В этой таблице у нас есть иерархия данных, которая может выглядеть примерно так:

INSERT INTO Test (Name) 
VALUES ('ABC'), ('DEF'), ('HIJ');
GO

INSERT INTO TEST (Name, ParentId) 
VALUES ('KLM', 1), ('NOP', 1), ('QRS', 2), ('TUV', 2), ('XYX', 3)
GO

INSERT INTO Test (Name, ParentId) 
VALUES ('AAB', 4), ('AAC', 4), ('AAD', 4)

Как можноУдалить идентификатор 1 и все его дочерние элементы без использования каскадного удаления?

1 Ответ

1 голос
/ 21 сентября 2019

Вы должны будете использовать rCTE (рекурсивное выражение общих таблиц), чтобы пройти через иерархию.Затем вы можете JOIN передать эти данные в вашу таблицу и удалить соответствующие строки:

DECLARE @ID int = 1;

WITH rCTE AS(
    SELECT T.Id
    FROM dbo.Test T
    WHERE T.Id = @ID
    UNION ALL
    SELECT T.Id
    FROM rCTE r
         JOIN dbo.Test T ON r.Id = T.ParentId)
DELETE T
FROM dbo.Test T
     JOIN rCTe r ON T.Id = r.Id;

Обратите внимание, что в отличие от некоторых примеров, которые вы, возможно, видели, например, когда CTE используется для DELETE дублирующихся строк, rCTE не обновляется (из-за использования UNION).Таким образом, вы не можете просто выполнить DELETE операцию над CTE в конце (DELETE FROM rCTE), и вы должны использовать ее как JOIN.

DB <> Fiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...