2016-03-25 16 views
0

私は複数のテーブル(約52)によって参照されているテーブルを持っており、さらに、子テーブルのいくつかは、他のテーブルも参照している複数の外部キーを持っています。複数の子テーブルによって参照される親テーブルからレコードを削除するにはどうすればよいですか?

エラーが発生したため、親テーブルからレコードを削除したい "DELETEステートメントがREFERENCE制約" FK_xxx "と競合しました。競合がデータベース" MyDB "、テーブル" dbo.A "、列 'x'

テーブルと参照数に関係なく一般化されたT-SQLソリューションが必要です。

+0

いくつかのコードを示してください。たぶん私はあなたを助けることができます。 – Francisunoxx

答えて

1

外部キー制約定義の一部である "on delete"キーワードを調べる必要があります。 基本的には4つのオプションがあります。

  • NO ACTIONは(何もしない)
  • CASCADE(子aswellを削除します)
  • のSET NULL(ヌルに参照フィールドを設定します)
  • のSET DEFAULT(設定デフォルト値への参照フィールド)

例は次のようになります

CREATE TABLE parent (
    id INT NOT NULL, 
    PRIMARY KEY (id) 
) ENGINE=INNODB; 

CREATE TABLE child (
    id INT, 
    parent_id INT, 
    INDEX par_ind (parent_id), 
    FOREIGN KEY (parent_id) 
     REFERENCES parent(id) 
     ON DELETE CASCADE -- replace CASCADE with your choice 
) ENGINE=INNODB; 

(この例では、より詳細にはここを見て:http://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html)を

あなたが今、あなたの制約を変更したい場合は、あなたが最初にそれをドロップすると、例えばのような新しいものを作成する必要があります。

ALTER TABLE child 
ADD CONSTRAINT fk_name 
FOREIGN KEY (parent_id) 
REFERENCES parent(id) 
ON DELETE CASCADE; -- replace CASCADE with your choice 

私はこれが助けてくれることを願っています。また言及するには、親を実際に削除しないで、別のブール型列「削除済み」を作成することをお勧めします。 「選択」クエリでは、その「削除済み」列でフィルタリングします。 このエントリの履歴は失われないという利点があります。

+0

すべての子テーブルを削除することはできません。いつでも何度も何度も実行できるコードまたはストアドプロシージャが必要です。 –

+0

あなたがこれを正しく理解しているかどうかはわかりません。テーブルを削除しないで、外部キー制約を削除し、それをあなたが望むように動作するものに置き換えます。まず、子テーブルの参照フィールドがどのように見えるかを知る必要があります。あなたが壊れた参照に満足しているなら、 "行動なし"をしてください。また、親が削除されたときに子を削除したい場合は、「カスケード」を選択します。履歴のために保持する場合は、別のものに置き換える場合は「NULLを設定」 "デフォルト設定"。あなたは子データではなく参照のみを「失う」 – chickahoona

+0

@varunkumardutta:質問を更新してください – TheGameiswar

0

問題は次のとおりです。FK制約は、52個のテーブルのいずれかに孤立した子レコードを作成できないように設計されています。私はあなたが探しているスクリプトを提供することができますが、FK制約を再び有効にしようとすると、孤立したデータ(FK制約が防止するように設計されているため)で制約が再度有効にならないことをまず認識しておく必要があります。あなたの次のステップでは、最初に52テーブルのそれぞれの孤立したデータを削除する必要があります。実際には、ON DELETE CASCADEを使用して制約をやり直すだけで、制約を破棄して参照整合性を完全に忘れることは、はるかに簡単です。あなたはそれを両方向に持つことはできません。

関連する問題