Constraints
Cosa sono in Constraints? forzano una regola quando si agisce con una insert, update o delete su una tabella prevengono la cancellazione di una tabella se ci sono dipendenze i constraint disponibili sono: - NOT NULL - UNIQUE - PRIMARY KEY - FOREIGN KEY - CHECK
Regole per la creazione di constraints occorre mettere un nome (possibilmente coerente) al constraint, se omesso Oracle Server metterà un nome di default nel formato SYS_Cn (dove n è un intero) è possibile creare un constraint nel momento della creazione della tabella o dopo la creazione la lista dei constraint è disponibile sulla tabella del dizionario dati USER_CONSTRAINTS i constraint possono essere creati a livello di tabella o di colonna
CONSTRAINTS CREATE TABLE [schema].tabella (colonna datatype [DEFAULT espr] [constraint], … [constraint di tabella] [,…]); CREATE TABLE employees (employee_id NUMBER(6), first_name VARCHAR2(20), job_id VARCHAR2(10) NOT NULL, CONSTRAINT emp_emp_id_pk PRIMARY KEY (EMPLOYEE_ID));
Definizione di constraint a livello di colonna colonna datatype (CONSTRAINT nome_constr) tipo constraint a livello di tabella : è riferito a una o più colonne. Può essere di qualsiasi tipo tranne NOT NULL colonna, … CONSTRAINT nome_constr tipo_constraint
NOT NULL non permette l’inserimento di valori nulli nella colonna CREATE TABLE employees (employee_id NUMBER(6), last_name VARCHAR2(25) NOT NULL, … hire_date DATE, CONSTRAINT emp_hire_date_nn NOT NULL …;
UNIQUE richiede che ogni valore nella colonna o set di colonne sia unico cioè non è possibile che due righe della tabella abbiano lo stesso valore nella colonna (o set) specificata permette l’inserimento di valori nulli inquanto il valore NULL non è considerato uguale a nulla. Quindi NULL in tutti i valori di una colonna con constraint UNIQUE soddisfano il constraint al momento della creazione viene automaticamente creato un indice unique
UNIQUE Esempio CREATE TABLE employees ( employee_id NUMBER(6), last_name VARCHAR2(25) NOT NULL, … hire_date DATE NOT NULL, CONSTRAINT emp_email_uk UNIQUE(email));
PRIMARY KEY crea una chiave primaria sulla tabella solo una chiave primaria può essere creata per ogni tabella è una colonna o un set di colonne che identifica univocamente le righe della tabella forza l’unicità di una colonna (o set di colonne) e non permette l’inserimento di valori nulli al momento della creazione della chiave primaria viene automaticamente creato un indice unique
PRIMARY KEY Esempio CREATE TABLE departments ( department_id NUMBER(4), department_name VARCHAR2(30), CONSTRAINT dept_name_nn NOT NULL, manager_id NUMBER(6) location_id NUMBER(4), CONSTRAINT dept_id_pk PRIMARY KEY(department_id)); una tabella può avere una sola chiave primaria ma più unique può essere definito a livello di tabella o di colonna
FOREIGN KEY CREATE TABLE employees ( employee_id NUMBER(6), last_name VARCHAR2(25) NOT NULL, email VARCHAR2(25), salary NUMBER(8,2), department_id NUMEBR(4), … CONSTRAINT emp_dept_fk FOREIGN KEY(department_id) REFERENCES departments(department_id) CONTRAINT emp_email_uk UNIQUE(email)); department_id è stato definito foreign key della tabella employees (child table). Essa referenzia la colonna department_id della tabella departments (parent table)
FOREIGN KEY la foreign key viene definita nella tabella figlia e deve essere in relazione con un valore esistente nella tabella parent o NULL una foreign key è basata su dati ed è un puntatore logico, non fisico è possibile creare una foreign key a livello di tabella o di colonna (la differenza è che nella definizione di colonna non appare la parola chiave FOREIGN KEY) CREATE TABLE employees (… department_id NUMBER(4) REFERENCES departments (department_id),…);
PAROLE CHIAVE DELLA FOREIGN KEY FOREIGN KEY : definisce la colonna nella tabella figlia nella definizione a livello di tabella REFERENCES : definisce la tabella e la colonna della tabella parent ON DELETE CASCADE : quando una riga nella tabella padre viene cancellata, vengono cancellate anche le righe della tabella figlia ON DELETE SET NULL : quando una riga nella tabella padre viene cancellata, converte i valori della tabella figlia in NULL senza le opzioni ON DELETE CASCADE o ON DELETE SET NULL le righe della tabella padre non possono essere cancellate se esistono righe nella tabella figlia
CHECK definisce una condizione che deve essere soddisfatta da tutte le righe ... , salary NUMBER(8,2) CONSTRAINT emp_salary_min CHECK (salary > 0) la condizione può essere espressa con la stessa struttura della clausola where ad eccezione delle seguenti espressioni : - riferimenti a CURRVAL, NEXTVAL, LEVEL e ROWNUM - chiamate a funzioni SYSDATE, USER - query che ritornano valori in altre righe
CHECK una colonna può avere più CHECK contraint, non c’è limite per il numero di constraint che possono essere definiti può essere definito a livello di tabella o a livello di colonna
AGGIUNGERE CONSTRAINT Usare ALTER TABLE per : aggiungere o cancellare constraint, ma non per modificare la struttura abilitare o disabilitare constraint aggiungere il constraint NOT NULL con la clausola MODIFY ALTER TABLE table ADD CONSTRAINT constraint type (colonna);
AGGIUNGERE CONSTRAINT Aggiungere un constraint FOREIGN KEY per la tabella employees indicando che un manager deve già esistere come un record valido nella tabella employees ALTER TABLE employees ADD CONSTRAINT emp_manager_fk FOREIGN KEY(manager_id) REFERENCES employees(employee_id); Viene creata una foreign key sulla tabella employees. Il constraint assicura che un manager esiste come record valido nella tabella employees
CANCELLARE UN CONSTRAINT ALTER TABLE employees DROP CONSTRAINT emp_manager_fk; Cancellare la primary key sulla tabella department e cancellare la foreign key associata sul campo department_id della tabella employees ALTER TABLE departments DROP PRIMARY KEY CASCADE; La clausola CASCADE fa si che vengano cancellate tutte le dipendenze.
DISABILITARE UN CONSTRAINT ALTER TABLE employees DISABLE CONSTRAINT emp_emp_id_pk CASCADE; disattiva il constraint e applicando il CASCADE disabilita anche le dipendenze è possibile usare il DISABLE sia in CREATE che in ALTER table disabilitando una primary o uno unique viene rimosso l’indice di unicità
ABILITARE UN CONSTRAINT ALTER TABLE employees ENABLE CONSTRAINT emp_emp_id_pk; abilitando un constraint UNIQUE o PRIMARY KEY viene automaticamente creato un’indice unique o primary key abilitando un indice sarà valido per tutte le righe della tabella quindi tutte le righe devono essere corrette per l’abilitazione è possibile usare ENABLE sia in CREATE che ALTER table abilitando una primary key che era stata disabilitata con l’opzione cascade, non riabilita la foreign key che era dipendente dalla primary key
CASCADING CONSTRAINT è usata nella clausola DROP COLUMN cancella tutti i referential integrity constraints che si riferiscono alla primary key e unique key definite nella colonna da cancellare cancella anche i constraint definiti su più colonne
CASCADING CONSTRAINT Esempio CREATE TABLE test1 ( pk NUMBER PRIMARY KEY, fk NUMBER, col1 NUMBER, col2 NUMBER, CONSTRAINT fk_constraint FOREIGN KEY (fk) REFERENCES test1, CONSTRAINT ck1 CHECK (pk > 0 and col1 > 0), CONSTRAINT ck2 CHECK (col2 > 0)); Viene generato un errore per i seguenti statement : ALTER TABLE test1 DROP (pk); -- pk è la parent key ALTER TABLE test1 DROP (col1); -- col1 fa parte del constraint multicolonna ck1
CASCADING CONSTRAINT Per risolvere il problema precedente occorre usare il CASCADE CONSTRAINT : ALTER TABLE test1 DROP (pk) CASCADE CONSTRIANT; Oppure occorre cancellare anche tutte le colonne referenziate ALTER TABLE test1 DROP (pk, fk, col1);
CONSTRAINT – dizionario dati Usare la tabella USER_CONSTRAINT per vedere la definizione del constraint e il nome SELECT constraint_name, constraint_type, search_condition FROM user_constraint WHERE table_name = ‘EMPLOYEES’; Constraint type : C per CHECK P per PRIMARY KEY R per FOREIGN KEY (referential integrity) U per UNIQUE Il constraint NOT NULL è considerato un constraint CHECK
CONSTRAINT – dizionario dati per vedere le colonne associate con i constraint, interrogare la vista USER_CONS_COLUMNS SELECT constraint_name, column_name FROM user_cons_column WHERE table_name = ‘EMPLOYEES’;