でレコードを削除します。SQLは、テーブル構造を考えるため
ただし、子コメントの前に親コメントが削除されると、親コメントレコードとの関係でFKの競合が発生します。
これを解決するには、逆ID順で削除することができます。テーブル内のすべてのレコードをIDの逆順で削除するにはどうすればよいですか?
でレコードを削除します。SQLは、テーブル構造を考えるため
ただし、子コメントの前に親コメントが削除されると、親コメントレコードとの関係でFKの競合が発生します。
これを解決するには、逆ID順で削除することができます。テーブル内のすべてのレコードをIDの逆順で削除するにはどうすればよいですか?
以下は、親自身ではないすべての行を削除します。テーブルが大きいとParentCommentIDにはインデックスがありません場合は、それが実行にしばらく時間がかかるかもしれません...
DELETE Comment
from Comment co
where not exists (-- Correlated subquery
select 1
from Comment
where ParentCommentID = co.ID)
テーブルが本当に大きい場合、大きな削除は、ロックなど、お使いのシステムに悪いことを行うことができますテーブルとトランザクションログファイルをbloating。以下は削除されますどれだけ多くの行を制限します:
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
:いくつかを削除したよう
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)
をすべてではないが、それほど便利ではないかもしれない、ここですべてがなくなってまで続けるだろうループ構造ですこの最後のステップは危険です(テストに使用されるbegin/endトランザクションに注意してください)。WHERE
句を削除して何かを制限し、無限ループに何もしないようにします。あなたのデータと状況に依存します。
別の親テーブルと子テーブルを使用すると、ON DELETE CASCADEによって、親を削除すると子を削除することも確実になります。両方のデータセットが同じテーブル内にある場合は機能しますか?多分、私は見つけることが大好きです!
これは動作します(あなたがトップでサブクエリを交換してくださいすることができます...)
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
外部キーとトランケートテーブルを無効にし、FKを有効にします。 – lad2025
外部キーをCASCADE – Mihai
で更新してください。この前の[SO答え](http://stackoverflow.com/a/18616544/1260204)を参照してください。基本的に、現在のFK制約を削除し、カスケード削除オプションを使用して再追加します。これにより、単一の削除で両方のテーブルからレコードを削除できます。 – Igor