SQL按顺序删除记录

Tom*_*len 1 sql sql-server sql-delete

给定表结构:

Comment
-------------
ID (PK)
ParentCommentID (FK)
Run Code Online (Sandbox Code Playgroud)

我想运行DELETE FROM Comments删除所有记录.

但是,如果在子注释之前删除父注释,则与父注释记录的关系会产生FK冲突.

要解决此问题,以反向ID顺序删除将起作用.如何以反向ID顺序删除表中的所有记录?

Phi*_*ley 5

以下将删除所有不是父项的行.如果表很大并且ParentCommentID上没有索引,则可能需要一段时间才能运行...

DELETE Comment
 from Comment co
 where not exists (--  Correlated subquery
                   select 1
                    from Comment
                    where ParentCommentID = co.ID)
Run Code Online (Sandbox Code Playgroud)

如果表真的很大,那么大的删除可能会对系统造成不良影响,例如锁定表并使事务日志文件膨胀.以下将限制将删除的行数:

DELETE top (1000) Comment  --  (1000 is not very many)
 from Comment co
 where not exists (--  Correlated subquery
                   select 1
                    from Comment
                    where ParentCommentID = co.ID)
Run Code Online (Sandbox Code Playgroud)

删除一些但不是全部可能没那么有用,这里有一个循环结构,一直到一切都消失了:

DECLARE @Done int = 1

--BEGIN TRANSACTION

WHILE @Done > 0
 BEGIN
    --  Loop until nothing left to delete
    DELETE top (1000) Comment
     from Comment co
     where not exists (--  Correlated subquery
                       select 1
                        from Comment
                        where ParentCommentID = co.ID)
    SET @Done = @@Rowcount

 END

--ROLLBACK
Run Code Online (Sandbox Code Playgroud)

当然,这最后是危险的(请注意用于测试的开始/结束事务!)您将希望WHERE子句限制被删除的内容,以及确保您不会以某种方式触及无限循环的所有细节取决于您的数据和情况.