2017-02-14 19 views
3

自己参照型のコメント表があります。 私は削除カスケードに書き込もうとしましたが、それは自己参照表の削除カスケード時

Introducing FOREIGN KEY constraint 'FK_Comments_Comments' on table 'Comments' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

いくつかの例外を取った後、トリガーを書き込もうが、それは例外を取る再び

CREATE TRIGGER [dbo].[T_comment_Trigger] 
    ON [dbo].[Comments] 
    FOR DELETE 
AS 
    DELETE FROM Comments 
    WHERE ParentId =(SELECT deleted.id FROM deleted) 
私はのために削除カスケードで行うことができますどのように

couldn't delete rows that have children

私の自己参照テーブル?

+2

あなたは* *エラーメッセージに注意を払っている場合それは本当に役立つだろう*単に「例外をとる」というよりも、テキストを質問にコピーした*。 –

+0

トリガーに大きな問題があります。これは、1つの行だけが削除されることを前提としています。あなたはこのタイプのもののために結合を使う必要があります。 –

+0

@Damien_The_Unbeliever私の質問 – Mike

答えて

6

FOREIGN KEYの制約を維持していると仮定すると、FOR DELETEトリガーで問題を修正することはできません。 FORトリガー(AFTERトリガーとも呼ばれます)は、の後にのアクティビティが発生しました。また、外部キーがの場合、参照がある場合は、行が削除されないようになります。外部キーのチェックはの前に行われ、の削除が行われます。

トリガーはINSTEAD OFトリガーです。また、現在のトリガは参照の1つの "レベル"に対処しようとしたことに留意する必要があります。 (だから、行3参照行2と行2参照行1、あなたは1行を削除するには、あなたのトリガーはわずか2行を削除しようとした場合)

ので、何かのように:

CREATE TRIGGER [dbo].[T_comment_Trigger] 
    ON [dbo].[Comments] 
    INSTEAD OF DELETE 
AS 
    ;WITH IDs as (
     select id from deleted 
     union all 
     select c.id 
     from Comments c 
       inner join 
      IDs i 
       on 
       c.ParentID = i.id 
    ) 
    DELETE FROM Comments 
    WHERE id in (select id from IDs); 

がある場合他の(非自己参照型)カスケード型の外部キー制約は、すべてこのトリガー内のアクションに置き換えなければなりません。そのような場合には、私は最終的にCommentsテーブルから削除されるすべてのIDのリストを保持するテーブル変数を導入するお勧めします:

CREATE TRIGGER [dbo].[T_comment_Trigger] 
    ON [dbo].[Comments] 
    INSTEAD OF DELETE 
AS 
    declare @deletions table (ID varchar(7) not null); 
    ;WITH IDs as (
     select id from deleted 
     union all 
     select c.id 
     from Comments c 
       inner join 
      IDs i 
       on 
       c.ParentID = i.id 
    ) 
    insert into @deletions(ID) 
    select ID from IDs 

    DELETE FROM OtherTable 
    WHERE CommentID in (select ID from @deletions) 

    --This delete comes last 
    DELETE FROM Comments 
    WHERE id in (select ID from @deletions); 
+0

を編集します。**テーブル 'dbo.Comments'の代わりに、置き換えトリガーまたは代わりに更新トリガー 'T_comment_Trigger'を作成することはできません。これは、表にカスケードDELETEまたはUPDATEを伴うFOREIGN KEYが存在するためです。** – Mike

+0

@Mike - すべてのカスケードする外部キーを削除して、このトリガー内のすべてのカスケードを手動で実装する必要があります。 (あなたは引き続きFKを使うことができますが、カスケードオプションはありません) –

+0

**私のテーブルには他の外部キーのための 'カスケード削除 'があります** – Mike