Was ist eine WITH CHECK CHECK-Einschränkung?

18

Ich habe einige automatisch generierte T-SQL, die wahrscheinlich gültig ist, aber ich verstehe nicht wirklich.

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

Ich weiß, was eine Fremdschlüsselbeschränkung ist, aber was ist die CHECK CHECK?

BanksySan
quelle

Antworten:

27

Auf der MSDN-Dokumentationsseite zu wird Folgendes ALTER TABLEerläutert:

  • ALTER TABLE: Ändere die Struktur der Tabelle
    (und einige der möglichen Aktionen / Änderungen sind):
    • CHECK CONSTRAINT ..: Aktivieren Sie die Einschränkung
    • NOCHECK CONSTRAINT ..: Deaktivieren der Einschränkung
      Beim Erstellen / Aktivieren / Deaktivieren einer Einschränkung sind außerdem zusätzliche, optionale Schritte erforderlich:
      • WITH CHECK: Überprüfen Sie auch die Einschränkung
      • WITH NOCHECK: überprüfen Sie die Einschränkung nicht

In ihren Worten:

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

...

WITH CHECK | WITH NOCHECK Gibt an, ob die Daten in der Tabelle ist oder validiert wird , nicht gegen eine neu hinzugefügte oder neu aktiviert FOREIGN KEYoder CHECKEinschränkung . Wenn nicht angegeben, WITH CHECKwird dies für neue Einschränkungen und WITH NOCHECKfür wieder aktivierte Einschränkungen angenommen.

Wenn Sie keine neuen Daten CHECKoder FOREIGN KEYEinschränkungen für vorhandene Daten überprüfen möchten , verwenden Sie WITH NOCHECK. Dies wird nur in seltenen Fällen empfohlen. Die neue Einschränkung wird bei allen späteren Datenaktualisierungen ausgewertet. Verstöße gegen Einschränkungen, die WITH NOCHECKbeim Hinzufügen der Einschränkung unterdrückt werden, können dazu führen, dass zukünftige Aktualisierungen fehlschlagen, wenn sie Zeilen mit Daten aktualisieren, die der Einschränkung nicht entsprechen.

Das Abfrageoptimierungsprogramm berücksichtigt keine definierten Einschränkungen WITH NOCHECK. Solche Einschränkungen werden ignoriert, bis sie mithilfe von ALTER TABLEtable wieder aktiviert werden WITH CHECK CHECK CONSTRAINT ALL.

...

{ CHECK | NOCHECK } CONSTRAINT
Gibt an, dass Constraint-Name aktiviert oder deaktiviert ist. Diese Option kann nur mit FOREIGN KEYund CHECKEinschränkungen verwendet werden. Wenn NOCHECKangegeben, ist die Einschränkung deaktiviert und zukünftige Einfügungen oder Aktualisierungen der Spalte werden nicht anhand der Einschränkungsbedingungen überprüft. DEFAULT, PRIMARY KEYUnd UNIQUEZwänge können nicht deaktiviert werden.

Test in DBFiddle :

CREATE TABLE a (aid INT PRIMARY KEY);

GEHEN

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

GEHEN

3 Zeilen betroffen
CREATE TABLE b 
( aid INT,
  bid INT PRIMARY KEY,
  CONSTRAINT [My_FORIEGN_KEY]
    FOREIGN KEY (aid) REFERENCES a (aid)
) ;

GEHEN

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

GEHEN

4 Zeilen betroffen
INSERT INTO b (aid, bid)
VALUES
  (6, 61),
  (6, 62) ;

GEHEN

Meldung 547 Stufe 16 Status 0 Zeile 1
Die INSERT-Anweisung ist mit der FOREIGN KEY-Einschränkung "My_FORIEGN_KEY" in Konflikt geraten. Der Konflikt ist in der Datenbank "fiddle_792fce5de09f42908c3a0f91421f3522", Tabelle "dbo.a", Spalte "aid" aufgetreten.
Meldung 3621 Ebene 0 Status 0 Zeile 1
Die Anweisung wurde beendet.
SELECT * FROM b ;

GEHEN

Hilfe bieten
-: | -:
  1 | 11
  1 | 12
  2 | 21
  3 | 31
ALTER TABLE b NOCHECK CONSTRAINT [My_FORIEGN_KEY];   --disable

GEHEN

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

GEHEN

2 Zeilen betroffen
SELECT * FROM b ;

GEHEN

Hilfe bieten
-: | -:
  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

GEHEN

SELECT * FROM b ;

GEHEN

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

GEHEN

Meldung 547 Stufe 16 Status 0 Zeile 1
Die INSERT-Anweisung ist mit der FOREIGN KEY-Einschränkung "My_FORIEGN_KEY" in Konflikt geraten. Der Konflikt ist in der Datenbank "fiddle_792fce5de09f42908c3a0f91421f3522", Tabelle "dbo.a", Spalte "aid" aufgetreten.
Meldung 3621 Ebene 0 Status 0 Zeile 1
Die Anweisung wurde beendet.
SELECT * FROM b ;

GEHEN

Hilfe bieten
-: | -:
  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 

GEHEN

Meldung 547 Stufe 16 Status 0 Zeile 1
Die Anweisung ALTER TABLE widersprach der FOREIGN KEY-Einschränkung "My_FORIEGN_KEY". Der Konflikt ist in der Datenbank "fiddle_792fce5de09f42908c3a0f91421f3522", Tabelle "dbo.a", Spalte "aid" aufgetreten.
ypercubeᵀᴹ
quelle
1
Vielen Dank. WRT ALTER TABLE b WITH NOCHECK CHECK CONSTRAINT [My_FORIEGN_KEY]; -- enable constraint without checking, bedeutet dies , dass die Beschränkung wird die bestehenden Daten nicht überprüfen, nur neu eingehende Daten?
BanksySan
1
Genau. Sehen Sie, wie das nächste Einfügen (aid = 6) nicht zulässig ist, aber vorhandene Zeilen (mit aid = 4) noch vorhanden sind.
ypercubeᵀᴹ
Das zeigt es perfekt.
BanksySan
1

Lesen Sie den Artikel hier: https://msdn.microsoft.com/en-us/library/ms190273.aspx

Es sagt uns: 'Das Abfrageoptimierungsprogramm berücksichtigt keine Einschränkungen, die mit NOCHECK definiert wurden. Solche Einschränkungen werden ignoriert, bis sie mithilfe der Tabelle ALTER TABLE WITH CHECK CHECK CONSTRAINT ALL wieder aktiviert werden.

Berücksichtigen Sie diesen Thread auch für StackOverflow: /programming/529941/with-check-add-constraint-followed-by-check-constraint-vs-add-constraint

George K
quelle