La página de documentación de MSDN ALTER TABLE
explica esto:
ALTER TABLE
: modifica la estructura de la tabla
(y algunas de las posibles acciones / modificaciones son):
CHECK CONSTRAINT ..
: habilitar la restricción
NOCHECK CONSTRAINT ..
: deshabilitar la restricción
También hay pasos opcionales adicionales que se deben realizar al crear / habilitar / deshabilitar una restricción:
WITH CHECK
: compruebe la restricción también
WITH NOCHECK
: no verifique la restricción
En 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ón FOREIGN KEY
o CHECK
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
o FOREIGN KEY
restricciones contra los datos existentes, use WITH 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 suprima WITH 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 la ALTER TABLE
tabla WITH CHECK CHECK CONSTRAINT ALL
.
...
{ CHECK | NOCHECK } CONSTRAINT
Especifica que restricint_name está habilitado o deshabilitado. Esta opción solo se puede usar con FOREIGN KEY
y CHECK
restricciones. Cuando NOCHECK
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
Y UNIQUE
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'.
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?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
fuente