Respuestas:
La página de documentación de MSDN ALTER TABLE
explica esto:
ALTER TABLE
: modifica la estructura de la tabla CHECK CONSTRAINT ..
: habilitar la restricciónNOCHECK CONSTRAINT ..
: deshabilitar la restricción WITH CHECK
: compruebe la restricción tambiénWITH NOCHECK
: no verifique la restricciónEn sus palabras:
| [ WITH { CHECK | NOCHECK } ] { CHECK | NOCHECK } CONSTRAINT { ALL | constraint_name [ ,...n ] }
...
WITH CHECK | WITH NOCHECK
Especifica si los datos de la tabla se validan o no contra una restricciónFOREIGN KEY
oCHECK
restricción recientemente agregada o reactivada . Si no se especifica,WITH CHECK
se supone para nuevas restricciones, yWITH NOCHECK
se asume para restricciones reactivadas.Si no desea verificar nuevas restricciones
CHECK
oFOREIGN KEY
restricciones contra los datos existentes, useWITH NOCHECK
. No recomendamos hacer esto, excepto en casos excepcionales. La nueva restricción se evaluará en todas las actualizaciones de datos posteriores. Cualquier violación de restricciones que se suprimaWITH NOCHECK
cuando se agrega la restricción puede provocar que las actualizaciones futuras fallen si actualizan filas con datos que no cumplen con la restricción.El optimizador de consultas no considera las restricciones que se definen
WITH NOCHECK
. Dichas restricciones se ignoran hasta que se vuelven a habilitar mediante laALTER TABLE
tablaWITH CHECK CHECK CONSTRAINT ALL
....
{ CHECK | NOCHECK } CONSTRAINT
Especifica que restricint_name está habilitado o deshabilitado. Esta opción solo se puede usar conFOREIGN KEY
yCHECK
restricciones. CuandoNOCHECK
se especifica, la restricción se deshabilita y las futuras inserciones o actualizaciones de la columna no se validan en función de las condiciones de restricción.DEFAULT
,PRIMARY KEY
YUNIQUE
las limitaciones no se puede desactivar.
Prueba en dbfiddle :
CREATE TABLE a (aid INT PRIMARY KEY);
VAMOS
✓
INSERT INTO a (aid) VALUES (1), (2), (3) ;
VAMOS
3 filas afectadas
CREATE TABLE b ( aid INT, bid INT PRIMARY KEY, CONSTRAINT [My_FORIEGN_KEY] FOREIGN KEY (aid) REFERENCES a (aid) ) ;
VAMOS
✓
INSERT INTO b (aid, bid) VALUES (1, 11), (1, 12), (2, 21), (3, 31) ;
VAMOS
4 filas afectadas
INSERT INTO b (aid, bid) VALUES (6, 61), (6, 62) ;
VAMOS
Msg 547 Nivel 16 Estado 0 Línea 1 La instrucción INSERT entró en conflicto con la restricción FOREIGN KEY "My_FORIEGN_KEY". El conflicto se produjo en la base de datos "fiddle_792fce5de09f42908c3a0f91421f3522", tabla "dbo.a", columna 'ayuda'. Msg 3621 Nivel 0 Estado 0 Línea 1 La instrucción se ha terminado.
SELECT * FROM b ;
VAMOS
ayuda | oferta -: | -: 1 | 11 1 | 12 2 | 21 3 | 31
ALTER TABLE b NOCHECK CONSTRAINT [My_FORIEGN_KEY]; --disable
VAMOS
✓
INSERT INTO b (aid, bid) VALUES (4, 41), (4, 42) ;
VAMOS
2 filas afectadas
SELECT * FROM b ;
VAMOS
ayuda | oferta -: | -: 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
VAMOS
✓
SELECT * FROM b ;
VAMOS
ayuda | oferta -: | -: 1 | 11 1 | 12 2 | 21 3 | 31 4 | 41 4 | 42
INSERT INTO b (aid, bid) VALUES (6, 61), (6, 62) ;
VAMOS
Msg 547 Nivel 16 Estado 0 Línea 1 La instrucción INSERT entró en conflicto con la restricción FOREIGN KEY "My_FORIEGN_KEY". El conflicto se produjo en la base de datos "fiddle_792fce5de09f42908c3a0f91421f3522", tabla "dbo.a", columna 'ayuda'. Msg 3621 Nivel 0 Estado 0 Línea 1 La instrucción se ha terminado.
SELECT * FROM b ;
VAMOS
ayuda | oferta -: | -: 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
VAMOS
Msg 547 Nivel 16 Estado 0 Línea 1 La instrucción ALTER TABLE entró en conflicto con la restricción FOREIGN KEY "My_FORIEGN_KEY". El conflicto se produjo en la base de datos "fiddle_792fce5de09f42908c3a0f91421f3522", tabla "dbo.a", columna 'ayuda'.
Considere leer el artículo aquí: https://msdn.microsoft.com/en-us/library/ms190273.aspx
Nos dice: 'El optimizador de consultas no considera las restricciones que se definen CON NOCHECK. Dichas restricciones se ignoran hasta que se vuelven a habilitar utilizando la tabla ALTER TABLE WITH CHECK CHECK CONSTRAINT ALL '
Además, considere este hilo en 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
, ¿significará esto que la restricción no verificará los datos existentes, solo los nuevos datos entrantes?