Odpowiedzi:
Strona dokumentacji MSDN about ALTER TABLE
wyjaśnia:
ALTER TABLE
: zmodyfikuj strukturę tabeli CHECK CONSTRAINT ..
: włącz ograniczenieNOCHECK CONSTRAINT ..
: wyłącz ograniczenie WITH CHECK
: sprawdź również ograniczenieWITH NOCHECK
: nie sprawdzaj ograniczeniaIch słowami:
| [ WITH { CHECK | NOCHECK } ] { CHECK | NOCHECK } CONSTRAINT { ALL | constraint_name [ ,...n ] }
...
WITH CHECK | WITH NOCHECK
Określa, czy dane w tabeli są weryfikowane względem nowo dodanego lub ponownie włączonegoFOREIGN KEY
lubCHECK
ograniczenia . Jeśli nie jest określony,WITH CHECK
zakłada się dla nowych wiązań iWITH NOCHECK
zakłada się dla wiązań ponownie włączonych.Jeśli nie chcesz weryfikować nowych
CHECK
lubFOREIGN KEY
ograniczeń istniejących danych, użyjWITH NOCHECK
. Nie zalecamy tego, z wyjątkiem rzadkich przypadków. Nowe ograniczenie zostanie ocenione we wszystkich późniejszych aktualizacjach danych. Wszelkie naruszenia ograniczeń, które są pomijane przezWITH NOCHECK
dodanie ograniczenia, mogą spowodować niepowodzenie przyszłych aktualizacji, jeśli zaktualizują wiersze danymi, które nie są zgodne z ograniczeniem.Optymalizator zapytań nie uwzględnia zdefiniowanych ograniczeń
WITH NOCHECK
. Takie ograniczenia są ignorowane, dopóki nie zostaną ponownie włączone przy użyciuALTER TABLE
tabeliWITH CHECK CHECK CONSTRAINT ALL
....
{ CHECK | NOCHECK } CONSTRAINT
Określa, że nazwa_wiązania jest włączona lub wyłączona. Opcja ta może być używana tylkoFOREIGN KEY
iCHECK
ograniczeń. KiedyNOCHECK
jest określony, ograniczenie jest wyłączone, a przyszłe wstawienia lub aktualizacje kolumny nie są sprawdzane pod kątem warunków ograniczenia.DEFAULT
,PRIMARY KEY
iUNIQUE
ograniczeń nie można wyłączyć.
Test w dbfiddle :
CREATE TABLE a (aid INT PRIMARY KEY);
UDAĆ SIĘ
✓
INSERT INTO a (aid) VALUES (1), (2), (3) ;
UDAĆ SIĘ
Dotknięte 3 rzędy
CREATE TABLE b ( aid INT, bid INT PRIMARY KEY, CONSTRAINT [My_FORIEGN_KEY] FOREIGN KEY (aid) REFERENCES a (aid) ) ;
UDAĆ SIĘ
✓
INSERT INTO b (aid, bid) VALUES (1, 11), (1, 12), (2, 21), (3, 31) ;
UDAĆ SIĘ
Wpływ na 4 rzędy
INSERT INTO b (aid, bid) VALUES (6, 61), (6, 62) ;
UDAĆ SIĘ
Msg 547 Poziom 16 Stan 0 Wiersz 1 Instrukcja INSERT kolidowała z ograniczeniem FOREIGN KEY „My_FORIEGN_KEY”. Konflikt wystąpił w bazie danych „fiddle_792fce5de09f42908c3a0f91421f3522”, tabela „dbo.a”, kolumna „pomoc”. Msg 3621 Poziom 0 Stan 0 Wiersz 1 Instrukcja została zakończona.
SELECT * FROM b ;
UDAĆ SIĘ
pomoc | stawka -: | -: 1 | 11 1 | 12 2 | 21 3 | 31
ALTER TABLE b NOCHECK CONSTRAINT [My_FORIEGN_KEY]; --disable
UDAĆ SIĘ
✓
INSERT INTO b (aid, bid) VALUES (4, 41), (4, 42) ;
UDAĆ SIĘ
Dotknięte 2 rzędy
SELECT * FROM b ;
UDAĆ SIĘ
pomoc | stawka -: | -: 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
UDAĆ SIĘ
✓
SELECT * FROM b ;
UDAĆ SIĘ
pomoc | stawka -: | -: 1 | 11 1 | 12 2 | 21 3 | 31 4 | 41 4 | 42
INSERT INTO b (aid, bid) VALUES (6, 61), (6, 62) ;
UDAĆ SIĘ
Msg 547 Poziom 16 Stan 0 Wiersz 1 Instrukcja INSERT kolidowała z ograniczeniem FOREIGN KEY „My_FORIEGN_KEY”. Konflikt wystąpił w bazie danych „fiddle_792fce5de09f42908c3a0f91421f3522”, tabela „dbo.a”, kolumna „pomoc”. Msg 3621 Poziom 0 Stan 0 Wiersz 1 Instrukcja została zakończona.
SELECT * FROM b ;
UDAĆ SIĘ
pomoc | stawka -: | -: 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
UDAĆ SIĘ
Msg 547 Poziom 16 Stan 0 Wiersz 1 Instrukcja ALTER TABLE powodowała konflikt z ograniczeniem FOREIGN KEY „My_FORIEGN_KEY”. Konflikt wystąpił w bazie danych „fiddle_792fce5de09f42908c3a0f91421f3522”, tabela „dbo.a”, kolumna „pomoc”.
Rozważ przeczytanie tego artykułu tutaj: https://msdn.microsoft.com/en-us/library/ms190273.aspx
Mówi nam: „Optymalizator zapytań nie uwzględnia ograniczeń zdefiniowanych za pomocą NOCHECK. Takie ograniczenia są ignorowane, dopóki nie zostaną ponownie włączone przy użyciu tabeli ALTER TABLE Z KONTROLĄ KONTRAKTU WSZYSTKIEGO „
Weź również pod uwagę ten wątek na StackOverflow: /programming/529941/with-check-add-constraint-followed-by-check-constraint-vs-add-constraint
ALTER TABLE b WITH NOCHECK CHECK CONSTRAINT [My_FORIEGN_KEY]; -- enable constraint without checking
, czy to będzie oznaczać, że ograniczenie nie sprawdzi istniejących danych, tylko nowe dane przychodzące?