No SQL Server, uma restrição de chave estrangeira (e um
CHECK
restrição) pode ser confiável ou não confiável. Quando uma restrição é confiável, isso significa que a restrição foi verificada pelo sistema. Quando não é confiável, a restrição não foi verificado pelo sistema.
Basicamente, quando você tem uma restrição não confiável, também pode ter dados inválidos em seu banco de dados. Com isso quero dizer que você pode ter dados que violam a restrição.
Isso significa que você não está mais mantendo a integridade referencial em seus relacionamentos, o que normalmente não é uma boa prática ao cuidar de um banco de dados relacional em produção.
Neste artigo, verificarei minhas restrições existentes quanto à “confiabilidade” e, em seguida, as atualizarei para se tornarem confiáveis novamente.
Exemplo 1 – Revisar restrições existentes
Você pode descobrir se uma restrição é confiável ou não 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 | 1 | 1 | | FK_Albums_Genres | 0 | 1 | +-------------------+---------------+------------------+
OK, isso me diz que tenho duas restrições de chave estrangeira e ambas não são confiáveis.
Uma das restrições está desabilitada, então faz sentido que não seja confiável (dados ruins podem entrar no banco de dados sempre que a restrição estiver desabilitada).
Mas a outra restrição está habilitada, então realmente não deve ser não confiável. Ser não confiável significa que pode haver dados inválidos no banco de dados. Isso não significa que existe dados inválidos, só que poderia ser.
Basicamente, ao ser ativado, ele verificará dados futuros, mas não poderá garantir dados existentes. Se uma restrição for confiável, você pode ter certeza de que todos os dados existentes são válidos.
Retornar apenas restrições não confiáveis
Você pode preferir usar um
WHERE
cláusula para retornar apenas as restrições não confiáveis. Assim:SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys WHERE is_not_trusted = 1;
Resultado:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 1 | 1 | | FK_Albums_Genres | 0 | 1 | +-------------------+---------------+------------------+
Portanto, neste caso, o resultado é o mesmo (porque todas as restrições atuais não são confiáveis).
Exemplo 2 – Restaurar a confiança
Para restaurar a confiança em sua restrição habilitada, basta reativá-la enquanto usa o
WITH CHECK
opção. Assim:
ALTER TABLE Albums WITH CHECK CHECK CONSTRAINT FK_Albums_Genres;
Agora, quando consultamos
sys.foreign_keys
obtemos um resultado diferente:SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys;
Resultado:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 1 | 1 | | FK_Albums_Genres | 0 | 0 | +-------------------+---------------+------------------+
Podemos ver que a restrição agora é confiável, porque o
is_not_trusted
sinalizador está definido como 0
. Exemplo 3 – Como a restrição se tornou não confiável?
Quando você desabilita uma restrição de chave estrangeira, ela automaticamente se torna não confiável. Ao reativar a mesma restrição, você tem a oportunidade de restaurar sua confiança. Se você não fizer isso, ele permanecerá não confiável.
Ao habilitar uma restrição de chave estrangeira, você tem a opção de especificar
WITH CHECK
ou WITH NOCHECK
. Se você especificar a última, sua restrição permanecerá não confiável depois de habilitada. É importante observar que
WITH NOCHECK
é a opção padrão, portanto, se você não especificar explicitamente que deve ser confiável, a restrição será habilitada como não confiável. No entanto, é o oposto quando você cria uma restrição de chave estrangeira. Quando você cria a restrição pela primeira vez, a opção padrão é
WITH CHECK
. Portanto, se você omitir essa configuração, ela será confiável por padrão (a menos que você tenha dados inválidos, caso em que não será ativado). No entanto, você pode substituir essa configuração especificando explicitamente WITH NOCHECK
quando você cria a restrição. Para demonstrar como suas restrições habilitadas podem permanecer facilmente não confiáveis, vou reativar a outra chave (a desabilitada), mas usarei a configuração padrão:
ALTER TABLE Albums 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 | 1 | | FK_Albums_Genres | 0 | 0 | +-------------------+---------------+------------------+
Então, sendo preguiçoso (ou esquecido) e não especificando explicitamente
WITH CHECK
, consegui habilitar uma restrição com sucesso, mantendo intacto seu status "não confiável". A principal conclusão disso é:se você deseja que suas restrições reativadas sejam confiáveis, você deve sempre habilitá-las usando
WITH CHECK
.