2014-11-11 2 views
2

Я пытаюсь написать рекурсивную процедуру, которая удалит узел и все его дочерние элементы, если они такие в таблице. Я пробовал сделать следующее:Удаление деревьев-узлов в таблице SQL

CREATE PROCEDURE DeleteFile 
    @FileID INTEGER, 
    @UserID VARCHAR(MAX) 
AS 
    DELETE FROM [FileTree] WHERE [ID] = @FileID AND [UserID][email protected]; 
    IF EXISTS(SELECT * FROM [FileTree] WHERE [ParentID] = @FileID AND [UserID][email protected]) 
    BEGIN 
     DECLARE FileCursor CURSOR LOCAL FOR 
      SELECT [ID],[UserID] FROM [FileTree] WHERE [ParentID] = @FileID AND [UserID][email protected]; 
     OPEN FileCursor 
     FETCH NEXT FROM FileCursor INTO @FileID , @UserID 
     WHILE @@FETCH_STATUS =0 
     BEGIN 
      EXEC DeleteFile @FileID,@UserID; 
      FETCH NEXT FROM FileCursor INTO @FileID , @UserID ; 
     END 
    END 
    ELSE 
    return 

Но по какой-то причине это не работает. Он удаляет узел, но дети остаются. . Таблица ,, дизайн»

CREATE TABLE [FileTree] (
    [ID]  INT   IDENTITY NOT NULL, 
    [Name]  VARCHAR (MAX) NOT NULL, 
    [ParentID] INT   NULL, 
    [UserID] VARCHAR (MAX) NOT NULL 
); 

Можете ли вы указать ошибки, которые я сделал и предложить рабочую процедуру UPD: Я сделал курсор LOCAL и я выборка один раз, прежде чем в то время цикла, его еще не удаляет всех детей

+0

Я не знаю, почему ваш не работает, но я бы изучил использование рекурсивного CTE для получения всех идентификаторов родителя и удаления из таблицы, в которой идентификатор находится в CTE. Google «рекурсивный CTE» для множества примеров. –

ответ

1

Я думаю, вы синтаксис problem.I установил его как этот

1

вы можете использовать КТР и временную таблицу:.

WITH CTE (ID) 
AS 
(
    SELECT ID FROM FileTree WHERE [email protected] 
    UNION ALL 
    SELECT t.ID FROM FileTree t 
    INNER JOIN CTE c ON t.ParentId=c.Id 
) 
SELECT ID INTO #temp FROM CTE; 


DELETE FROM FileTree WHERE ID IN(SELECT ID FROM #temp) 
DROP TABLE #temp 
+1

Подождите, но как должна быть организована рекурсия? Создать временную таблицу после проверки наличия детей и использовать код, который вы написали, и он удалит всех детей и их детей? Если вы объясните, как это работает, это будет очень полезно. –

+0

Рекурсия выполняется CTE, затем CTE вставляет идентификаторы самого узла и его дочерних элементов в #temp. В конце мы можем использовать #temp для удаления узлов, которые мы хотим удалить. –

+1

Спасибо за ваш ответ, я посмотрю, что) –

Смежные вопросы