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

Como habilitar uma restrição de chave estrangeira no SQL Server (Exemplos de T-SQL)


Se você tiver uma restrição de chave estrangeira no SQL Server que está desabilitada no momento, poderá usar o código abaixo para reativá-la.

Ao habilitar uma restrição de chave estrangeira, você tem a opção de especificar se deseja ou não verificar quaisquer dados existentes na tabela. Isso também se aplica quando você ativa um CHECK limitação.

Abaixo estão exemplos de código de como habilitar uma restrição de chave estrangeira, especificando cada uma dessas diferentes opções.


Exemplo 1 – Habilitar uma restrição usando WITH CHECK


Este é o método recomendado (a menos que você tenha um motivo específico para não usá-lo).

Aqui está um exemplo de como habilitar uma restrição de chave estrangeira chamada FK_Albums_Artists :
ALTER TABLE Albums 
WITH CHECK CHECK CONSTRAINT FK_Albums_Artists; 

Aqui eu declaro explicitamente WITH CHECK , que informa ao SQL Server para verificar os dados existentes antes de habilitar a restrição. Se algum dado violar a restrição, a restrição não será habilitada e você receberá um erro.

Isso é bom, porque reforça a integridade referencial.

Quando você cria uma nova restrição de chave estrangeira, essa é a configuração padrão. No entanto, quando você habilita uma restrição existente (como estamos fazendo aqui), ela não a configuração padrão.

Exemplo 2 – Habilitar uma restrição usando WITH NOCHECK


Neste exemplo, a restrição é habilitada sem verificar os dados existentes:
ALTER TABLE Albums 
WITH NOCHECK CHECK CONSTRAINT FK_Albums_Artists;

Aqui eu declaro explicitamente WITH NOCHECK , que informa ao SQL Server para não verificar os dados existentes. Isso significa que a restrição será habilitada mesmo que a tabela já contenha dados que violem a restrição.

Esta é a configuração padrão ao habilitar uma restrição (mas não ao criar uma).

Uma das poucas razões (provavelmente a única razão) que você usaria isso é se você deseja manter dados inválidos no banco de dados. Talvez você tenha uma exceção única em que deve inserir uma linha ou mais de dados inválidos, mas exige que todos os dados futuros estejam em conformidade com a restrição.

No entanto, ainda existem riscos associados a fazer isso. Aqui está o que a Microsoft tem a dizer sobre isso:

Não recomendamos fazer isso, exceto em casos raros. A nova restrição é avaliada em todas as atualizações de dados posteriores. Quaisquer violações de restrição suprimidas por WITH NOCHECK quando a restrição é adicionada pode fazer com que atualizações futuras falhem se atualizarem linhas com dados que não seguem a restrição.

Então, usando WITH NOCHECK poderia causar problemas mais tarde.

Exemplo 3 – Habilitar uma restrição usando a opção padrão


Aqui está um exemplo usando a opção padrão:
ALTER TABLE Albums 
CHECK CONSTRAINT FK_Albums_Artists;

Este exemplo é o equivalente ao exemplo anterior. Como eu não especifiquei se deveria ou não verificar, o SQL Server assume que eu quero WITH NOCHECK .

Portanto, certifique-se de especificar explicitamente WITH CHECK se você quiser evitar problemas de integridade referencial.

Usar WITH NOCHECK remove a confiança


Quando você habilita uma restrição usando (o padrão) WITH NOCHECK , uma consequência da qual você deve estar ciente é que o SQL Server não confiará mais nessa restrição. Ele sinaliza como não confiável. Na verdade, ele já está sinalizado como não confiável quando você desativa a restrição.

SQL Server tem um is_not_trusted sinalizador que ele define como 1 quando você desabilita uma restrição de chave estrangeira (o que significa que não é confiável) e a única maneira de defini-la como 0 (confiável) é especificar WITH CHECK ao reativar a restrição. Por outro lado, usando WITH NOCHECK apenas o habilita sem verificar os dados existentes.

Usando WITH CHECK , você garante que a restrição verifique todos os dados existentes antes de ser habilitada. A única maneira de habilitar é se todos os dados existentes estiverem em conformidade com a restrição. Depois de verificar todos os dados existentes, a restrição pode ser confiável.

Exemplo 4 – Verifique o status confiável/desativado


Você pode verificar o status confiável e desabilitado consultando o sys.foreign_keys visão do sistema.

Assim:
SELECT 
  name AS 'Constraint',
  is_disabled,
  is_not_trusted
FROM sys.foreign_keys;

Resultado:
+-------------------+---------------+------------------+
| Constraint        | is_disabled   | is_not_trusted   |
|-------------------+---------------+------------------|
| FK_Albums_Artists | 0             | 1                |
| FK_Albums_Genres  | 0             | 0                |
+-------------------+---------------+------------------+

Isso me diz que a restrição que habilitei no exemplo anterior ( FK_Albums_Artists ) não é confiável.

Isso ocorre porque eu o habilitei usando a configuração padrão, que é WITH NOCHECK .

Se eu reativar usando WITH CHECK , eis o que acontece:
ALTER TABLE Albums 
WITH CHECK CHECK CONSTRAINT FK_Albums_Artists;

SELECT 
  name AS 'Constraint',
  is_disabled,
  is_not_trusted
FROM sys.foreign_keys;

Resultado:
+-------------------+---------------+------------------+
| Constraint        | is_disabled   | is_not_trusted   |
|-------------------+---------------+------------------|
| FK_Albums_Artists | 0             | 0                |
| FK_Albums_Genres  | 0             | 0                |
+-------------------+---------------+------------------+

Felizmente, neste caso, eu não tinha nenhum dado que violasse a restrição, então a restrição foi habilitada com sucesso e sua confiança foi restaurada.

Se houvesse dados que violassem a restrição, um erro seria exibido e eu seria forçado a corrigir os dados antes de poder restaurar a confiança na restrição.