W SQL Server możesz utworzyć CHECK
ograniczenie w tabeli, aby określić wartości danych, które są dopuszczalne w jednej lub kilku kolumnach.
Jeśli tabela ma CHECK
ograniczenie i próbujesz dostarczyć dane, które nie są zgodne z CHECK
ograniczenie, operacja zakończy się niepowodzeniem z błędem.
Pomaga to zachować integralność danych, ponieważ pomaga zapobiegać przedostawaniu się nieprawidłowych danych do bazy danych.
Kiedy tworzysz CHECK
ograniczenie, podajesz wyrażenie logiczne, które zwraca TRUE
lub FALSE
. To wyrażenie logiczne jest używane do sprawdzania danych.
CHECK
ograniczenia są podobne do ograniczeń klucza obcego, ponieważ kontrolują wartości umieszczane w kolumnie. Jednak różnica polega na tym, jak określają, które wartości są prawidłowe:ograniczenia klucza obcego uzyskują listę prawidłowych wartości z innej tabeli, podczas gdy CHECK
ograniczenia określają prawidłowe wartości z wyrażenia logicznego.
Wiązania można zdefiniować na poziomie kolumny lub tabeli. Ograniczenie na poziomie kolumny dotyczy tylko danych w tej kolumnie. Ograniczenie na poziomie tabeli dotyczy całego wiersza i sprawdza dane z wielu kolumn.
Poniżej znajdują się przykłady tworzenia zarówno na poziomie kolumny, jak i tabeli CHECK
ograniczenia.
Przykład 1 – Tworzenie wiązania kontrolnego na poziomie kolumny
Oto przykład tworzenia podstawowej kolumny CHECK
ograniczenie w czasie tworzenia tabeli.
CREATE TABLE ConstraintTest ( ConstraintTestId int IDENTITY(1,1) NOT NULL PRIMARY KEY, Price smallmoney NOT NULL, CONSTRAINT chkPrice CHECK (Price > 0) );
W takim przypadku CHECK
ograniczenie określa, że wszystkie dane w Price
kolumna musi być większa od 0. Innymi słowy, cena nie może wynosić zero i nie może być ujemna. Jest to ograniczenie na poziomie kolumny, ponieważ dotyczy danych w jednej kolumnie.
Ponieważ jest to ograniczenie na poziomie kolumny, mogłem zdefiniować je jako część kolumny (bez przecinka). Więc mogłem to zrobić:
CREATE TABLE ConstraintTest ( ConstraintTestId int IDENTITY(1,1) NOT NULL PRIMARY KEY, Price smallmoney NOT NULL CONSTRAINT chkPrice CHECK (Price > 0) );
Tak czy inaczej, spróbujmy wstawić nieprawidłową wartość:
INSERT INTO ConstraintTest ( Price ) VALUES ( 0 );
Wynik:
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkPrice". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'Price'.
Przykład 2 – Dodaj więcej kolumn i kolejne ograniczenie kontrolne na poziomie kolumny
Dodajmy więcej kolumn do naszej tabeli, a następnie dodajmy kolejną kolumnę CHECK
ograniczenie.
ALTER TABLE ConstraintTest ADD TeamSize tinyint NOT NULL, StartDate date NOT NULL, EndDate date NOT NULL, CONSTRAINT chkTeamSize CHECK (TeamSize >= 3 AND TeamSize <= 15) ;
Jedna z nowych kolumn rejestruje liczbę członków zespołu. W tym przypadku regułą biznesową jest to, że zespół musi mieć co najmniej 3 członków, ale nie więcej niż 15. Dlatego baza danych powinna zapobiegać sytuacji, w której zespół ma mniej niż 3 członków lub więcej niż 15.
Spróbujmy wstawić nieprawidłową wartość:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 2, '2020-01-01', '1900-02-02' );
Wynik:
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkTeamSize". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'TeamSize'.
Przykład 3 – Dodaj ograniczenie kontrolne na poziomie tabeli
Teraz dodajmy ograniczenie na poziomie tabeli. Spowoduje to sprawdzenie danych w dwóch kolumnach.
Nawiasem mówiąc, nie musisz dodawać kolejnej kolumny, aby dodać CHECK
ograniczenie. Możesz po prostu dodać samo ograniczenie.
Przykład:
ALTER TABLE ConstraintTest ADD CONSTRAINT chkValidEndDate CHECK (EndDate >= StartDate) ;
W tym przypadku dodaję ograniczenie, aby data zakończenia nigdy nie była wcześniejsza niż data rozpoczęcia. To sprawdzanie danych w dwóch kolumnach i dlatego jest ograniczeniem na poziomie tabeli.
Spróbuj wstawić nieprawidłową wartość:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 3, '2020-01-01', '1900-02-02' );
Wynik:
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkValidEndDate". The conflict occurred in database "Test", table "dbo.ConstraintTest".
Zwróć uwagę, że aby przetestować to ograniczenie, musiałem zwiększyć liczbę członków zespołu do 3, aby zapobiec uruchomieniu poprzedniego ograniczenia (CHECK
ograniczenia są sprawdzane w kolejności ich tworzenia).
Przykład 4 – Zmiana ograniczenia CHECK
W rzeczywistości nie możesz zmienić CHECK
ograniczenie. Jeśli chcesz go zmienić, musisz go usunąć i utworzyć z nową definicją.
Przykład:
ALTER TABLE ConstraintTest DROP CONSTRAINT chkTeamSize; ALTER TABLE ConstraintTest ADD CONSTRAINT chkTeamSize CHECK (TeamSize >= 5 AND TeamSize <= 20) ;
Jak wspomniano, CHECK
Ograniczenia są sprawdzane w kolejności, w jakiej są tworzone, więc może to mieć wpływ na to, który błąd zostanie przechwycony jako pierwszy.
Dlatego w tym przypadku, jeśli spróbuję wstawić nieprawidłową wartość (i uwzględnić również nieprawidłowe daty), nieprawidłowe daty zostaną przechwycone jako pierwsze:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 4, '2020-01-01', '1900-02-02' );
Wynik:
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkValidEndDate". The conflict occurred in database "Test", table "dbo.ConstraintTest".
Aby więc sprawdzić moje ostatnie ograniczenie, muszę najpierw naprawić problem z datą:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 4, '2020-01-01', '2020-02-02' );
Wynik:
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkTeamSize". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'TeamSize'.
Więc moje ostatnie ograniczenie działa zgodnie z oczekiwaniami.
Przykład 5 – SPRAWDŹ Ograniczenia i kolumny TOŻSAMOŚĆ
Więc teraz, gdy przetestowaliśmy ograniczenia, przejdźmy dalej i wstawmy prawidłowe dane:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 5, '2020-01-01', '2020-02-02' );
Wynik:
+--------------------+---------+------------+-------------+------------+ | ConstraintTestId | Price | TeamSize | StartDate | EndDate | |--------------------+---------+------------+-------------+------------| | 13 | 1.0000 | 5 | 2020-01-01 | 2020-02-02 | +--------------------+---------+------------+-------------+------------+
W końcu otrzymujemy udaną wstawkę.
Zauważysz jednak, że IDENTITY
kolumna już wzrosła do 13.
Pamiętaj, kiedy po raz pierwszy utworzyłem tabelę, zdefiniowałem ConstraintTestId
kolumna do użycia IDENTITY(1,1)
, co oznacza, że powinien zaczynać się od 1 i automatycznie zwiększać się o 1 przy każdym wstawieniu wiersza.
Ale teraz, kiedy w końcu wstawiłem swój pierwszy wiersz, wartość wynosi już 13. To dlatego, że IDENTITY
kolumna jest zwiększana, nawet gdy CHECK
ograniczenie powoduje INSERT
operacja zakończy się niepowodzeniem.
Zauważ, że zrobiłem kilka dodatkowych nieudanych wstawek podczas wymyślania przykładów do tego artykułu, więc wartość wzrosła do wyższej wartości niż ta, którą otrzymasz, jeśli będziesz postępować zgodnie z tym artykułem krok po kroku.
W każdym razie zróbmy ostatnią nieudaną wstawkę, a następnie udaną, aby to potwierdzić.
Nieudane wstawienie:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 2, 4, '2020-01-02', '2020-02-03' );
Wynik:
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkTeamSize". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'TeamSize'.
Udane wstawienie:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 2, 6, '2020-01-02', '2020-02-03' ); SELECT * FROM ConstraintTest;
Wynik:
+--------------------+---------+------------+-------------+------------+ | ConstraintTestId | Price | TeamSize | StartDate | EndDate | |--------------------+---------+------------+-------------+------------| | 13 | 1.0000 | 5 | 2020-01-01 | 2020-02-02 | | 15 | 2.0000 | 6 | 2020-01-02 | 2020-02-03 | +--------------------+---------+------------+-------------+------------+
Widzimy, że IDENTITY
kolumna skacze z 13 do 15, więc oczywiście wzrosła podczas nieudanego wstawiania.
Niektóre ograniczenia ograniczeń wyboru
Oto kilka ograniczeń, o których należy pamiętać podczas pracy z CHECK
ograniczenia:
- Warunek wyszukiwania musi dać w wyniku wyrażenie logiczne i nie może odwoływać się do innej tabeli.
- Wyrażenie nie może zawierać typów danych aliasów.
CHECK
ograniczeń nie można zdefiniować w tekście , ntekst lub obraz kolumny.