我有一个存储在 SQL 表中的字符串树,这是该表的定义。
CREATE TABLE [FileTree] (
[ID] INT NOT NULL,
[Name] VARCHAR (MAX) NOT NULL,
[ParentID] INT NULL,
[UserID] VARCHAR (MAX) NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
我有一个递归删除过程,用于删除节点及其子节点,它使用游标,并且在我上一个关于此事的问题中的用户指出语法问题后,它工作得非常好。(删除 SQL 表中的树节点)
CREATE PROCEDURE DeleteFile
@FileID INTEGER,
@UserID VARCHAR(MAX)
AS
BEGIN
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
Run Code Online (Sandbox Code Playgroud)
然而,对问题的另一个答复建议使用通用表表达式,我用谷歌搜索,我认为我并不真正理解 CTE 如何替换此过程中的光标。有什么建议 ?
小智 5
您可以使用递归 CTE 获取应删除的 ID 的所有子级,然后在 DELETE 语句中使用它:
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);
Run Code Online (Sandbox Code Playgroud)
SQLFiddle 示例:http://sqlfiddle.com/#!3/ef474f /1
| 归档时间: |
|
| 查看次数: |
1168 次 |
| 最近记录: |