6 SQL : Check,Asserzioni,Viste
Vincoli di CHECK
SQL permette di specificare vincoli di integrit generici sugli attributi e le tabelle attraverso la clausola check
Le condizioni utilizzabili sono le stesse che possono apparire come argomento della clausola where di uninterrogazione SQL La condizione contenuta nel vincolo di check deve essere sempre verificata affinch la base di dati sia corretta.
3 Esercitazioni di Basi di Dati A.A.10\11 6 SQL : Check,Asserzioni,Viste
ESEMPIO : CREATE TABLE Impiegato( Nome VARCHAR(20), Cognome VARCHAR(20) check (Cognome like c%), Dipart VARCHAR(20), StipAnn INT check (StipAnn >= 1 AND StipAnn <= 999) )
Nella creazione della tabella Impiegato, vengono accettate solo tuple in cui il valore dellattributo Cognome inizia con la c e in cui lo Stipendio compreso tra 1 e 999
4 Esercitazioni di Basi di Dati A.A.10\11 6 SQL : Check,Asserzioni,Viste
La condizione contenuta nel vincolo di check viene valutata immediatamente dopo linserimento\modifica di una tupla nella tabella in cui il vincolo definito
Esempio
Impiegato Nome Cognome Dipart StipAnn
In caso di violazione del vincolo, loperazione di modifica\inserimento che ha causato tale violazione viene disfatta dal sistema (Rollback parziale). Esempio Impiegato
Nome Cognome Dipart StipAnn
Rollback parziale
6
Dipart Amministrazione
StipAnn 800
Vincoli di CHECK
la condizione specificata nel vincolo pu far riferimento ad altri attributi della stessa tabella oppure ad attributi in tabelle differenti. tutti i vincoli predefiniti (PRIMARY KEY, UNIQUE, FOREIGN KEY, ) possono essere espressi attraverso il vincolo di check.
6 SQL : Check,Asserzioni,Viste
Nella creazione della tabella Impiegato, vengono accettate solo tuple in cui il valore dellattributo Cognome inizia con la c oppure in cui il dipartimento a cui afferisce limpiegato contenuto nella tabella Dipartimento.
6 SQL : Check,Asserzioni,Viste
CREATE TABLE Impiegato( Nome VARCHAR (20), Cognome VARCHAR (20), Dipart VARCHAR (20), StipAnn INT, PRIMARY KEY (Nome, Cognome) )
E preferibile lutilizzo dei vincoli predefiniti, che permettono una rappresentazione pi compatta. Infatti, in questo caso, il vincolo di chiave primaria richiede una rappresentazione complicata con luso delloperatore aggregato count. 9
CREATE TABLE Impiegato( Nome VARCHAR(20), Cognome VARCHAR(20), Dipart VARCHAR(20), StipAnn INT, check (Nome is not null AND Cognome is not null AND 1 >= (SELECT count(*) FROM Impiegato I WHERE Nome = I.Nome and Cognome = I.Cognome ) ) )
6 SQL : Check,Asserzioni,Viste
CREATE TABLE Impiegato( Nome VARCHAR(20), Cognome VARCHAR(20), Dipart VARCHAR(20), StipAnn INT, UNIQUE(Nome, Cognome) )
CREATE TABLE Impiegato( Nome VARCHAR(20), Cognome VARCHAR(20), Dipart VARCHAR(20), StipAnn INT, check (1 >= (SELECT count(*) FROM Impiegato I WHERE Nome = I.Nome and Cognome = I.Cognome ) ) )
10
6 SQL : Check,Asserzioni,Viste
Quando un vincolo di check coinvolge due o pi tabelle, possono emergere comportamenti anomali non desiderati CREATE TABLE Impiegato( Nome VARCHAR (20), Cognome VARCHAR (20), Dipart VARCHAR (20), StipAnn INT, check ( (SELECT count(distinct Dipart) FROM Impiegato) + (SELECT count(Nome) FROM Dipartimento) <100 ) )
Se inseriamo nella tabella Dipartimento un numero di Dipartimenti superiore a 100, il vincolo rimane soddisfatto, dato che il controllo viene effettuato solo quando inseriamo tuple dentro la tabella Impiegato...ci non soddisfacente per le nostre richieste.
11 Esercitazioni di Basi di Dati A.A.10\11 6 SQL : Check,Asserzioni,Viste
Asserzioni
Per evitare eventuali spiacevoli anomalie comportate dai vincoli di check su pi tabelle, si possono utilizzare le asserzioni. Le asserzioni rappresentano vincoli non associati a nessun attributo o tabella in particolare, ma appartengono direttamente allo schema della Base di Dati.
CREATE ASSERTION NomeAsserzione
check (Condizione)
Le asserzioni permettono di esprimere vincoli particolari, come vincoli su pi tabelle o vincoli che richiedono una cardinalit minima\massima per una tabella.
12 Esercitazioni di Basi di Dati A.A.10\11 6 SQL : Check,Asserzioni,Viste
Asserzioni - Esempio
ESEMPIO : CREATE ASSERTION NonPiDi100( check ( (SELECT count(distinct Dipart) FROM Impiegato) + (SELECT count(Nome) FROM Dipartimento) < 100 ) ) Ad esempio, se il numero di valori contenuti nellattributo Nome della tabella Dipartimento superiore a 100 e la tabella Impiegato vuota , il vincolo non risulta soddisfatto.
ESEMPIO : Creare un vincolo che imponga che nella tabella Impiegato vi sia
almeno una riga
1) Costruire la tabella Impiegato, assicurando che ogni Impiegato guadagni almeno 10.000 Euro CREATE TABLE Impiegato( ID INT PRIMARY KEY, Nome VARCHAR(20), Et INT, Salario REAL, check (Salario >= 10000) )
14 Esercitazioni di Basi di Dati A.A.10\11 6 SQL : Check,Asserzioni,Viste
CREATE TABLE Dipartimento( NON VA BENE! ID INT PRIMARY KEY, Il vincolo pu essere Budget REAL, facilmente aggirato. ManagerID INT, Infatti basta aggiornare FOREIGN KEY (ManagerID) REFERENCES Impiegato let di un manager direttamente nella check ( 30 < (SELECT I.Et tabella Impiegato, FROM Impiegato I senza violare alcun WHERE I.ID = ManagerID vincolo di ) Dipartimento ) ) 15 6 SQL : Check,Asserzioni,Viste
CREATE TABLE Dipartimento( ID INT PRIMARY KEY, Budget REAL, ManagerID INT, FOREIGN KEY (ManagerID) REFERENCES Impiegato )
E preferibile lutilizzo di unasserzione, che effettua il controllo ogni qualvolta una delle due tabelle coinvolte viene aggiornata
16
CREATE ASSERTION EtManager ( check(30 < (SELECT I.Et FROM Impiegato I, Dipartimento D WHERE I.ID = D.ManagerID ) ) )
Ogni vincolo di integrit, definito tramite check o tramite asserzione, associato ad una politica di controllo che specifica se il vincolo immediato o differito. I vincoli immediati (valore di default) sono verificati dopo ogni operazione che coinvolge le tabelle presenti nel vincolo di check o nellasserzione.
Quando un vincolo immediato non soddisfatto, loperazione di modifica che ha causato la violazione stata appena eseguita e il sistema pu disfarla. Questo modo di procedere chiamato Rollback Parziale (guardare lesempio a pag. 6).
Tutti i vincoli predefiniti (PRIMARY KEY, UNIQUE, FOREIGN KEY, NOT NULL) sono verificati in modo immediato.
17
6 SQL : Check,Asserzioni,Viste
I vincoli differiti sono verificati solo al termine dellesecuzione di una serie di operazioni (che costituisce una transazione). Il controllo differito viene tipicamente introdotto per gestire situazioni in cui non possibile costruire una situazione consistenze con una singola modifica della base di dati.
Si pensi, ad esempio, ad una tabella Dipartimenti il cui attributo Direttore associato ad un vincolo di integrit referenziale verso una tabella Impiegato, e la tabella Impiegato presenta a sua volta un attributo Dipart associato ad un vincolo di integrit referenziale verso la tabella Dipartimenti. Se entrambi i vincoli fossero immediati, non sarebbe possibile modificare lo stato iniziale vuoto delle due tabelle, in quanto ogni singolo comando di inserimento di tuple non rispetterebbe il vincolo di integrit referenziale. Il controllo differito permette di gestire agevolmente questa situazione.
18
6 SQL : Check,Asserzioni,Viste
Quando si verifica una violazione di un vincolo differito al termine della transazione, non c modo di individuare loperazione che ha causato la violazione. Diventa perci necessario disfare lintera sequenza di operazioni che costituiscono la transazione. in questo caso si esegue un rollback. Grazie ai meccanismi di controllo immediato\differito, lesecuzione di un comando di modifica dellistanza della base di dati che soddisfa tutti i vincoli, produrr una nuova istanza consistente della base di dati (cio, che soddisfa a sua volta tutti i vincoli).
19
6 SQL : Check,Asserzioni,Viste
Viste
SQL permette di specificare tabelle virtuali in cui le righe non sono esplicitamente memorizzate nella base di dati, ma sono calcolate quando necessario le viste
Le viste vengono definite associando un nome ed una lista di attributi al risultato dellesecuzione di uninterrogazione. Linterrogazione interna (che pu contenere anche altre viste) deve restituire un insieme di attributi pari a quelli contenuti nello schema della vista, nello stesso ordine. Una vista una relazione di cui viene memorizzata solo la definizione, piuttosto che linsieme delle tuple.
20 Esercitazioni di Basi di Dati A.A.10\11 6 SQL : Check,Asserzioni,Viste
Viste Esempio
TABELLE DI ESEMPIO :
Impiegato Nome Cognome Dipart StipAnn Dipartimento Nome Citt
ESEMPIO : Definire una vista ImpiegatiAmmin che contiene tutti gli impiegati
del dipartimento Amministrazione con uno stipendio superiore a 10 mila euro:
CREATE VIEW ImpiegatiAmmin( Nome,Cognome, Dipart,StipAnn ) as SELECT Nome,Cognome,Dipart,StipAnn FROM Impiegato WHERE Dipart = Amministrazione AND StipAnn > 10
21
6 SQL : Check,Asserzioni,Viste
Viste Esempio
TABELLE DI ESEMPIO :
Impiegato Nome Cognome Dipart StipAnn Dipartimento Nome Citt
22
6 SQL : Check,Asserzioni,Viste
Viste aggiornabili
SQL-92 permette di aggiornare solo quelle viste definite su una sola tabella di base e che per la loro definizione non usano operatori di aggregazione o il comando distinct. Queste restrizioni relative alla politica aggiornamenti sono FONDAMENTALI per rendere laggiornamento alla tabella sottostante non ambiguo.
A ciascuna riga della tabella di base corrisponder una sola riga della vista (le viste mantengono i duplicati). Unoperazione di modifica\cancellazione nella vista deve soddisfare tutti i vincoli di integrit della tabella sottostante, altrimenti non viene eseguita.
23
6 SQL : Check,Asserzioni,Viste
Viste aggiornabili
ESEMPIO : INSERT INTO ImpiegatiAmmin (Nome,Cognome,Dipart,StipAnn) VALUES(Marco,Grigi,Amministrazione,7)
La tupla viene inserita correttamente nella relazione sottostante Impiegato, ma non nella vista ImpiegatiAmmin, che non accetta Stipendi < 10 Gli inserimenti che non soddisfano le condizioni con cui stata definita una vista possono essere disabilitati attraverso la clausola with check option. In questo caso saranno accettati solo inserimenti di righe che continuano ad apparire nella vista.
ESEMPIO : CREATE VIEW ImpiegatiAmmin( Nome,Cognome, Dipart,StipAnn ) as SELECT Nome,Cognome,Dipart,StipAnn FROM Impiegato WHERE Dipart = Amministrazione and StipAnn > 10 24 with check option
In questo caso linserimento della tupla relativa allesempio precedente verrebbe rifiutato
Citt
Milano Torino Roma Milano Milano
ESEMPIO : Definire una vista DipartimentiMilano che contiene tutti i nomi dei
dipartimenti che si trovano a Milano, con una politica di inserimento controllato
CREATE VIEW DipartimentiMilano ( Nome ) as SELECT Nome FROM Dipartimento WHERE Citt=Milano with check option SELECT * FROM DipartimentiMilano
25 Esercitazioni di Basi di Dati A.A.10\11
DipartimentiMilano Nome
Amministrazione Direzione Ricerca 6 SQL : Check,Asserzioni,Viste
Citt
Milano Torino Roma Milano Milano
DipartimentiMilano Nome
Amministrazione Direzione Ricerca
ESEMPIO : Inserire la tupla Sviluppo nella vista DipartimentiMilano INSERT INTO DipartimentiMilano ( Nome ) VALUES (Sviluppo)
26
Linserimento fallisce, perch la riga verrebbe correttamente inserita allinterno di Dipartimento (con il valore di Citt posto a NULL), ma tale risultato non sarebbe visibile in DipartimentiMilano (data la presenza di with check option nella creazione 6 SQL : Check,Asserzioni,Viste della vista)
Citt
Milano Torino Roma Milano Milano
DipartimentiMilano Nome
Amministrazione Direzione Ricerca
ESEMPIO : Inserire la tupla NULL nella vista DipartimentiMilano INSERT INTO DipartimentiMilano ( Nome ) VALUES (NULL)
Linserimento fallisce, perch si vola il vincolo di PRIMARY KEY nella tabella sottostante Dipartimento
27 Esercitazioni di Basi di Dati A.A.10\11 6 SQL : Check,Asserzioni,Viste
Citt
Milano Torino Roma Milano Milano
ESEMPIO : Definire una vista DipartimentiD che contiene tutti i nomi dei
dipartimenti che hanno nome che inizia con la D
CREATE VIEW DipartimentiD (Nome) as SELECT Nome FROM Dipartimento WHERE Nome like D%
DipartimentiD Nome
Distribuzione Direzione 6 SQL : Check,Asserzioni,Viste
Citt
Milano Torino Roma Milano Milano
DipartimentiD Nome
Distribuzione Direzione
ESEMPIO : Inserire la tupla DirezioneAvanzata nella vista DipartimentiD INSERT INTO DipartimentiD (Nome) VALUES (DirezAvanz )
Dipartimento Nome
Amministrazione
Citt
Milano Torino Roma Milano Milano NULL
DipartimentiD Nome
Distribuzione Direzione DirezAvanz
Linserimento avviene correttamente sia nella vista DipartimentiD che nella tabella sottostante Dipartimento
Citt
Milano Torino Roma Milano Milano NULL
DipartimentiD Nome
Distribuzione Direzione DirezAvanz
ESEMPIO : Inserire la tupla Sviluppo nella vista DipartimentiD INSERT INTO DipartimentiD (Nome) VALUES (Sviluppo )
Dipartimento Nome
Amministrazione Produzione Distribuzione
Citt
Milano Torino Roma Milano Milano NULL NULL
DipartimentiD Nome
Distribuzione Direzione DirezAvanz
Linserimento avviene correttamente sia nella tabella sottostante Dipartimento, ma non nella vista DipartimentiD
Citt
Milano Torino Roma Milano Milano NULL NULL
DipartimentiD Nome
Distribuzione Direzione DirezAvanz
ESEMPIO : Inserire la tupla DIS nella tabella Dipartimento INSERT INTO Dipartimento (Nome) VALUES (DIS )
Dipartimento Nome
Amministrazione Produzione Distribuzione Direzione Ricerca DirezAvanz Sviluppo DIS
Citt
Milano Torino Roma Milano Milano NULL NULL NULL
DipartimentiD Nome
Distribuzione Direzione DirezAvanz DIS
Linserimento avviene correttamente nella tabella sottostante Dipartimento. In questo caso anche la vista DipartimentiD beneficia dellinserimento
Le Viste e le interrogazioni
Le viste in SQL possono anche servire per formulare interrogazioni che non sarebbero altrimenti esprimibili, aumentando il potere espressivo del linguaggio
Ad esempio, permettono di definire in SQL interrogazioni che richiedono di utilizzare diversi operatori aggregati in cascata
32
6 SQL : Check,Asserzioni,Viste
Le Viste e le interrogazioni
ESEMPIO : Estrarre il numero medio di Dipartimenti per ogni citt
Dipartimento Nome Citt
CREATE VIEW DipartCitt( NomeCitt, NroDipart ) as SELECT Citt, count(Nome) FROM Dipartimento GROUP BY Citt SELECT avg(NroDipart) FROM DipartCitt
33
6 SQL : Check,Asserzioni,Viste
Le Viste e le interrogazioni
ESEMPIO : Estrarre il dipartimento caratterizzato dal massimo della somma
per gli stipendi
Impiegato Nome Cognome Dipart Stipendio
CREATE VIEW BudgetStipendi( Dip, TotaleStipendi) as SELECT Dipart, sum(Stipendio) FROM Impiegato GROUP BY Dipart SELECT Dip FROM BudgetStipendi WHERE TotaleStipendi = (SELECT max(TotaleStipendi) FROM BudgetStipendi)
34 Esercitazioni di Basi di Dati A.A.10\11 6 SQL : Check,Asserzioni,Viste
Esercizio
Date le seguenti tabelle :
Impiegato
Nome Cognome Dipart StipAnn
Dipartimento
Nome Citt
35
6 SQL : Check,Asserzioni,Viste
ESEMPIO : Estrarre il dipartimento in cui la somma degli stipendi degli impiegati che vi lavorano massima rispetto agli altri dipartimenti. CONSIGLIO : Creare una vista che memorizzi, per ogni dipartimento, la somma degli stipendi degli impiegati che vi lavorano.
Dipartimento
Cognome Dipart StipAnn Nome Citt
Impiegato
Nome
CREATE VIEW SommaStipendi(Dipart,Stip) AS SELECT Dipart, sum(StipAnn) FROM Impiegato GROUP BY Dipart SELECT Dipart FROM SommaStipendi WHERE Stip = (SELECT max(Stip) FROM SommaStipendi)
36 Esercitazioni di Basi di Dati A.A.10\11 6 SQL : Check,Asserzioni,Viste
ESEMPIO : Definire una vista che mostra per ogni dipartimento il valore medio degli stipendi superiori alla media del dipartimento.
Dipartimento
Cognome Dipart StipAnn Nome Citt
Impiegato
Nome
CREATE VIEW SalariSopraMedia (Dipartimento,Stipendio) AS SELECT Dipart, avg(StipAnn) FROM Impiegato I WHERE StipAnn > (SELECT avg(StipAnn) FROM Impiegato J WHERE J.Dipart=I.Dipart) GROUP BY Dipart
37
6 SQL : Check,Asserzioni,Viste