2016-04-15 3 views
0

Учитывая структуру таблицы:SQL удалять записи в порядке

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

Я хочу запустить DELETE FROM Comments, чтобы удалить все записи.

Однако связь с родительской записью комментариев создает конфликт FK, если родительский комментарий удаляется до комментариев ребенка.

Чтобы решить эту проблему, удаление в обратном порядке идентификатора будет работать. Как удалить все записи в таблице в порядке обратного идентификатора?

+1

Отключить внешний ключ и обрезать таблицу, включить FK. – lad2025

+2

обновите внешний ключ CASCADE – Mihai

+0

Смотрите предыдущий [SO ответ] (http://stackoverflow.com/a/18616544/1260204). В принципе, снимите текущее ограничение FK и повторно добавьте его с опцией удаления каскада. Это позволит одному удалению удалить записи из обеих таблиц. – Igor

ответ

4

Ниже будут удалены все строки, которые не являются сами родители. Если таблица большая и нет никакого индекса на 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, чтобы ограничить то, что удаляется, и что-то или гарантировать, что вы каким-то образом не достигли бесконечного цикла - все подробности которые зависят от ваших данных и обстоятельств.

0

С помощью отдельных родительских и дочерних таблиц ON DELETE CASCADE гарантирует, что удаление родителя также удалит дочерние элементы. Работает ли он, когда оба набора данных находятся в одной таблице? Может быть, и мне бы хотелось узнать!

How do I use cascade delete with SQL server.

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 
Смежные вопросы