A página de documentação do MSDN sobre ALTER TABLE
explica estes:
ALTER TABLE
: modifique a estrutura da tabela
(e algumas das possíveis ações / modificações são):
CHECK CONSTRAINT ..
: habilite a restrição
NOCHECK CONSTRAINT ..
: desativar a restrição
Também há etapas opcionais adicionais a serem executadas ao criar / ativar / desativar uma restrição:
WITH CHECK
: verifique a restrição também
WITH NOCHECK
: não verifique a restrição
Nas suas palavras:
| [ WITH { CHECK | NOCHECK } ] { CHECK | NOCHECK } CONSTRAINT
{ ALL | constraint_name [ ,...n ] }
...
WITH CHECK | WITH NOCHECK
Especifica se os dados na tabela é ou não validados contra um recém-adicionado ou re-habilitado FOREIGN KEY
ou CHECK
restrição . Se não especificado, WITH CHECK
será assumido para novas restrições e WITH NOCHECK
assumido para restrições reativadas.
Se você não deseja verificar novas CHECK
ou FOREIGN KEY
restrições em relação aos dados existentes, use WITH NOCHECK
. Não recomendamos fazer isso, exceto em casos raros. A nova restrição será avaliada em todas as atualizações de dados posteriores. Quaisquer violações de restrição suprimidas WITH NOCHECK
quando a restrição é adicionada podem causar falhas em atualizações futuras se atualizarem linhas com dados que não estão em conformidade com a restrição.
O otimizador de consulta não considera restrições definidas WITH NOCHECK
. Tais restrições são ignoradas até serem reativadas usando a ALTER TABLE
tabela WITH CHECK CHECK CONSTRAINT ALL
.
...
{ CHECK | NOCHECK } CONSTRAINT
Especifica que constraint_name está ativado ou desativado. Esta opção pode ser usada apenas com FOREIGN KEY
e CHECK
restrições. Quando NOCHECK
especificada, a restrição é desativada e futuras inserções ou atualizações na coluna não são validadas com relação às condições da restrição. DEFAULT
, PRIMARY KEY
, E UNIQUE
restrições não pode ser desativado.
Teste no dbfiddle :
CREATE TABLE a (aid INT PRIMARY KEY);
IR
✓
INSERT INTO a (aid)
VALUES (1), (2), (3) ;
IR
3 linhas afetadas
CREATE TABLE b
( aid INT,
bid INT PRIMARY KEY,
CONSTRAINT [My_FORIEGN_KEY]
FOREIGN KEY (aid) REFERENCES a (aid)
) ;
IR
✓
INSERT INTO b (aid, bid)
VALUES
(1, 11),
(1, 12),
(2, 21),
(3, 31) ;
IR
4 linhas afetadas
INSERT INTO b (aid, bid)
VALUES
(6, 61),
(6, 62) ;
IR
Msg 547 Nível 16 Estado 0 Linha 1
A instrução INSERT entra em conflito com a restrição FOREIGN KEY "My_FORIEGN_KEY". O conflito ocorreu no banco de dados "fiddle_792fce5de09f42908c3a0f91421f3522", tabela "dbo.a", coluna 'aid'.
Msg 3621 Nível 0 Estado 0 Linha 1
A instrução foi encerrada.
SELECT * FROM b ;
IR
ajuda | licitação
-: | -:
1 | 11
1 | 12
2 21
3 31
ALTER TABLE b NOCHECK CONSTRAINT [My_FORIEGN_KEY]; --disable
IR
✓
INSERT INTO b (aid, bid)
VALUES
(4, 41),
(4, 42) ;
IR
2 linhas afetadas
SELECT * FROM b ;
IR
ajuda | licitação
-: | -:
1 | 11
1 | 12
2 21
3 31
4 41
4 42.
ALTER TABLE b WITH NOCHECK CHECK CONSTRAINT [My_FORIEGN_KEY];
-- enable constraint without checking existing data
IR
✓
SELECT * FROM b ;
IR
ajuda | licitação
-: | -:
1 | 11
1 | 12
2 21
3 31
4 41
4 42.
INSERT INTO b (aid, bid)
VALUES
(6, 61),
(6, 62) ;
IR
Msg 547 Nível 16 Estado 0 Linha 1
A instrução INSERT entra em conflito com a restrição FOREIGN KEY "My_FORIEGN_KEY". O conflito ocorreu no banco de dados "fiddle_792fce5de09f42908c3a0f91421f3522", tabela "dbo.a", coluna 'aid'.
Msg 3621 Nível 0 Estado 0 Linha 1
A instrução foi encerrada.
SELECT * FROM b ;
IR
ajuda | licitação
-: | -:
1 | 11
1 | 12
2 21
3 31
4 41
4 42.
ALTER TABLE b WITH CHECK CHECK CONSTRAINT [My_FORIEGN_KEY];
-- check existing data and enable constraint
IR
Msg 547 Nível 16 Estado 0 Linha 1
A instrução ALTER TABLE entra em conflito com a restrição FOREIGN KEY "My_FORIEGN_KEY". O conflito ocorreu no banco de dados "fiddle_792fce5de09f42908c3a0f91421f3522", tabela "dbo.a", coluna 'aid'.
ALTER TABLE b WITH NOCHECK CHECK CONSTRAINT [My_FORIEGN_KEY]; -- enable constraint without checking
, isso significa que a restrição não verificará os dados existentes, apenas os novos dados recebidos?Considere ler o artigo aqui: https://msdn.microsoft.com/en-us/library/ms190273.aspx
Ele nos diz: 'O otimizador de consulta não considera restrições definidas com WITH NOCHECK. Tais restrições são ignoradas até serem reativadas usando a tabela ALTER TABLE WITH CHECK CHECK CONSTRAINT ALL '
Além disso, considere este encadeamento no StackOverflow: /programming/529941/with-check-add-constraint-followed-by-check-constraint-vs-add-constraint
fonte