WITH CHECK CHECK CONSTRAINTとは何ですか?


18

おそらく自動生成されたT-SQLがいくつかありますが、これはおそらく有効ですが、実際にはわかりません。

ALTER TABLE [dbo].[MyTable]
WITH CHECK
CHECK CONSTRAINT [My_FORIEGN_KEY];

私は外部キー制約が何であるか知っていますが、何CHECK CHECKですか?

回答:


27

ALTER TABLEこれらについては、MSDNのドキュメントページで説明しています。

  • ALTER TABLE:テーブルの構造を変更します
    (および可能なアクション/変更の一部は次のとおりです)。
    • CHECK CONSTRAINT ..:制約を有効にします
    • NOCHECK CONSTRAINT ..:制約の無効化制約の
      作成/有効化/無効化中に実行する追加のオプションの手順もあります。
      • WITH CHECK:制約も確認します
      • WITH NOCHECK:制約をチェックしません

彼らの言葉で:

| [ WITH { CHECK | NOCHECK } ] { CHECK | NOCHECK } CONSTRAINT   
    { ALL | constraint_name [ ,...n ] }

...

WITH CHECK | WITH NOCHECKテーブル内のデータが、新しく追加または再有効化された制約FOREIGN KEYまたはCHECK制約に対して検証される かどうかを指定します。指定されていない場合WITH CHECK、新しい制約に対してWITH NOCHECK想定され、再有効化された制約に対して想定されます。

新しい検証したくない場合CHECKFOREIGN KEY、既存のデータ、使用に対して制約をWITH NOCHECK。まれな場合を除き、これを行うことはお勧めしません。新しい制約は、その後のすべてのデータ更新で評価されます。WITH NOCHECK制約が追加されたときに抑制された制約違反は、制約に準拠しないデータで行を更新すると、将来の更新が失敗する可能性があります。

クエリオプティマイザーは、定義されている制約を考慮しませんWITH NOCHECK。このような制約は、ALTER TABLEtableを使用して再度有効にするまで無視されますWITH CHECK CHECK CONSTRAINT ALL

...

{ CHECK | NOCHECK } CONSTRAINT
constraint_nameを有効または無効にすることを指定します。このオプションはFOREIGN KEYand CHECK制約でのみ使用できます。ときにNOCHECK指定され、制約が無効になっていると、カラムへの将来の挿入や更新は、制約条件に対して検証されていません。DEFAULTPRIMARY KEY、およびUNIQUE制約は無効にすることはできません。

dbfiddleでテストします

CREATE TABLE a (aid INT PRIMARY KEY);

行く

INSERT INTO a (aid)
VALUES (1), (2), (3) ;

行く

影響を受ける3行
CREATE TABLE b 
( aid INT,
  bid INT PRIMARY KEY,
  CONSTRAINT [My_FORIEGN_KEY]
    FOREIGN KEY (aid) REFERENCES a (aid)
) ;

行く

INSERT INTO b (aid, bid)
VALUES
  (1, 11),
  (1, 12),
  (2, 21), 
  (3, 31) ;

行く

影響を受ける4行
INSERT INTO b (aid, bid)
VALUES
  (6, 61),
  (6, 62) ;

行く

メッセージ547レベル16状態0行1
INSERTステートメントがFOREIGN KEY制約「My_FORIEGN_KEY」と競合しました。データベース「fiddle_792fce5de09f42908c3a0f91421f3522」、テーブル「dbo.a」、列「aid」で競合が発生しました。
メッセージ3621レベル0状態0行1
ステートメントは終了されました。
SELECT * FROM b ;

行く

援助| 入札
-:| -:
  1 | 11
  1 | 12
  2 | 21
  3 | 31
ALTER TABLE b NOCHECK CONSTRAINT [My_FORIEGN_KEY];   --disable

行く

INSERT INTO b (aid, bid)
VALUES
  (4, 41),
  (4, 42) ;

行く

影響を受ける2行
SELECT * FROM b ;

行く

援助| 入札
-:| -:
  1 | 11
  1 | 12
  2 | 21
  3 | 31
  4 | 41
  4 | 42
ALTER TABLE b WITH NOCHECK CHECK CONSTRAINT [My_FORIEGN_KEY];  
-- enable constraint without checking existing data

行く

SELECT * FROM b ;

行く

援助| 入札
-:| -:
  1 | 11
  1 | 12
  2 | 21
  3 | 31
  4 | 41
  4 | 42
INSERT INTO b (aid, bid)
VALUES
  (6, 61),
  (6, 62) ;

行く

メッセージ547レベル16状態0行1
INSERTステートメントがFOREIGN KEY制約「My_FORIEGN_KEY」と競合しました。データベース「fiddle_792fce5de09f42908c3a0f91421f3522」、テーブル「dbo.a」、列「aid」で競合が発生しました。
メッセージ3621レベル0状態0行1
ステートメントは終了されました。
SELECT * FROM b ;

行く

援助| 入札
-:| -:
  1 | 11
  1 | 12
  2 | 21
  3 | 31
  4 | 41
  4 | 42
ALTER TABLE b WITH CHECK CHECK CONSTRAINT [My_FORIEGN_KEY];  
-- check existing data and enable constraint 

行く

メッセージ547レベル16状態0行1
ALTER TABLEステートメントがFOREIGN KEY制約「My_FORIEGN_KEY」と競合しました。データベース「fiddle_792fce5de09f42908c3a0f91421f3522」、テーブル「dbo.a」、列「aid」で競合が発生しました。

1
ありがとう。Wrt ALTER TABLE b WITH NOCHECK CHECK CONSTRAINT [My_FORIEGN_KEY]; -- enable constraint without checking、これは制約が既存のデータをチェックせず、新しい着信データのみをチェックすることを意味しますか?
BanksySan

1
丁度。次の挿入(aid = 6)が許可されていないが、既存の行(aid = 4)がまだあることを確認してください。
ypercubeᵀᴹ

それは完全にそれを示しています。
BanksySan

1

こちらの記事を読んで考えてみましょう: https://msdn.microsoft.com/en-us/library/ms190273.aspx

「クエリオプティマイザーは、WITH NOCHECKで定義された制約を考慮しません。このような制約は、ALTER TABLEテーブルWITH CHECK CHECK CONSTRAINT ALL 'を使用して再度有効にするまで無視されます。

また、StackOverflowのスレッドを検討してくださいhttps : //stackoverflow.com/questions/529941/with-check-add-constraint-followed-by-check-constraint-vs-add-constraint

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