SQL delete records in order

时间:2016-04-15 15:10:31

标签: sql sql-server sql-delete

Given the table structure:

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

I want to run DELETE FROM Comments to remove all records.

However, the relationship with the parent comment record creates a FK conflict if the parent comment is deleted before the child comments.

To solve this, deleting in reverse ID order would work. How do I delete all records in a table in reverse ID order?

3 个答案:

答案 0 :(得分:5)

以下内容将删除所有不属于父级的行。如果表很大且ParentCommentID上没有索引,则可能需要一段时间才能运行...

DELETE Comment
 from Comment co
 where not exists (--  Correlated subquery
                   select 1
                    from Comment
                    where ParentCommentID = co.ID)

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

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

这最后一个当然是危险的(注意用于测试的开始/结束事务!)你需要WHERE条款来限制被删除的东西,以及确保你不会以某种方式命中的东西无限循环 - 所有细节都取决于您的数据和环境。

答案 1 :(得分:0)

With separate Parent and Child tables, ON DELETE CASCADE would ensure that deleting the parent also deletes the children. Does it work when both sets of data are within the same table? Maybe, and I'd love to find out!

How do I use cascade delete with SQL server.

答案 2 :(得分:0)

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

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