Wprowadzenie

Ograniczenia to ‘zasady/reguły’ nakładane na kolumny danej tabeli. Pozwalają na ograniczenie rodzaju danych, który mogą trafić do danej kolumny. Podejście takie wpływa na zapewnienie poprawności oraz wiarygodności danych znajdujących się w bazie danych.

Ograniczenia możemy nakładać na poziomie danej kolumny lub całej tabeli. Jak sama nazwa wskazuje, ograniczenie nakładane na poziomie kolumny stosowane jest tylko do jednej z nich. Pamiętajcie jednak, że możemy mieć różne ograniczenia nałożone na różne kolumny danej tabeli. Z drugiej strony możemy zdefiniować ograniczenia stosowane na poziomie całej tabeli.

Zanim przejdziemy do praktyki skupmy się na kilku najczęściej używanych ograniczeniach:

  • NOT NULL - kolumna nie może mieć wartości NULL;
  • DEFAULT - domyślna wartość dla kolumny jeśli żadna nie została określona;
  • UNIQUE - wszystkie wartość w kolumnie są różne;
  • Primary Key - klucz główny tabeli, jednoznaczna identyfikacja danego wiersza w tabeli;
  • Foreign Key - klucz obcy, unikalny identifkator rekordu z innej tabeli bazy danych;
  • CHECK - wszystkie wartości w danej kolumnie spełniają określone warunki;
  • INDEX - używany do tworzenia spisu treści rekordów – zabieg indeksowania pozwala na bardzo szybkie tworzenie i pobierane danych z bazy danych.

Ograniczenia mogą być definiowane w momencie tworzenia tabeli przy pomocy polecenia CREATE TABLE lub wprowadzania modyfikacji z wykorzystaniem polecenia ALTER TABLE. Kolejnym spodobem jest wykorzystanie środowiska w którym się poruszymy i “wyklikanie wszystkiego myszką".

Istniejący przykład

Zanim przejdziemy do nakładania ograniczeń na poszczególne kolumny sprawdźmy jak wyglądają ograniczenia na przykładowej tabeli importowanej w ramach bazy danych AdventureWorks2017. W tym celu wykonamy polecenie, które pozwala nam podejrzeć istniejące ograniczenia:

-- pierwsza linia pozwala zwrócić ograniczenia na całej bazie danych
-- druga linia ogranicza nas wybór do określonej tabeli
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE TABLE_NAME = 'Employee'
SQL: ograniczenia

Na bazie powyższego zrzutu ekranu możecie zobaczyć nałożone ograniczenia: klucz główny, klucz obcy oraz ograniczenia typu CHECK - dane muszą spełniać określone warunki. Chcecie wiedzieć jakie? Najłatwiej jest podejrzeć tabelę wykorzystując Object Explorer znajdujący się po prawej stronie Waszego środowiska: SQL: ograniczenia

W efekcie 'modyfikacji' ograniczenia zobaczycie poniższą tabele oraz nałożony warunek: SQL: ograniczenia

(upper([MaritalStatus])='S' OR upper([MaritalStatus])='M')

Spróbujemy zatem ‘złamać’ ograniczenie i zobaczyć co się stanie:

-- Wynikiem wykonania tego zapytania będzie poniższy komunikat
-- The UPDATE statement conflicted with the CHECK constraint "CK_Employee_MaritalStatus". The conflict occurred in database "AdventureWorks2017", table "HumanResources.Employee", column 'MaritalStatus'.
-- The statement has been terminated.
-- Nie możemy naruszać integralności i poprawności danych
UPDATE HumanResources.Employee
SET MaritalStatus = 'O'
WHERE BusinessEntityID = 1

Kasowanie i dodawanie własnych ograniczeń

Skoro powyższe ograniczenie istnieje i nam nie odpowiada w pierwszej kolejności je skasujemy a następnie dodamy swoje własne, które będzie spełniało nasze wymagania. Kasowanie jest niezwykle proste, spójrzcie na poniższą składnię:

ALTER TABLE NAZWA_TRABEL DROP CONSTRAINT NAZWA_OGRANICZENIA

W tym poleceniu dokonujemy modyfikacji tabeli przy użyciu polecenia ALTER TABLE a następnie usunięcia danego wiązania przy użyciu polecenia DROP CONSTRAINT. Spójrzcie jak wyglądałoby zapytanie dla naszego przypadku:

ALTER TABLE HumanResources.Employee DROP CONSTRAINT CK_Employee_MaritalStatus

Od teraz możemy dodawać inne statusy dla tej kolumny. Spójrzcie na pierwszy rekord w tabeli: SQL: ograniczenia

W ramach praktyki dodajmy jeszcze swoje własne ograniczenie typu CHECK, które pozwala na dodawanie trzech statusów: ‘M’, ‘S’ oraz wspomniane wcześniej ‘O’:

ALTER TABLE  HumanResources.Employee -- modyfikujmy tabelę
ADD CONSTRAINT CK_Employee_MaritalStatus  -- dodajemy ogrniaczeniu typu CHECK
CHECK (upper([MaritalStatus])='S' OR upper([MaritalStatus])='M' OR upper([MaritalStatus])='O')
-- defniujemy nasze własne ograniczenia

Podsumowanie

W ramach własnych eksperymentów warto popróbować z różnymi typami ograniczeń nakładanymi na różne kolumny – dopiero wówczas będziecie w stanie dokładnie zrozumieć potencjał i wymagania kryjące się pod pojęciem tych reguł. Zwykle są one wynikiem analizy biznesowej danego produktu oraz potrzeb Waszych własnych projektów.