Co to jest OGRANICZONA KONTROLA KONTROLNA?

18

Mam automatycznie wygenerowany T-SQL, który prawdopodobnie jest poprawny, ale tak naprawdę nie rozumiem.

ALTER TABLE [dbo].[MyTable]
WITH CHECK
CHECK CONSTRAINT [My_FORIEGN_KEY];

Wiem, co to jest ograniczenie klucza obcego, ale co to jest CHECK CHECK?

BanksySan
źródło

Odpowiedzi:

28

Strona dokumentacji MSDN about ALTER TABLEwyjaśnia:

  • ALTER TABLE: zmodyfikuj strukturę tabeli
    (niektóre z możliwych akcji / modyfikacji są):
    • CHECK CONSTRAINT ..: włącz ograniczenie
    • NOCHECK CONSTRAINT ..: wyłącz ograniczenie
      Istnieją również dodatkowe, opcjonalne kroki, które należy wykonać podczas tworzenia / włączania / wyłączania ograniczenia:
      • WITH CHECK: sprawdź również ograniczenie
      • WITH NOCHECK: nie sprawdzaj ograniczenia

Ich 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łączonego FOREIGN KEYlub CHECKograniczenia . Jeśli nie jest określony, WITH CHECKzakłada się dla nowych wiązań i WITH NOCHECKzakłada się dla wiązań ponownie włączonych.

Jeśli nie chcesz weryfikować nowych CHECKlub FOREIGN KEYograniczeń istniejących danych, użyj WITH 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 przez WITH NOCHECKdodanie 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życiu ALTER TABLEtabeli WITH 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 tylko FOREIGN KEYi CHECKograniczeń. Kiedy NOCHECKjest określony, ograniczenie jest wyłączone, a przyszłe wstawienia lub aktualizacje kolumny nie są sprawdzane pod kątem warunków ograniczenia. DEFAULT, PRIMARY KEYi UNIQUEograniczeń 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”.
ypercubeᵀᴹ
źródło
1
Dzięki. Wrt 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?
BanksySan
1
Dokładnie. Zobacz, jak kolejna wstawka (pomoc = 6) jest niedozwolona, ​​ale istniejące wiersze (z pomocą = 4) nadal tam są.
ypercubeᵀᴹ
To doskonale to pokazuje.
BanksySan
1

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

George K.
źródło