Więzy integralności (konstrainty)

Więzy integralności jest to szereg zasad włączonych w definicję tabel, które gwarantują, że nie będzie można zmodyfikować danych w taki sposób, aby dane te straciły spójność i poprawność.

Rodzaje więzów integralności

NOT NULL

Konstraint ten zapobiega wstawianiu lub zmodyfikowaniu wiersza w tabeli w taki sposób, aby kolumna przyjęła wartość NULL. Konstraint ten bardzo często łączy się z klauzulą DEFAULT.

Aby zobaczyć, które kolumny posiadają ograniczenie NOT NULL wystarczy wpisać polecenie :


DESC tabela;
                        

UNIQUE

  • Konstraint ten zapewnia unikalność wartości w kolumnie na której został założony.
  • Dopuszcza występowanie wartości nullowych.
  • Założenie tego konstraintu wiąże się z niejawnym założeniem indeksu unikatowego.
  • UNIQUE może zostać założony na dowolnej ilości kolumn (max 32).
  • W jednej tabeli może zostać założonych wiele konstraintów UNIQUE.

PRIMARY KEY

Konstraint ten jest bardzo podobny do UNIQUE. Różnice są następujące:

  • W tabeli może być tylko jeden klucz główny
  • Klucz główny gwarantuje brak wartości NULL.

CHECK

CHECK sprawdza pewien warunek określony wyrażeniem logicznym. Jeżeli warunek jest prawdziwy, to dołożenie wiersza lub jego modyfikacja kończy się powodzeniem, w przeciwnym wypadku, gdy warunek jest nullowy lub nieprawdziwy, operacja kończy się błędem o naruszeniu konstraintu.

W wyrażeniu opisującym warunek mogą wystąpić odwołania do kolumn tabeli, na której jest założony konstraint, do funkcji wbudowanych (z wyjątkiem agregujących), do stałych, do funkcji użytkownika (w ograniczonym stopniu).

W wyrażeniu opisującym warunek nie mogą wystąpić odwołania do innych tabel, zmiennych pakietowych, SYSDATE i USER.

FOREIGN KEY

Klucz obcy służy do definiowania relacji nadrzędny podrzędny pomiędzy wieloma tabelami. Nie pozwala on na żadną modyfikacje danych w którejkolwiek z połączonych tabel, która spowodowałaby sytuację, że rekord z tabeli podrzędnej nie ma swojego odpowiednika w tabeli nadrzędnej.

Klucz obcy może być oparty na wielu kolumnach.

Klucz obcy musi się odwoływać do kolumny (kolumn) w tabeli nadrzędnej, na których założony jest UNIQUE lub klucz główny.

Jedna tabela może być zarówno tabelą nadrzędną i podrzędną dla wielu innych tabel. Możliwe jest budowanie bardzo skomplikowanych zależności łączących tabele.

Zakładanie konstraintów

Jeżeli konstraint dotyczy tylko jednej kolumny, to można wyspecyfikować go przy definicji kolumny.

Przykład

Stworzyć tabelę uczniowie z odpowiednimi ograniczeniami.

CREATE TABLE uczniowie (
  id number CONSTRAINT tab_pk PRIMARY KEY,
  nazwisko varchar2(25) NOT NULL,
  wiek number(3) CONSTRAINT wiek_ck CHECK (wiek > 0),
  id_klasy number(9) CONSRAINT kl_fk REFERENCES klasy(id)
);
                        

Możliwe jest definiowanie wielu konstraintów dotyczących jednej kolumny.

Przykład

Założyć klucz główny i warunek dodatkowy na jedną kolumnę

  ...
  id number CONSTRAINT tab_pk PRIMARY KEY CHECK (mod (id,2)=0),
  ...
                        

Konstrainty można również dodawać po zdefiniowaniu kolumn. Jest to jedyna metoda, w przypadku, gdy konstraint odwołuje się do kilku kolumn. Definiujemy je wtedy na końcu tabeli, po przecinku.

Przykład

Założyć konstraint gwarantujący unikalność dwu kolumn, warunek obejmujący dwie kolumny i klucz obcy do kolumny id w tabeli klasy.

 CREATE TABLE uczniowie (
  id number CONSTRAINT tab_pk PRIMARY KEY,
  nazwisko varchar2(25) NOT NULL,
  wiek number(3) CONSTRAINT wiek_ck CHECK (wiek > 0),
  id_klasy number(9),
  CONSTRAINT naz_uk UNIQUE (nazwisko, wiek),
  CONSTRAINT naz_ck CHECK (nazwisko = upper (nazwisko)),
  CONSTRAINT kl_fk FOREIGN KEY (id_klasy) REFERENCES klasy(id));
                        

Konstrainty można zakładać i usuwać już po stworzeniu tabeli.

Przykład

Założyć klucz główny i klucz obcy na istniejącej tabeli. Usunąć konstraint wiek_ck

CREATE TABLE uczniowie (
  id number,
  nazwisko varchar2(25) NOT NULL,
  wiek number(3) CONSTRAINT wiek_ck CHECK (wiek > 0),
  id_klasy number(9)
);

ALTER TABLE uczniowie 
  ADD CONSTRAINT tab_pk PRIMARY KEY (id);
ALTER TABLE uczniowie 
  ADD CONSTRAINT kl_fk FOREIGN KEY (id_klasy) 
  REFERENCES klasy(id);
ALTER TABLE uczniowie DROP CONSTRAINT wiek_ck;
                        

W wyjątkowy sposób podczas zakładania na istniejącej tablicy traktuje się konstraint NOT NULL. Zakłada się go i usuwa w taki sposób jakby się modyfikowało kolumnę w tabeli.

Przykład

Zmienić kolumnę NOT NULL na NULL i kolumnę NULL na NOT NULL.

CREATE TABLE uczniowie (
  nazwisko varchar2(25) NOT NULL,
  wiek number(3)
);

ALTER TABLE uczniowie 
  MODIFY (nazwisko varchar2(25) NULL);
ALTER TABLE uczniowie 
  MODIFY (wiek number(3) NOT NULL);
                        

Jeżeli podczas zakładania konstraintów w tabeli znajdują się dane, to są one sprawdzane, czy są zgodne z zakładanym ograniczeniem. Jeżeli nie, to konstraint jest tworzony, ale w postaci wyłączonej.

Włączanie i wyłączanie konstraintów

Konstrainty mogą być włączane i wyłączane bez ich usuwania. W przypadku wyłączania i włączania klucza głównego i unikatowego stowarzyszony indeks jest usuwany i tworzony na nowo.

Włączanie i wyłączanie dokonuje się poleceniem:


ALTER TABLE tabela 
[DISABLE|ENABLE] CONSTRAINT konstraint;
                        

Każdy konstraint zaraz po utworzeniu jest domyślnie włączony. Można go jednak utworzyć od razu jako wyłączony dodając klauzulę DISABLE podczas jego definicji.

Po wyłączeniu i próbie ponownego włączenia mogą pojawić się kłopoty spowodowane modyfikacjami danych, jakie wystąpiły w międzyczasie.

Istnieją wtedy dwie metody dalszego postępowania:


ALTER TABLE tabela 
ENABLE CONSTRAINT konstraint 
NOVALIDATE;
                        

Spowoduje załączenie konstraintu bez walidacji istniejących danych


ALTER TABLE tabela 
ENABLE CONSTRAINT konstraint 
EXCEPTIONS INTO nazwa_tabeli;
                        

Tabelę nazwa_tabeli tworzy się przy pomocy skryptu UTLEXCPT.SQL. Po wykonaniu próby włączenia konstraintu z klauzulą EXCEPTION INTO do wskazanej tabeli wpisywane są następujące dane na temat wszystkich wierszy, które naruszają więzy integralności: nazwa konstraintu naruszonego, nazwa i właściciel tabeli, ROWID wiersza.