Cos'è una VINCITA CON WITH CHECK CHECK?


18

Ho un T-SQL generato automaticamente, che è probabilmente valido, ma non capisco davvero.

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

So cos'è un vincolo di chiave esterna, ma qual è il CHECK CHECK?

Risposte:


27

La pagina di documentazione MSDN su ALTER TABLEspiega questi:

  • ALTER TABLE: modifica la struttura della tabella
    (e alcune delle possibili azioni / modifiche sono):
    • CHECK CONSTRAINT ..: abilita il vincolo
    • NOCHECK CONSTRAINT ..: disabilita il vincolo
      Ci sono anche ulteriori passaggi opzionali da fare durante la creazione / abilitazione / disabilitazione di un vincolo:
      • WITH CHECK: controlla anche il vincolo
      • WITH NOCHECK: non verifica il vincolo

Nelle loro parole:

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

...

WITH CHECK | WITH NOCHECK Specifica se i dati nella tabella sono o meno convalidati rispetto a un nuovo aggiunto, riattivato FOREIGN KEYo CHECKvincolo . Se non specificato, WITH CHECKviene assunto per nuovi vincoli e WITH NOCHECKassunto per vincoli riattivati.

Se non si desidera verificare nuovi CHECKo FOREIGN KEYvincoli rispetto ai dati esistenti, utilizzare WITH NOCHECK. Non è consigliabile farlo, tranne in rari casi. Il nuovo vincolo verrà valutato in tutti gli aggiornamenti successivi dei dati. Qualsiasi violazione del vincolo che viene soppressa WITH NOCHECKquando viene aggiunto il vincolo può causare errori futuri in caso di aggiornamento di righe con dati non conformi al vincolo.

Query Optimizer non considera i vincoli definiti WITH NOCHECK. Tali vincoli vengono ignorati fino a quando non vengono riattivati ​​utilizzando la ALTER TABLEtabella WITH CHECK CHECK CONSTRAINT ALL.

...

{ CHECK | NOCHECK } CONSTRAINT
Specifica che Vincolo_nome è abilitato o disabilitato. Questa opzione può essere utilizzata solo con FOREIGN KEYe CHECKvincoli. Quando NOCHECKviene specificato, il vincolo è disabilitato e i futuri inserimenti o aggiornamenti alla colonna non vengono convalidati rispetto alle condizioni del vincolo. DEFAULT, PRIMARY KEYe i UNIQUEvincoli non possono essere disabilitati.

Test in dbfiddle :

CREATE TABLE a (aid INT PRIMARY KEY);

PARTIRE

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

PARTIRE

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

PARTIRE

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

PARTIRE

4 file interessate
INSERT INTO b (aid, bid)
VALUES
  (6, 61),
  (6, 62) ;

PARTIRE

Messaggio 547 livello 16 stato 0 riga 1
L'istruzione INSERT è in conflitto con il vincolo FOREIGN KEY "My_FORIEGN_KEY". Il conflitto si è verificato nel database "fiddle_792fce5de09f42908c3a0f91421f3522", tabella "dbo.a", colonna "help".
Messaggio 3621 Livello 0 Stato 0 Riga 1
La dichiarazione è stata chiusa.
SELECT * FROM b ;

PARTIRE

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

PARTIRE

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

PARTIRE

2 file interessate
SELECT * FROM b ;

PARTIRE

aiuto | offerta
-: | -:
  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

PARTIRE

SELECT * FROM b ;

PARTIRE

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

PARTIRE

Messaggio 547 livello 16 stato 0 riga 1
L'istruzione INSERT è in conflitto con il vincolo FOREIGN KEY "My_FORIEGN_KEY". Il conflitto si è verificato nel database "fiddle_792fce5de09f42908c3a0f91421f3522", tabella "dbo.a", colonna "help".
Messaggio 3621 Livello 0 Stato 0 Riga 1
La dichiarazione è stata chiusa.
SELECT * FROM b ;

PARTIRE

aiuto | offerta
-: | -:
  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 

PARTIRE

Messaggio 547 livello 16 stato 0 riga 1
L'istruzione ALTER TABLE è in conflitto con il vincolo FOREIGN KEY "My_FORIEGN_KEY". Il conflitto si è verificato nel database "fiddle_792fce5de09f42908c3a0f91421f3522", tabella "dbo.a", colonna "help".

1
Grazie. Scritto ALTER TABLE b WITH NOCHECK CHECK CONSTRAINT [My_FORIEGN_KEY]; -- enable constraint without checking, questo significa che il vincolo non controllerà i dati esistenti, ma solo i nuovi dati in arrivo?
BanksySan,

1
Esattamente. Scopri come l'inserzione successiva (aiuto = 6) non è consentita ma le righe esistenti (con aiuto = 4) sono ancora lì.
ypercubeᵀᴹ

Questo lo dimostra perfettamente.
BanksySan,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.