No SQL Server você pode criar um
CHECK
restrição em uma tabela para especificar os valores de dados que são aceitáveis em uma ou mais colunas. Se uma tabela tiver um
CHECK
restrição sobre ele, e você tenta fornecer dados que não estão de acordo com o CHECK
restrição, a operação falhará com um erro. Isso ajuda a manter a integridade dos dados, pois ajuda a evitar que dados inválidos entrem no banco de dados.
Quando você cria um
CHECK
restrição, você fornece uma expressão lógica que retorna TRUE
ou FALSE
. Essa expressão lógica é o que é usado para verificar os dados. CHECK
As restrições são semelhantes às restrições de chave estrangeira porque controlam os valores que são colocados em uma coluna. No entanto, a diferença está em como eles determinam quais valores são válidos:restrições de chave estrangeira obtêm a lista de valores válidos de outra tabela, enquanto CHECK
restrições determinam os valores válidos de uma expressão lógica. As restrições podem ser definidas no nível da coluna ou da tabela. Uma restrição de nível de coluna se aplica apenas aos dados dessa coluna. Uma restrição de nível de tabela se aplica a toda a linha e verifica os dados de várias colunas.
Abaixo estão exemplos de criação de nível de coluna e de tabela
CHECK
restrições. Exemplo 1 – Criar uma restrição CHECK em nível de coluna
Aqui está um exemplo de criação de um
CHECK
básico em nível de coluna restrição no momento da criação de uma tabela. CREATE TABLE ConstraintTest ( ConstraintTestId int IDENTITY(1,1) NOT NULL PRIMARY KEY, Price smallmoney NOT NULL, CONSTRAINT chkPrice CHECK (Price > 0) );
Neste caso, o
CHECK
restrição especifica que todos os dados no Price
coluna deve ser maior que 0. Em outras palavras, o preço não pode ser zero e não pode ser negativo. Essa é uma restrição de nível de coluna porque se aplica a dados em uma coluna. Como essa é uma restrição de nível de coluna, eu poderia tê-la definido como parte da coluna (sem a vírgula). Então eu poderia ter feito isso:
CREATE TABLE ConstraintTest ( ConstraintTestId int IDENTITY(1,1) NOT NULL PRIMARY KEY, Price smallmoney NOT NULL CONSTRAINT chkPrice CHECK (Price > 0) );
De qualquer forma, vamos tentar inserir um valor inválido:
INSERT INTO ConstraintTest ( Price ) VALUES ( 0 );
Resultado:
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkPrice". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'Price'.
Exemplo 2 - Adicionar mais colunas e outra restrição CHECK em nível de coluna
Vamos adicionar mais algumas colunas à nossa tabela e, em seguida, adicionar outro nível de coluna
CHECK
limitação. ALTER TABLE ConstraintTest ADD TeamSize tinyint NOT NULL, StartDate date NOT NULL, EndDate date NOT NULL, CONSTRAINT chkTeamSize CHECK (TeamSize >= 3 AND TeamSize <= 15) ;
Uma das novas colunas registra o número de membros da equipe. Nesse caso, a regra de negócio é que uma equipe deve ter pelo menos 3 membros, mas não mais que 15. Portanto, o banco de dados deve evitar a situação em que uma equipe tenha menos de 3 membros ou mais de 15.
Vamos tentar inserir um valor inválido:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 2, '2020-01-01', '1900-02-02' );
Resultado:
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkTeamSize". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'TeamSize'.
Exemplo 3 - Adicionar uma restrição CHECK em nível de tabela
Agora vamos adicionar uma restrição de nível de tabela. Isso verificará os dados em duas colunas.
A propósito, você não precisa adicionar outra coluna para adicionar um
CHECK
limitação. Você pode simplesmente adicionar a restrição por si só. Exemplo:
ALTER TABLE ConstraintTest ADD CONSTRAINT chkValidEndDate CHECK (EndDate >= StartDate) ;
Nesse caso, adiciono uma restrição para garantir que a data de término nunca seja anterior à data de início. Isso está verificando dados em duas colunas e, portanto, é uma restrição de nível de tabela.
Tente inserir um valor inválido:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 3, '2020-01-01', '1900-02-02' );
Resultado:
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkValidEndDate". The conflict occurred in database "Test", table "dbo.ConstraintTest".
Observe que, para testar essa restrição, tive que aumentar os membros da equipe para 3 para evitar que a restrição anterior fosse acionada primeiro (
CHECK
restrições são validadas na ordem em que são criadas). Exemplo 4 – Alterar uma restrição CHECK
Você não pode alterar um
CHECK
limitação. Se você precisar alterá-lo, precisará soltá-lo e criá-lo com a nova definição. Exemplo:
ALTER TABLE ConstraintTest DROP CONSTRAINT chkTeamSize; ALTER TABLE ConstraintTest ADD CONSTRAINT chkTeamSize CHECK (TeamSize >= 5 AND TeamSize <= 20) ;
Como mencionado,
CHECK
as restrições são validadas na ordem em que são criadas, portanto, isso pode afetar qual erro é detectado primeiro. Portanto, neste caso, se eu tentar inserir um valor inválido (e também incluir datas inválidas), as datas inválidas serão capturadas primeiro:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 4, '2020-01-01', '1900-02-02' );
Resultado:
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkValidEndDate". The conflict occurred in database "Test", table "dbo.ConstraintTest".
Portanto, para verificar minha restrição mais recente, precisarei corrigir o problema de data primeiro:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 4, '2020-01-01', '2020-02-02' );
Resultado:
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkTeamSize". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'TeamSize'.
Portanto, minha última restrição está funcionando conforme o esperado.
Exemplo 5 – VERIFICAR Restrições e Colunas de IDENTIDADE
Agora que testamos as restrições, vamos em frente e inserir dados válidos:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 5, '2020-01-01', '2020-02-02' );
Resultado:
+--------------------+---------+------------+-------------+------------+ | ConstraintTestId | Price | TeamSize | StartDate | EndDate | |--------------------+---------+------------+-------------+------------| | 13 | 1.0000 | 5 | 2020-01-01 | 2020-02-02 | +--------------------+---------+------------+-------------+------------+
Finalmente, obtemos uma inserção bem-sucedida.
No entanto, você notará que a
IDENTITY
coluna já foi incrementada para 13. Lembre-se quando criei a tabela pela primeira vez, defini o
ConstraintTestId
coluna para usar IDENTITY(1,1)
, o que significa que deve começar em 1 e incrementar automaticamente em 1 com cada inserção de linha. Mas agora que finalmente inseri minha primeira linha, o valor já é 13. Isso porque a
IDENTITY
coluna é incrementada mesmo quando um CHECK
restrição faz com que o INSERT
operação falhar. Observe que eu fiz algumas inserções extras com falha enquanto criava os exemplos para este artigo, então o valor foi incrementado para um valor mais alto do que o que você obterá se você simplesmente seguir passo a passo este artigo.
De qualquer forma, vamos fazer uma última inserção com falha e, em seguida, uma bem-sucedida para confirmar isso.
Falha na inserção:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 2, 4, '2020-01-02', '2020-02-03' );
Resultado:
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkTeamSize". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'TeamSize'.
Inserção bem-sucedida:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 2, 6, '2020-01-02', '2020-02-03' ); SELECT * FROM ConstraintTest;
Resultado:
+--------------------+---------+------------+-------------+------------+ | ConstraintTestId | Price | TeamSize | StartDate | EndDate | |--------------------+---------+------------+-------------+------------| | 13 | 1.0000 | 5 | 2020-01-01 | 2020-02-02 | | 15 | 2.0000 | 6 | 2020-01-02 | 2020-02-03 | +--------------------+---------+------------+-------------+------------+
Podemos ver que a
IDENTITY
A coluna salta de 13 para 15, então obviamente é incrementada durante a inserção com falha. Algumas restrições das restrições CHECK
Aqui estão algumas restrições a serem observadas ao trabalhar com
CHECK
restrições:- A condição de pesquisa deve ser avaliada como uma expressão booleana e não pode fazer referência a outra tabela.
- A expressão não pode conter tipos de dados de alias.
CHECK
restrições não podem ser definidas em texto , ntext , ou imagem colunas.