删除SQL表中的树节点

时间:2014-11-11 13:22:45

标签: sql-server tsql

我正在尝试编写一个递归过程,删除节点及其所有子节点(如果它们在表中)。我尝试了以下

  CREATE PROCEDURE DeleteFile 
    @FileID INTEGER,
    @UserID VARCHAR(MAX) 
AS
    DELETE FROM [FileTree] WHERE [ID] = @FileID AND [UserID]=@UserID;
    IF EXISTS(SELECT * FROM [FileTree] WHERE [ParentID] = @FileID AND [UserID]=@UserID)
    BEGIN
       DECLARE FileCursor CURSOR LOCAL FOR 
            SELECT [ID],[UserID] FROM [FileTree] WHERE [ParentID] = @FileID AND [UserID]=@UserID;
       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,并且在进入while循环之前我获取了一次,它仍然不会删除所有子项。

2 个答案:

答案 0 :(得分:1)

您可以使用CTE和临时表:

WITH CTE (ID)
AS
(
    SELECT ID FROM FileTree WHERE Id=@ID
    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 :(得分:1)

我认为你有语法问题。我像这样修复它

CREATE PROCEDURE DeleteFile 
    @FileID INTEGER,
    @UserID VARCHAR(MAX) 
AS
BEGAIN
    DELETE FROM [FileTree] WHERE [ID] = @FileID AND [UserID]=@UserID;
    IF EXISTS(SELECT * FROM [FileTree] WHERE [ParentID] = @FileID AND [UserID]=@UserID)
    BEGIN
       DECLARE FileCursor CURSOR LOCAL FOR 
            SELECT [ID],[UserID] FROM [FileTree] WHERE [ParentID] = @FileID AND [UserID]=@UserID;
       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