SQL按顺序删除记录

SQL delete records in order

给定 table 结构:

Comment
-------------
ID (PK)
ParentCommentID (FK)

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

但是,如果先删除父评论,再删除子评论,则与父评论记录的关系会产生 FK 冲突。

为了解决这个问题,倒序删除就可以了。如何以倒序删除 table 中的所有记录?

对于单独的父项和子项 table,ON DELETE CASCADE 将确保删除父项也会删除子项。当两组数据在同一个table内时,它是否有效?也许吧,我很想知道!

How do I use cascade delete with SQL server.

这个有效(您可以尝试用 top... 替换子查询)

create table #a1 (i1 int identity, b1 char(5))
insert into #a1 values('abc')
go 5 

while ( (select count(*) from #a1 ) > 0)
    begin 
     delete from #a1 where i1=(select top 1 i1 from #a1 order by i1 desc)

    end

以下将删除所有本身不是父项的行。如果 table 很大并且 ParentCommentID 上没有索引,则 运行...

可能需要一段时间
DELETE Comment
 from Comment co
 where not exists (--  Correlated subquery
                   select 1
                    from Comment
                    where ParentCommentID = co.ID)

如果 table 确实很大,大的删除会对您的系统造成不良影响,例如锁定 table 和使事务日志文件膨胀。以下将限制删除的行数:

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)

由于删除一些但不是全部可能不是那么有用,这里有一个循环结构,它将一直运行直到一切都消失:

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

最后一个当然是危险的(注意用于测试的 begin/end 事务!)您需要 WHERE 子句来限制删除的内容,以及某些内容或确保您不删除不知何故陷入无限循环——所有细节都取决于您的数据和情况。