Puede ejecutar DBCC CHECKCONSTRAINTS
comando de consola para devolver una lista de todas las violaciones de restricciones en una base de datos de SQL Server.
Este comando verifica la integridad de una restricción específica o todas las restricciones en una tabla específica en la base de datos actual. Devuelve cualquier clave foránea y CHECK
violaciones de restricciones que encuentra.
Puedes usar las ALL_CONSTRAINTS
opción para verificar las restricciones habilitadas y deshabilitadas. Si omite esto, solo se devolverán las restricciones habilitadas (a menos que especifique explícitamente una restricción para verificar, en cuyo caso se devolverá independientemente de si está habilitada o deshabilitada).
Ejemplo 1:restricciones CHECK violadas
Ejecuté este ejemplo en una base de datos que contiene algo de CHECK
violaciones de restricciones.
USE Test; DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
Resultado:
+------------------------+-------------------+---------------------------------------------------------+ | Table | Constraint | Where | |------------------------+-------------------+---------------------------------------------------------| | [dbo].[Occupation] | [chkJobTitle] | [JobTitle] = 'Digital Nomad' | | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' | | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' | +------------------------+-------------------+---------------------------------------------------------+
Esto muestra que tengo tres violaciones de restricciones en mi base de datos.
Explicación de las Columnas
Las tres columnas devuelven la siguiente información:
- Mesa
- Nombre del nombre de la tabla que contiene la violación de la restricción.
- Restricción
- Nombre de la restricción que se viola.
- Dónde
- Asignaciones de valores de columna que identifican la fila o filas que violan la restricción. El valor de esta columna se puede utilizar en un
WHERE
cláusula de unSELECT
declaración que consulta filas que violan la restricción.
Por lo tanto, gracias a la tercera columna, ahora puedo encontrar (y actualizar) todos los datos no válidos.
Encuentra los datos no válidos
Entonces, si miramos la primera fila de mi DBCC CHECKCONSTRAINTS
resultados, vemos que podemos encontrar los datos ofensivos usando [JobTitle] = 'Digital Nomad'
en un WHERE
cláusula.
Así:
SELECT * FROM [dbo].[Occupation] WHERE [JobTitle] = 'Digital Nomad';
Resultado:
+----------------+---------------+ | OccupationId | JobTitle | |----------------+---------------| | 7 | Digital Nomad | +----------------+---------------+
La definición de restricción
Echemos un vistazo a la definición real de chkJobTitle
restricción:
SELECT Definition FROM sys.check_constraints WHERE name = 'chkJobTitle';
Resultado:
+-------------------------------+ | Definition | |-------------------------------| | ([JobTitle]<>'Digital Nomad') | +-------------------------------+
Esta restricción dice que el valor de JobTitle la columna debe no sé nómada digital , ¡sin embargo, un nómada digital logró ingresar a mi base de datos!
Actualizar los datos ofensivos
Puede actualizar los datos ofensivos, eliminarlos o dejarlos solos.
En este ejemplo utilizo el mismo WHERE
cláusula para actualizar el valor:
UPDATE [dbo].[Occupation] SET [JobTitle] = 'Unemployed' WHERE [JobTitle] = 'Digital Nomad';
Ahora, si vuelvo a ejecutar la verificación, ese registro ya no es un problema y solo quedan los otros dos problemas:
DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
Resultado:
+------------------------+-------------------+---------------------------------------------------------+ | Table | Constraint | Where | |------------------------+-------------------+---------------------------------------------------------| | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' | | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' | +------------------------+-------------------+---------------------------------------------------------+
Ejemplo 2:restricciones de clave externa violadas
En este ejemplo, cambio a una base de datos que contiene un par de violaciones de restricciones de clave externa.
USE Music; DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
Resultado:
+----------------+---------------------+--------------------+ | Table | Constraint | Where | |----------------+---------------------+--------------------| | [dbo].[Albums] | [FK_Albums_Artists] | [ArtistId] = '123' | | [dbo].[Albums] | [FK_Albums_Artists] | [ArtistId] = '17' | +----------------+---------------------+--------------------+
En este caso, parece que dos filas en Álbumes la tabla hace referencia a un ArtistId eso no existe.
Encuentra los datos no válidos
Nuevamente, podemos usar el
Dónde
columna para construir nuestro WHERE
cláusula. Esta vez agregaré ambas violaciones a mi WHERE
cláusula:
SELECT * FROM [dbo].[Albums] WHERE [ArtistId] = '123' OR [ArtistId] = '17';
Resultado:
+-----------+-------------+---------------+------------+-----------+ | AlbumId | AlbumName | ReleaseDate | ArtistId | GenreId | |-----------+-------------+---------------+------------+-----------| | 21 | Yo Wassup | 2019-03-12 | 17 | 3 | | 22 | Busted | 1901-05-11 | 123 | 3 | +-----------+-------------+---------------+------------+-----------+
Así que ahora podemos ver las dos filas que violan la restricción (aunque es solo el ArtistId columna que viola la restricción).
Consulte la tabla de claves principales
Podemos confirmar la infracción consultando a los Artistas tabla (es decir, la tabla que contiene la clave principal para esta clave externa).
Así que ejecutemos la misma consulta contra los Artistas mesa.
SELECT * FROM [dbo].[Artists] WHERE [ArtistId] = '123' OR [ArtistId] = '17';
Resultado:
(0 rows affected)
Como era de esperar, ningún valor está en esa tabla.
Se supone que la clave externa evita que esto suceda. Los datos no válidos ingresaron a la base de datos mientras la clave externa estaba deshabilitada o ingresaron antes de que se creara la clave externa. De cualquier manera, al crear o habilitar una clave externa o CHECK
restricción, debe usar WITH CHECK
para especificar que todos los datos existentes deben verificarse antes de habilitar la restricción.
Ejemplo 3:marcar solo las restricciones habilitadas
Si solo desea verificar las restricciones que están actualmente habilitadas, elimine WITH ALL_CONSTRAINTS
:
USE Test; DBCC CHECKCONSTRAINTS;
Resultado:
+--------------------+---------------+------------------------------+ | Table | Constraint | Where | |--------------------+---------------+------------------------------| | [dbo].[Occupation] | [chkJobTitle] | [JobTitle] = 'Digital Nomad' | +--------------------+---------------+------------------------------+
Entonces, de las dos restricciones que se violaron, parece que chkJobTitle es el único que estaba habilitado.
Podemos verificar esto aún más con la siguiente consulta:
SELECT name, is_disabled FROM sys.check_constraints WHERE name = 'chkValidEndDate' OR name = 'chkJobTitle';
Resultado:
+-----------------+---------------+ | name | is_disabled | |-----------------+---------------| | chkJobTitle | 0 | | chkValidEndDate | 1 | +-----------------+---------------+
Ejemplo 4:verificar solo las restricciones para una tabla determinada
Puede agregar el nombre de una tabla entre paréntesis si solo desea verificar las restricciones de esa tabla:
USE Test; DBCC CHECKCONSTRAINTS(ConstraintTest) WITH ALL_CONSTRAINTS;
Resultado:
+------------------------+-------------------+---------------------------------------------------------+ | Table | Constraint | Where | |------------------------+-------------------+---------------------------------------------------------| | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' | | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' | +------------------------+-------------------+---------------------------------------------------------+
Ejemplo 5:Comprobar una sola restricción
Puede comprobar una sola restricción encerrando su nombre entre paréntesis:
USE Test; DBCC CHECKCONSTRAINTS(chkValidEndDate);
Resultado:
+------------------------+-------------------+---------------------------------------------------------+ | Table | Constraint | Where | |------------------------+-------------------+---------------------------------------------------------| | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' | | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' | +------------------------+-------------------+---------------------------------------------------------+
Cuando especifica una única restricción, el WITH ALL_CONSTRAINTS
no tiene efecto:
USE Test; DBCC CHECKCONSTRAINTS(chkValidEndDate) WITH ALL_CONSTRAINTS;
Resultado:
+------------------------+-------------------+---------------------------------------------------------+ | Table | Constraint | Where | |------------------------+-------------------+---------------------------------------------------------| | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' | | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' | +------------------------+-------------------+---------------------------------------------------------+