Summaries

University notes in Markdown format from Obsidian.

Le asserzioni sono costrutti SQL attraverso i quali è possibile (dichiarativamente) specificare vincoli di integrità su una base di dati. Un vincolo è una condizione logica che i dati devono soddisfare affinchè la BD si trovi in uno stato consistente. Le asserzioni fanno parte dello schema della BD.

La struttura di una assertion è la seguente:

CREATE ASSERTION nome
CHECK (condizione)

Se la condizione (booleana) è verificata, il vincolo espresso dalla ASSERTION è soddisfatto. Altrimenti, viene annullato l’effetto dell’aggiornamento che ha portato alla violazione del vincolo.

La verifica dei vincoli può essere:

  • immediata: la loro violazione annulla l'ultima modifica;

  • differita: la loro violazione annulla l'intera transazione. Si consideri la seguente BD:

  • Imp(matr, nome, dip, stip, superiore, livello)

  • *Dip(cod, nome, dir, azienda)**

  • Azienda(cod, nome, città)

dove superiore e direttore sono chiavi secondarie i cui valori sono le matricole degli impiegati (quindi, sia i superiori che i direttori sono impiegati), mentre dip è una chiave secondaria i cui valori sono i codici dei dipartimenti di afferenza degli impiegati.

ESEMPIO 1: il direttore di un dipartimento deve essere un impiegato che afferisce allo stesso dipartimento:

CREATE ASSERTION Vincolo- Direttore
CHECK (NOT EXISTS (SELECT *
                     FROM Dip AS D, Imp AS I
                     WHERE D.dir = I.matr AND cod != dip))

v1
v1

La suddetta asserzione genera l’insieme di tutte le tuple di Dip il cui codice è diverso dal codice del dipartimento di afferenza del proprio direttore (tupla in rosso nell’esempio sopra). Se l’insieme è vuoto, la condizione NOT EXISTS è soddisfatta, quindi, la clausola CHECK è soddisfatta, quindi, il vincolo è soddisfatto. Altrimenti, viene annullata l’operazione di aggiornamento che ha causato la violazione del vincolo (ad es. l’inserimento della tupla dell’impiegato i2).

CREATE ASSERTION Vincolo-Stipendi
CHECK (NOT EXISTS (SELECT *
                    FROM Imp AS I
                    WHERE stip > (SELECT stip
                                    FROM Imp AS S
                                    WHERE I.superiore = S.matr)))

NOTA: col NOT EXISTS la tecnica di base è quella di scrivere una query che seleziona tuple che violano il vincolo.

CREATE ASSERTION Vincolo-Esistenza
CHECK (NOT EXISTS (SELECT *
                     FROM Dip
                     WHERE cod NOT IN (SELECT dip
                                         FROM Imp))

NOTA: la sotto-query restituisce l’insieme dei codici dei dipartimenti ai quali afferisce almeno un impiegato.

CREATE ASSERTION Vincolo-Esistenza
CHECK (NOT EXISTS (SELECT *
                     FROM Dip AS D
                     WHERE 0 = (SELECT COUNT(*)
                                 FROM Imp
                                 WHERE Imp.dip = D.cod )))

La sotto-query restituisce, per ogni dipartimento D, il relativo numero di impiegati. La condizione F = 0 = (SELECT COUNT(*) ... ) è verificata, per un dipartimento D, se il rispettivo numero di impiegati è zero. La clausola CHECK è verificata se non esiste un dipartimento D che soddisfi la condizione F.

Le condizioni utilizzabili nella CHECK sono le stesse che possono apparire come argomento della clausola where di un’interrogazione SQL.

CREATE ASSERTION Vincolo-numMax-Imp
CHECK (10 >= ALL (SELECT COUNT(*) 
                    FROM Imp
                    GROUP BY dip))

La sotto-query genera l’insieme in cui ogni elemento è il numero di impiegati di un dipartimento (che ha almeno 1 impiegato). La condizione 10 $>$= ALL verifica che ognuno di tali elementi sia minore o uguale a 10.

CREATE ASSERTION Vincolo-numMax-Imp
CHECK (NOT EXISTS (SELECT Dip 
                    FROM Imp
                    GROUPBY Dip
                    HAVING COUNT(*) > 10))
CREATE ASSERTION Vincolo-Esistenza
CHECK (EXISTS (SELECT *
                 FROM Imp))
```sql
CREATE ASSERTION Vincolo-Esistenza
CHECK (0 < (SELECT COUNT(*)
             FROM Imp))

Le asserzioni vengono eseguite ogniqualvolta viene effettuato un aggiornamento sulle relazioni di base. Se il vincolo non è soddisfatto nel nuovo stato della base di dati, l’aggiornamento viene disfatto. Aggiornamento IMMEDIATO o DIFFERITO (nel caso di transazioni). Nel primo caso si ha un rollback parziale viene effettuato dopo l’aggiornamento, nel secondo si ha un rollback di tutta la transazione.