Risposte:
La pagina di documentazione MSDN su ALTER TABLE
spiega questi:
ALTER TABLE
: modifica la struttura della tabella CHECK CONSTRAINT ..
: abilita il vincoloNOCHECK CONSTRAINT ..
: disabilita il vincolo WITH CHECK
: controlla anche il vincoloWITH NOCHECK
: non verifica il vincoloNelle 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, riattivatoFOREIGN KEY
oCHECK
vincolo . Se non specificato,WITH CHECK
viene assunto per nuovi vincoli eWITH NOCHECK
assunto per vincoli riattivati.Se non si desidera verificare nuovi
CHECK
oFOREIGN KEY
vincoli rispetto ai dati esistenti, utilizzareWITH 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 soppressaWITH NOCHECK
quando 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 laALTER TABLE
tabellaWITH CHECK CHECK CONSTRAINT ALL
....
{ CHECK | NOCHECK } CONSTRAINT
Specifica che Vincolo_nome è abilitato o disabilitato. Questa opzione può essere utilizzata solo conFOREIGN KEY
eCHECK
vincoli. QuandoNOCHECK
viene specificato, il vincolo è disabilitato e i futuri inserimenti o aggiornamenti alla colonna non vengono convalidati rispetto alle condizioni del vincolo.DEFAULT
,PRIMARY KEY
e iUNIQUE
vincoli 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".
Valuta di leggere l'articolo qui: https://msdn.microsoft.com/en-us/library/ms190273.aspx
Ci dice: 'Query Optimizer non considera i vincoli definiti CON NOCHECK. Tali vincoli vengono ignorati fino a quando non vengono riattivati utilizzando la tabella ALTER TABLE CON CHECK CHECK CONSTRAINT ALL '
Inoltre, considera questo thread su StackOverflow: /programming/529941/with-check-add-constraint-followed-by-check-constraint-vs-add-constraint
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?