Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

VERIFICAR Restrições no SQL Server


Neste artigo, falaremos sobre as restrições CHECK. Veremos como adicionar restrições CHECK às colunas da tabela do SQL Server e discutiremos as armadilhas que você pode encontrar ao usar esse tipo de restrição do SQL Server.

VERIFICAR noções básicas de restrição


As restrições CHECK são simplesmente instruções condicionais (predicados que retornam TRUE ou FALSE) que se referem às colunas da tabela para manter a integridade dos dados. Quando se insere dados em uma coluna ou várias colunas em uma única linha, as restrições CHECK entram em ação. Eles avaliam os dados a serem inseridos. Caso os dados não atendam à condição especificada na restrição CHECK, a inserção falha.


Considere o seguinte exemplo:

É necessário definir uma restrição para a coluna Salário para que ela armazene apenas valores positivos que não excedam US$ 150.000. A instrução condicional terá a seguinte aparência:(Salary>=0 e Salário <=150.000). Ao tentar inserir valores negativos, o predicado resultará em FALSE e a inserção falhará.

É possível adicionar uma restrição CHECK a uma ou várias colunas. A adição de uma restrição CHECK de várias colunas pode ser implementada no nível da tabela.

Trabalhando com restrições CHECK

Como criar restrições CHECK no SSMS

  1. No Explorador de Objetos , navegue até uma tabela necessária.

  2. Clique com o botão direito do mouse nas Restrições pasta e, em seguida, c lick Nova restrição…

  3. No painel direito de Verificar restrições caixa de diálogo, clique em Expressão e, em seguida, clique no botão de reticências.

  1. Digite uma expressão de restrição CHECK no campo de texto da Expressão de restrição Check caixa de diálogo. Por exemplo, para permitir apenas códigos postais de sete dígitos em uma coluna CEP, a expressão pode ter a seguinte aparência:


No Designer de tabela seção, você pode configurar as regras para impor a restrição.


CHECK Restrição em CREATE TABLE

Considere o seguinte exemplo:

É necessário criar uma tabela que armazene os dados dos clientes do banco e preencha-a com os dados de teste. A tabela incluirá as seguintes colunas:ID do cliente, Nome, Sobrenome, Status, Telefone, Cidade, Estado e CEP.

Ao desenvolver a tabela, devemos levar em consideração os seguintes fatos:

  1. O formato ZIP básico consiste em cinco dígitos numéricos.

  2. O número de telefone americano padrão tem dez dígitos, como (555) 555-1234

  3. As ​​abreviações de duas letras são usadas para representar as divisões políticas dos Estados Unidos para endereços postais, processamento de dados, abreviações gerais e outros fins.

A tarefa é fornecer consistência de dados para a tabela. É necessário proibir a inserção de números de telefone de 12 dígitos e zips de 6 dígitos etc. Para fazer isso, o SQL Server permite adicionar uma ou mais restrições CHECK para cada coluna da tabela.

Na seção anterior, examinamos a única maneira de criar uma restrição CHECK no SSMS. Agora, discutiremos como criar a restrição com a ajuda do T-SQL.

O script a seguir mostra como criar uma restrição CHECK na coluna Zip:

CREATE TABLE Customers
(
 Customer_Id tinyint NOT NULL,
 [First Name] varchar(50),
 [Last Name] varchar(50),
 Status varchar(50),
 Phone tinyint,
 Address varchar(50),
 State varchar(50),
 Zip tinyint,
 Email varchar(50),
 [Credit Limit] INT NULL,
 CONSTRAINT CK_Zip CHECK (Zip LIKE REPLICATE ('[0-9]', 5)) --Check Constraint Condition
)

Agora, vamos ver o que obtemos ao tentar inserir um valor de 6 dígitos na coluna Zip:

INSERT INTO dbo.Customers (Customer_Id, [First Name], [Last Name], Status, Phone, Address, State, Zip, Email)
SELECT 1, 'James', 'Madison', 'Mr', 555-555-1234, 'Madison street, 12', 'LA', 123456, NULL
GO

A inserção falha e o SQL Server exibe a seguinte prevenção:


Até agora, tudo bem.

Expressão CASE na restrição CHECK

Suponha que o banco tenha uma regra de negócios para definir o limite de crédito para os residentes do estado da Louisiana abaixo de US$ 150.000. Implementaremos esse requisito adicionando uma restrição CHECK à coluna Credit Limit:

ALTER TABLE dbo.Customers
ADD CONSTRAINT CK_Credit_Limit
CHECK (State='LA' AND [Credit Limit] <= 150000)
GO

INSERT INTO Customers (Customer_Id, Name, Status, Phone, State, Zip, Email, [Credit Limit])
VALUES (1, 'James Black', 'Mr', 5558787, 'LA', 46853, '[email protected]', 120000);
GO

INSERT INTO Customers (Customer_Id, Name, Status, Phone, State, Zip, Email, [Credit Limit])
VALUES (2, 'Mark Spencer', 'Mr', 3332244, 'NY', 23487, '[email protected]', 200000);
GO

Ao executar a instrução acima, obtemos o seguinte erro:


A instrução INSERT entrou em conflito com a restrição CHECK. O que deu errado?

Vamos dar uma olhada mais de perto na consulta. Observe que a restrição CHECK permite apenas os valores ‘LA’ para a coluna State. Ao mesmo tempo, os valores na coluna Crédito não devem exceder 150.000.

Da mesma forma, a restrição CHECK não permitiria escrever outros códigos de estado na coluna.

Assim, precisamos modificar a condição. De acordo com a lógica do negócio, o banco fornece $ 150.000 do limite de crédito para residentes da Louisiana. Ao mesmo tempo, esse valor pode variar para outros moradores.

Para implementar este caso, usaremos a cláusula CASE dentro da restrição CHECK:

ALTER TABLE dbo.Customers
ADD CONSTRAINT CK_Credit_Limit
CHECK (CASE WHEN State='LA' AND [Credit Limit] <= 150000 THEN 1 ELSE 0 END = 1)
GO

Essa expressão atende completamente à lógica de negócios.

Valores NULL na restrição CHECK


O banco divide seus clientes em segmentos. A coluna Status contém os dados que determinam se um cliente é VIP ou regular. O valor máximo do limite de crédito para os clientes regulares é de $ 200.000. Os VIPs podem sacar $ 500.000.

A restrição CHECK pode ter a seguinte aparência:
ALTER TABLE dbo.Customers
ADD CONSTRAINT CK_Status_Credit_Limit
CHECK (Status = 'VIP' OR Status = 'Regular')
GO

Observe que a restrição CHECK permite inserir NULLs na coluna State (desde que não haja uma restrição NOT NULL explicitamente definida). A restrição CHECK avalia os valores e retorna TRUE ou FALSE. Ele avalia NULL como UNKNOWN. Portanto, NULLs não causarão erros. Isso é contrário aos predicados em cláusulas WHERE em instruções SELECT ou UPDATE.

VERIFICAR e NÃOVERIFICAR

De tempos em tempos, a lógica de negócios muda. Causa modificações no objeto do banco de dados. Imagine que um país estende a base de CEP e adiciona valores de 6 dígitos.

Os antigos valores de 5 dígitos não serão mais atribuídos às áreas. No entanto, eles ainda são válidos para os existentes. Assim, a restrição CHECK deve levar em consideração os dados existentes no formato antigo e validar os dados no novo formato.

A cláusula NOCHECK resolve este problema:

ALTER TABLE Customers WITH NOCHECK
ADD CONSTRAINT CK_Zip_Code
CHECK (Zip LIKE REPLICATE('[0-9]', 6));
GO

A seguinte inserção foi bem-sucedida:
INSERT INTO Customers (Customer_Id, Name, Status, Phone, State, Zip, Email, [Credit Limit])
VALUES (102, 'Jake Harrison', 'VIP', 555-555-1234, 'NY', 123456, '[email protected]', 100000);
GO

Ao tentar inserir um zip de cinco dígitos, o mecanismo gera o erro:


DBCC CHECKCONSTRAINTS

O SQL Server fornece DBCC CHECKCONSTRAINTS para pesquisar dados que não correspondem às restrições.

Se houver um problema de integridade do banco de dados, execute DBCC CHECKCONSTRAINTS para todo o banco de dados para garantir que não haja problemas.

Observe que este comando afeta o desempenho. Portanto, ele não deve ser executado em uma base agendada.

É possível executar DBCC CHECKCONSTRAINTS para uma única restrição, uma tabela ou todo o banco de dados.

Em comparação com outros comandos de verificação, DBCC CHECKCONSTRAINTS leva um tempo considerável para ser concluído e consome recursos do sistema. Ao contrário de outros comandos, CHECKCONSTRAINTS não utiliza um instantâneo de banco de dados.

Conclusão


As restrições CHECK fornecem o mecanismo para avaliar os dados antes da inserção. As restrições CHECK podem se referir a uma única coluna ou a várias colunas de tabela.

Restrições são simplesmente predicados que resultam em TRUE, FALSE ou UNKNOWN. Caso NULL seja inserido em uma tabela, uma restrição não é violada.