Cuando creas un CHECK
restricción en SQL Server, es posible que ni siquiera piense si se trata de una restricción a nivel de tabla o una restricción a nivel de columna.
Un CHECK
a nivel de tabla la restricción se aplica a la tabla, mientras que una restricción a nivel de columna se aplica a una columna específica. Con un CHECK
a nivel de tabla restricción, es la fila que se verifica cuando verifica los datos. Con un CHECK
a nivel de columna restricción, es la columna específica la que está marcada.
Por lo general, sabrá si la restricción que está creando es una restricción de nivel de tabla o de columna por la definición que le dé. Si solo se verifica una columna en la expresión, será una restricción de nivel de columna. De lo contrario, será una restricción a nivel de tabla.
Pero, ¿cómo sabe si sus restricciones existentes son de nivel de columna o de tabla?
Puede ejecutar cualquiera de los ejemplos de código a continuación para determinar si sus restricciones existentes son de nivel de columna o de tabla. Estos recuperan todos los CHECK
restricciones para la base de datos actual, pero siempre puede usar un WHERE
cláusula para reducirla a una restricción específica.
Ejemplo 1:consulta básica
Aquí hay una consulta simple que devuelve información básica sobre todos los CHECK
restricciones en la base de datos actual.
Aquí, consulto el sys.check_constraints
vista del sistema (que devuelve una fila para cada objeto que es un CHECK
restricción, con sys.objects.type = 'C'
). Solo devuelvo cuatro columnas (pero siéntete libre de devolver tantas columnas como quieras).
SELECT Name, OBJECT_NAME(parent_object_id) AS 'Table', parent_column_id, Definition FROM sys.check_constraints;
Resultado:
+-----------------+----------------+--------------------+----------------------------------------+ | Name | Table | parent_column_id | Definition | |-----------------+----------------+--------------------+----------------------------------------| | chkPrice | ConstraintTest | 2 | ([Price]>(0)) | | chkValidEndDate | ConstraintTest | 0 | ([EndDate]>=[StartDate]) | | chkTeamSize | ConstraintTest | 3 | ([TeamSize]>=(5) AND [TeamSize]<=(20)) | | chkJobTitle | Occupation | 3 | ([JobTitle]<>'Digital Nomad') | +-----------------+----------------+--------------------+----------------------------------------+
La forma más rápida de determinar qué restricciones son restricciones de nivel de tabla es buscar el cero (
0
) en el
parent_column_id
columna. Cualquier cosa con un cero es un CHECK
de nivel de tabla restricción. Un valor distinto de cero indica que es un CHECK
de nivel de columna restricción definida en la columna con el valor de ID especificado.
Entonces, en este ejemplo, hay tres restricciones a nivel de columna y una restricción a nivel de tabla.
Tenga en cuenta que hay dos restricciones con el mismo parent_column_id (3), sin embargo, estas dos restricciones son de diferentes tablas. El 3 hace referencia a la tercera columna de sus respectivas tablas.
Como se mencionó, si solo desea información sobre una restricción específica, use un WHERE
cláusula:
SELECT Name, OBJECT_NAME(parent_object_id) AS 'Table', parent_column_id, Definition FROM sys.check_constraints WHERE name = 'chkPrice';
Resultado:
+----------+----------------+--------------------+---------------+ | Name | Table | parent_column_id | Definition | |----------+----------------+--------------------+---------------| | chkPrice | ConstraintTest | 2 | ([Price]>(0)) | +----------+----------------+--------------------+---------------+
Ejemplo 2:mejorar la consulta
Podemos mejorar el ejemplo anterior devolviendo el nombre de la columna principal en lugar de solo su ID. Por supuesto, esto devolverá el nombre de la columna solo para las restricciones de nivel de columna. Para restricciones a nivel de tabla, se devolverá NULL.
SELECT cc.name AS 'Constraint', o.name AS 'Table', ac.name AS 'Column', cc.Definition AS 'Constraint Definition' FROM sys.check_constraints cc LEFT OUTER JOIN sys.objects o ON cc.parent_object_id = o.object_id LEFT OUTER JOIN sys.all_columns ac ON cc.parent_column_id = ac.column_id AND cc.parent_object_id = ac.object_id;
Resultado:
+-----------------+----------------+----------+----------------------------------------+ | Constraint | Table | Column | Constraint Definition | |-----------------+----------------+----------+----------------------------------------| | chkPrice | ConstraintTest | Price | ([Price]>(0)) | | chkValidEndDate | ConstraintTest | NULL | ([EndDate]>=[StartDate]) | | chkTeamSize | ConstraintTest | TeamSize | ([TeamSize]>=(5) AND [TeamSize]<=(20)) | | chkJobTitle | Occupation | JobTitle | ([JobTitle]<>'Digital Nomad') | +-----------------+----------------+----------+----------------------------------------+
Ejemplo 3:mejoras adicionales
Modifiquemos la consulta un poco más:
SELECT cc.name AS 'Constraint', cc.is_disabled AS 'Disabled?', CASE WHEN cc.parent_column_id = 0 THEN 'Table-level' ELSE 'Column-level' END AS 'Table/Column', o.name AS 'Table', ISNULL(ac.name, '(n/a)') AS 'Column', cc.Definition AS 'Constraint Definition' FROM sys.check_constraints cc LEFT OUTER JOIN sys.objects o ON cc.parent_object_id = o.object_id LEFT OUTER JOIN sys.all_columns ac ON cc.parent_column_id = ac.column_id AND cc.parent_object_id = ac.object_id;
Resultado:
+-----------------+-------------+----------------+----------------+----------+----------------------------------------+ | Constraint | Disabled? | Table/Column | Table | Column | Constraint Definition | |-----------------+-------------+----------------+----------------+----------+----------------------------------------| | chkPrice | 0 | Column-level | ConstraintTest | Price | ([Price]>(0)) | | chkValidEndDate | 0 | Table-level | ConstraintTest | (n/a) | ([EndDate]>=[StartDate]) | | chkTeamSize | 0 | Column-level | ConstraintTest | TeamSize | ([TeamSize]>=(5) AND [TeamSize]<=(20)) | | chkJobTitle | 0 | Column-level | Occupation | JobTitle | ([JobTitle]<>'Digital Nomad') | +-----------------+-------------+----------------+----------------+----------+----------------------------------------+
Así que ahora tengo el texto "Nivel de columna" o "Nivel de tabla", dependiendo de cuál sea.
También uso el ISNULL()
función para convertir cualquier valor NULL en "(n/a)".
Y también agregué is_disabled columna a la lista, en caso de que alguna de las restricciones haya sido deshabilitada. Siempre puede darle a esta columna el mismo tratamiento que a parent_column_id y presente "Sí" o "No" o "Habilitado" o "Deshabilitado" o similar.