2014-11-15 2 views
0

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

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

И у меня есть рекурсивная процедура удаления для удаления узла и его дети, он использует курсор, и он работает отлично после пользователя на SO в моем предыдущем вопросе по этому вопросу указывал на проблемы с синтаксисом , (Deleting Tree-Nodes in a SQL table)

CREATE PROCEDURE DeleteFile 
    @FileID INTEGER, 
    @UserID VARCHAR(MAX) 
AS 
BEGIN 
    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 
    END 

Однако другой ответ на этот вопрос предложил использовать Common Table Expression, я гугл, и я не думаю, что я действительно понимаю, как может КТР заменить курсор в этой процедуре. Какие-либо предложения ?

ответ

3

Вы можете использовать рекурсивные CTE, чтобы получить все дочерние ID, которые должны быть удалены, а затем использовать его в ВЕЬЕТЕ:

with all_ids as (
    select id, ParentID 
    from FileTree 
    where id = 4 -- this is the root ID that should be deleted 

    union all 

    select c.id, c.ParentID 
    from FileTree c 
    join all_ids p on p.id = c.ParentID 
) 
delete from file_tree 
where id in (select id from all_ids); 

SQLFiddle пример: http://sqlfiddle.com/#!3/ef474f/1

+1

Так 4 является идентификатором узел, который вы хотите удалить, и в моем случае, где находится параметр? И, кстати, что все должно быть? –

+0

Правильно, '4' - это идентификатор, который вы хотите удалить. 'all_ids' является (рекурсивным) общим табличным выражением, которое создает иерархию всех дочерних узлов. –

+1

Спасибо, это работает отлично. –

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