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 porWITH 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.