SQL Serverでカスケード削除を使用するにはどうすればよいですか?


332

T1とT2の2つのテーブルがあります。これらは既存のデータテーブルです。T1とT2の間には1対多の関係があります。T1のレコードが削除されたときにSQL Serverでカスケード削除を実行するようにテーブル定義を変更するにはどうすればよいですか。T2のすべての関連レコードも削除されます。

それらの間に外部制約が設定されています。テーブルを削除したり、T2の削除を実行するトリガーを作成したりしたくありません。たとえば、従業員を削除すると、すべてのレビューレコードも削除されます。

T1-従業員、

Employee ID      
Name
Status

T2-パフォーマンスレビュー、

Employee ID - 2009 Review
Employee ID - 2010 Review

回答:


362

あなたがする必要があります、

  • 既存の外部キー制約を削除し、
  • ON DELETE CASCADE設定を有効にして新しいものを追加します。

何かのようなもの:

ALTER TABLE dbo.T2
   DROP CONSTRAINT FK_T1_T2   -- or whatever it's called

ALTER TABLE dbo.T2
   ADD CONSTRAINT FK_T1_T2_Cascade
   FOREIGN KEY (EmployeeID) REFERENCES dbo.T1(EmployeeID) ON DELETE CASCADE

3
私のチームと私はちょうどこれをやった。制約を削除して再度追加する必要がありました。これでうまくいきました。
ダニエルL.ヴァンデンボッシュ

2
これは完全削除を支持する方法ですか?論理削除では、制約の問題は発生しません。私とは正反対のようです。
Maxx 2018

2
@Maxxハード削除では、1つのレコードを削除し、孤立したレジスタについて心配する必要はありませんが、ソフト削除では手動で行う必要があります。
ロナウドアラウージョアルベス

318

SQL Server Management Studioで既存の外部キーに「カスケード削除」を追加するには:

まず、外部キーを選択し、それを「DROP and Create To ..」を新しいクエリウィンドウで開きます。

ここに画像の説明を入力してください

次に、コマンドに追加ON DELETE CASCADEしますADD CONSTRAINT

ん そして、「実行」ボタンを押してこのクエリを実行します。

ちなみに、外部キーのリストを取得し、「カスケード削除」がオンになっているキーを確認するには、次のスクリプトを実行します。

SELECT 
   OBJECT_NAME(f.parent_object_id) AS 'Table name',
   COL_NAME(fc.parent_object_id,fc.parent_column_id) AS 'Field name',
   delete_referential_action_desc AS 'On Delete'
FROM sys.foreign_keys AS f,
     sys.foreign_key_columns AS fc,
     sys.tables t 
WHERE f.OBJECT_ID = fc.constraint_object_id
AND t.OBJECT_ID = fc.referenced_object_id
ORDER BY 1

またDROP、外部キー制約のために特定のテーブルを使用できないことがわかったが、問題の原因となっているFKを特定できない場合は、次のコマンドを実行できます。

sp_help 'TableName'

その記事のSQLには、特定のテーブルを参照するすべてのFKがリストされています。

このすべてがお役に立てば幸いです。

長い指でお詫び申し上げます。私はただ主張しようとしていました。


163

SQL Server Management Studioでこれを行うことができます。

→テーブルデザインを右クリックして[Relationships]に移動し、左側のペインと右側のペインで外部キーを選択して、メニュー[INSERT and UPDATE specification]を展開し、Delete Ruleとして[Cascade]を選択します。

SQL Server Management Studio


こんにちは。4の違いは何ですか。カスケードをオンにすると、テーブル内のすべてのデータを簡単に削除できます。どのように私はすべての依存関係/ FKキーを表示することができますはない、この表から、このテーブル。すべてのFKを削除した後でも、エラーが発生します
aggie

@aggie-依存関係を次の方法で確認できます-テーブルを右クリック-> [依存関係の表示]また、SQLサーバーは、「DELETEステートメントがREFERENCE制約 "FK_Child1_Parent1"と競合しています。データベース "TESTDB"、テーブル "dbo.Child1"、列 'Parent1ID'で競合が発生しました。
パラニクマール

@aggie-また、4番目のケースの「デフォルトの設定」は、外部キー列にデフォルトの制約を設定する必要があります。親を削除すると、デフォルト値が子テーブルで置き換えられます。(注:既定値は親テーブルと一致する必要があります。)詳細については、mssqltips.com
sqlservertip / 2365 /

これはとても役に立ちます。挿入ルールがないのはなぜですか?つまり、T1に行を追加すると、T2の対応するエントリが自動的に作成されます。
ロバートM.

@RobertM。それは意味がないからです。どのような値を挿入するかをどのようにして知るのでしょうか?INSERTトリガーを使用して子の行を生成できる場合があります。調査してみてください。
Dan Bechard 2017

46

のようなものを使う

ALTER TABLE T2
ADD CONSTRAINT fk_employee
FOREIGN KEY (employeeID)
REFERENCES T1 (employeeID)
ON DELETE CASCADE;

正しい列名を入力すると、設定する必要があります。mark_sが正しく述べたように、すでに外部キー制約が設定されている場合は、最初に古い制約を削除してから、新しい制約を作成する必要がある場合があります。


41
@marc_s-実際には、両側のまったく同じ列に対して2番目の外部キーを追加でき、正しく動作します。ダウンタイムのない実稼働環境で作業している場合は、FKが配置されていないときにテーブルにウィンドウを残さずに、カスケード付きの新しいFKを導入してから古いFKをドロップすることをお勧めします。(SQL 2008でテスト済み)
Damien_The_Unbeliever

これは正しいです。私はこれを試してみましたが、うまくいきました。最初の外部キー制約を削除する必要はありません。返信いただきありがとうございます。
Bichvan Nguyen

15

最初にONCascadeプロパティを有効にする:

1.既存の外部キー制約を削除する

2. ON DELETE CASCADE設定を有効にして新しいものを追加する

例:

IF EXISTS(SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.Response'))
 BEGIN 

ALTER TABLE [dbo].[Response] DROP CONSTRAINT [FK_Response_Request]  

ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request]  FOREIGN KEY([RequestId])
REFERENCES [dbo].[Request] ([RequestId])
ON DELETE CASCADE
END

ELSE

 BEGIN 
 ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request]  FOREIGN KEY([RequestId])
REFERENCES [dbo].[Request] ([RequestId])
ON DELETE CASCADE
END

ONCascadeプロパティを無効にする2つ目:

1.既存の外部キー制約を削除する

2. ON DELETE NO ACTION設定を有効にして新しいものを追加します。

例:

IF EXISTS(SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.Response'))
 BEGIN 
ALTER TABLE [dbo].[Response] DROP CONSTRAINT [FK_Response_Request]  

ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request]  FOREIGN KEY([RequestId])
REFERENCES [dbo].[Request] ([RequestId])
ON DELETE CASCADE
END

ELSE

 BEGIN 
 ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request]  FOREIGN KEY([RequestId])
REFERENCES [dbo].[Request] ([RequestId])
ON DELETE NO ACTION 
END

15

ON DELETE CASCADE
親データが削除されるときに子データが削除されることを指定します。

CREATE TABLE products
( product_id INT PRIMARY KEY,
  product_name VARCHAR(50) NOT NULL,
  category VARCHAR(25)
);

CREATE TABLE inventory
( inventory_id INT PRIMARY KEY,
  product_id INT NOT NULL,
  quantity INT,
  min_level INT,
  max_level INT,
  CONSTRAINT fk_inv_product_id
    FOREIGN KEY (product_id)
    REFERENCES products (product_id)
    ON DELETE CASCADE
);

この外部キーではON DELETE CASCADE、親テーブルのデータが削除されたときに子テーブルの対応するレコードを削除するようにSQL Serverに指示する句を指定しています。したがって、この例では、product_id値がproductsテーブルから削除されると、このproduct_idを使用する在庫テーブル内の対応するレコードも削除されます。


-2

1対多の関係がT1からT2である場合、それは関数を表さないため、結果のT2値が演繹的に有効なT1結合T2のタプルを省略しないことを保証する逆関数を推定または推論するために使用できません。 、演繹的に有効な逆関数がないためです。(関数を表すことが主キーの目的でした。)SQLでの答えは、「できる」ということです。リレーショナル思考の答えは、あなたがそれを行うことはできないということです。Codd 1970のあいまいな点を参照してください。関係はT1からT2まで多対1でなければなりません。


-10

これが実際の本番データである場合は、テーブルプロパティを削除するだけでなく、テーブルスキーマに影響を与えないコンテンツを削除することはできないと思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.