CHECK i problem z NULL

14-wrz-2011

CHECK pozwala określić, że w danej kolumnie ma być zapisywana tylko taka wartość, która spełnia określony warunek, np długość napisu większa niż 10. Wydaje się, że taki zapis jest poprawny:

CREATE TABLE Test
(ID INT PRIMARY KEY CHECK,
Name VARCHAR(20) CONSTRAINT Test_Name5 CHECK (LEN(NAME)>5)
)
GO

Zobacz jak zachowają sie takie polecenia:

INSERT INTO Test VALUES (1,’abcdef’)
INSERT INTO Test VALUES (2,’abc’)

Pierwszy rekord się zapisał, a zapis drugiego zakończył się komunikatem o błędzie:

Msg 547, Level 16, State 0, Line 3
The INSERT statement conflicted with the CHECK constraint „Test_Name5”. The conflict occurred in database „Test”, table „dbo.Test”, column 'Name’.

Ale… jeżeli spróbujesz czegoś takiego:

INSERT INTO Test VALUES (3,NULL)

to zapis się uda.

Niby dobrze, bo przecież kolumna NAME dopuszcza NULL, ale raczej kiedy ktoś życzy sobie aby długość była większa niż 5, to wolałby aby do danej koluny nie trafiał NULL. Niekiedy nieco intuicyjnie zakładamy, że długość NULL-a to 0, więc CHECK powinien zablokować zapis, a tymczasem:

SELECT LEN(NULL)

daje w wyniku NULL

Tymczsem CHECK blokuje zapis rekordu tylko jeżeli wynik wyrażenia jest równy FALSE. W tym wypadku nie otrzymałeś FALSE, więc rekord się zapisał. Jeżeli chcesz zmienić warunek, tak by NULL nie mógł zostać zapisany możesz postąpić tak:

1. Usuń aktualny CHECK:

ALTER TABLE TEST
DROP CONSTRAINT Test_Name5

2. Utwórz go ponownie zabezpieczając się przed pojawieniem się wartości NULL:

ALTER TABLE TEST
ADD CONSTRAINT Test_Name5 CHECK (LEN(ISNULL(NAME,”))>5)

Jeżeli na tym etapie pojawił się błąd zajrzyj tu.

Teraz zapis wartości NULL już się nie uda.

Tego rodzaju informacje znajdziesz na autoryzowanym kursie Microsoft 6232. Zapraszam na autoryzowane szkolenia Microsoft w Opolu, Katowicach i Warszawie.

Komentarze są wyłączone

Autor: Rafał Kraik