Quando você cria um
CHECK
restrição no SQL Server, você pode nem pensar se é uma restrição de nível de tabela ou uma restrição de nível de coluna. Um
CHECK
no nível da tabela restrição se aplica à tabela, enquanto uma restrição de nível de coluna se aplica a uma coluna específica. Com um CHECK
no nível da tabela restrição, é a linha que é verificada quando verifica os dados. Com um CHECK
no nível da coluna restrição, é a coluna específica que é verificada. Geralmente, você saberá se a restrição que está criando é uma restrição de nível de tabela ou de coluna pela definição que você der. Se apenas uma coluna estiver sendo verificada na expressão, será uma restrição de nível de coluna. Caso contrário, será uma restrição de nível de tabela.
Mas como você sabe se suas restrições existentes são em nível de coluna ou em nível de tabela?
Você pode executar qualquer um dos exemplos de código abaixo para determinar se suas restrições existentes são em nível de coluna ou em nível de tabela. Estes recuperam todos os
CHECK
restrições para o banco de dados atual, mas você sempre pode usar um WHERE
cláusula para reduzi-lo a uma restrição específica. Exemplo 1 – Consulta básica
Aqui está uma consulta simples que retorna informações básicas sobre todos os
CHECK
restrições no banco de dados atual. Aqui, eu consulto as
sys.check_constraints
visão do sistema (que retorna uma linha para cada objeto que é um CHECK
restrição, com sys.objects.type = 'C'
). Eu só retorno quatro colunas (mas sinta-se à vontade para retornar quantas colunas quiser). 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') | +-----------------+----------------+--------------------+----------------------------------------+
A maneira mais rápida de determinar quais restrições são restrições de nível de tabela é procurar o zero ( 0 ) no parent_column_id coluna. Qualquer coisa com zero é um
CHECK
no nível da tabela limitação. Um valor diferente de zero indica que é um CHECK
no nível da coluna restrição definida na coluna com o valor de ID especificado. Portanto, neste exemplo, há três restrições em nível de coluna e uma restrição em nível de tabela.
Observe que há duas restrições com o mesmo parent_column_id (3), no entanto, essas duas restrições são de tabelas diferentes. O 3 refere-se à terceira coluna de suas respectivas tabelas.
Como mencionado, se você deseja apenas informações sobre uma restrição específica, use um
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)) | +----------+----------------+--------------------+---------------+
Exemplo 2 – Melhorar a consulta
Podemos melhorar o exemplo anterior retornando o nome da coluna pai em vez de apenas seu ID. Obviamente, isso retornará o nome da coluna apenas para restrições de nível de coluna. Para restrições de nível de tabela, NULL será retornado.
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') | +-----------------+----------------+----------+----------------------------------------+
Exemplo 3 – Melhorias adicionais
Vamos ajustar a consulta um pouco mais:
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') | +-----------------+-------------+----------------+----------------+----------+----------------------------------------+
Portanto, agora tenho o texto “Nível da coluna” ou “Nível da tabela” sendo retornado, dependendo de qual seja.
Eu também uso o
ISNULL()
função para transformar qualquer valor NULL em “(n/a)”. E também adicionei o is_disabled coluna à lista, caso alguma das restrições tenha sido desativada. Você sempre pode dar a esta coluna o mesmo tratamento que o parent_column_id coluna e apresentar “Sim” ou “Não” ou “Ativado” ou “Desativado” ou similar.