sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo habilitar una restricción de clave externa en SQL Server (ejemplos de T-SQL)

Si tiene una restricción de clave externa en SQL Server que actualmente está deshabilitada, puede usar el siguiente código para volver a habilitarla.

Cuando habilita una restricción de clave externa, tiene la opción de especificar si desea verificar o no los datos existentes en la tabla. Esto también se aplica cuando habilita un CHECK restricción.

A continuación se muestran ejemplos de código para habilitar una restricción de clave externa, mientras se especifica cada una de estas diferentes opciones.

Ejemplo 1:habilite una restricción con WITH CHECK

Este es el método recomendado (a menos que tenga una razón específica para no usarlo).

Aquí hay un ejemplo de cómo habilitar una restricción de clave externa llamada FK_Albums_Artists :

ALTER TABLE Albums 
WITH CHECK CHECK CONSTRAINT FK_Albums_Artists; 

Aquí declaro explícitamente WITH CHECK , que le dice a SQL Server que verifique los datos existentes antes de habilitar la restricción. Si algún dato viola la restricción, la restricción no se habilitará y obtendrá un error.

Esto es bueno porque refuerza la integridad referencial.

Cuando crea una nueva restricción de clave externa, esta es la configuración predeterminada. Sin embargo, cuando habilita una restricción existente (como lo estamos haciendo aquí), no la configuración predeterminada.

Ejemplo 2:habilitar una restricción con WITH NOCHECK

En este ejemplo, la restricción se habilita sin verificar los datos existentes:

ALTER TABLE Albums 
WITH NOCHECK CHECK CONSTRAINT FK_Albums_Artists;

Aquí declaro explícitamente WITH NOCHECK , que le dice a SQL Server que no verifique los datos existentes. Esto significa que la restricción se habilitará incluso si la tabla ya contiene datos que violan la restricción.

Esta es la configuración predeterminada cuando se habilita una restricción (pero no cuando se crea una).

Una de las pocas razones (probablemente la única razón) por la que usaría esto es si desea mantener datos no válidos en la base de datos. Tal vez tenga una excepción única en la que debe ingresar una fila o más de datos no válidos, pero requiere que todos los datos futuros se ajusten a la restricción.

Sin embargo, todavía hay riesgos asociados con hacer esto. Esto es lo que Microsoft tiene que decir al respecto:

No recomendamos hacer esto, excepto en casos excepcionales. La nueva restricción se evalúa en todas las actualizaciones de datos posteriores. Cualquier infracción de restricción suprimida por WITH NOCHECK cuando se agrega la restricción, es posible que las actualizaciones futuras fallen si actualizan las filas con datos que no siguen la restricción.

Entonces usando WITH NOCHECK podría causar problemas más adelante.

Ejemplo 3:habilitar una restricción con la opción predeterminada

Aquí hay un ejemplo usando la opción predeterminada:

ALTER TABLE Albums 
CHECK CONSTRAINT FK_Albums_Artists;

Este ejemplo es el equivalente del ejemplo anterior. Debido a que no especifiqué si verificar o no, SQL Server asume que quiero WITH NOCHECK .

Así que asegúrese de especificar explícitamente WITH CHECK si desea evitar problemas de integridad referencial.

Usar WITH NOCHECK elimina la confianza

Cuando habilita una restricción usando (el valor predeterminado) WITH NOCHECK , una consecuencia que debe tener en cuenta es que SQL Server ya no confiará en esa restricción. Lo marca como no confiable. En realidad, ya está marcado como no confiable cuando deshabilita la restricción.

SQL Server tiene un is_not_trusted marca que se establece en 1 cuando deshabilita una restricción de clave externa (lo que significa que no es de confianza), y la única forma de establecerla en 0 (de confianza) es especificar WITH CHECK al volver a habilitar la restricción. Por otro lado, usando WITH NOCHECK simplemente lo habilita sin verificar los datos existentes.

Usando WITH CHECK , se asegura de que la restricción compruebe todos los datos existentes antes de habilitarla. La única forma en que se puede habilitar es si todos los datos existentes se ajustan a la restricción. Una vez que haya verificado todos los datos existentes, se puede confiar en la restricción.

Ejemplo 4:verificar el estado de confianza/deshabilitado

Puede verificar el estado de confianza y deshabilitado consultando sys.foreign_keys vista del sistema.

Así:

SELECT 
  name AS 'Constraint',
  is_disabled,
  is_not_trusted
FROM sys.foreign_keys;

Resultado:

+-------------------+---------------+------------------+
| Constraint        | is_disabled   | is_not_trusted   |
|-------------------+---------------+------------------|
| FK_Albums_Artists | 0             | 1                |
| FK_Albums_Genres  | 0             | 0                |
+-------------------+---------------+------------------+

Esto me dice que la restricción que habilité en el ejemplo anterior ( FK_Albums_Artists ) no es de confianza.

Esto se debe a que lo habilité usando la configuración predeterminada, que es WITH NOCHECK .

Si lo vuelvo a habilitar usando WITH CHECK , esto es lo que sucede:

ALTER TABLE Albums 
WITH CHECK CHECK CONSTRAINT FK_Albums_Artists;

SELECT 
  name AS 'Constraint',
  is_disabled,
  is_not_trusted
FROM sys.foreign_keys;

Resultado:

+-------------------+---------------+------------------+
| Constraint        | is_disabled   | is_not_trusted   |
|-------------------+---------------+------------------|
| FK_Albums_Artists | 0             | 0                |
| FK_Albums_Genres  | 0             | 0                |
+-------------------+---------------+------------------+

Afortunadamente, en este caso no tenía ningún dato que violara la restricción, por lo que la restricción se habilitó con éxito y se restauró su confianza.

Si hubiera datos que violaran la restricción, se mostraría un error y me vería obligado a corregir los datos antes de poder restaurar la confianza en la restricción.