Controllo d’accesso e transazioni
Introduzione al controllo d’accesso
In SQL è possibile specificare chi (quale utente) e come (lettura, scrittura) può utilizzare la base di dati, oggetto dei privilegi sono di solito le tabelle, ma anche altri tipi di risorse quali singoli attributi, viste o domini. Un utente predefinito _system ha tutti i privilegi
Privilegi
Un privilegio è caratterizzato da:
- la risorsa cui si riferisce
- l’utente che concede il privilegio
- l’azione che viene permessa
- la trasmissibilità del privilegio i privilegi offerti da SQL sono:
- insert: permette di inserire nuovi oggetti
- update: permette di modificare il contenuto
- delete: permette di eliminare oggetti
- select: permette di leggere la risorsa
- references: permette la definizione di vincoli di integrità referenziale verso la risorsa
- usage: permette l’utilizzo in una definizione
per dare questi privilegi usiamo i comandi grant e revoke che hanno le seguenti sintassi:

Autorizzazioni
La gestione delle autorizzazioni deve nascondere gli elementi cui un utente non può accedere, senza sospetti. Esempio:
- Facciamo una select sulla tabella “Impiegati” e ricevo “non esiste” (è vero la tabella non esiste)
- Facciamo una select sulla tabella “ImpiegatiSegreti” e ricevo “non esiste” (la tabella esiste ma l’utente che sta facendo la query non è autorizzato)
Per autorizzare un utente a vedere solo alcune ennuple di una relazione usiamo le viste.
Il concetto di ruolo da assegnare ad ogni utente dentro la nostra base di dati viene introdotto con SQL 1999
Introduzione alle transazioni
Insieme di operazioni da considerare indivisibile, corretto anche in presenza di concorrenza e con effetti definitivi. Le proprietà principali delle transazioni sono:
- Atomicità: la sequenza di operazioni sulla base di dati viene eseguita per intero o per niente
- Consistenza: al termine dell’esecuzione di una transazione, i vincoli di integrità devono essere soddisfatti
- Isolamento: l’effetto di transazioni concorrenti deve essere coerente
- Durabilità: la conclusione positiva di una transazione corrisponde ad un impegno a mantenere traccia del risultato in modo definitivo
Transazioni in SQL
Una transazione inizia al primo comando SQL dopo la connessione alla base dati, esiste anche un comando start transaction non obbligatorio. Alla conclusione di una transazione potremmo avere due casi:
- commit: le operazioni specificate a partire dall’inizio della transazione vengono eseguite sulla base di dati
- rollback: si rinuncia all’esecuzione delle operazioni specificate dopo l’inizio della transazione molti sistemi prevedono una modalità di autocommit
start transaction
update ContoCorrente
set Saldo = Saldo – 10
where NumeroConto = 12345 ;
update ContoCorrente
set Saldo = Saldo + 10
where NumeroConto = 55555 ;
commit work;Basi di dati attive
Introduzione ai trigger
Una base di dati può contenere delle regole attive dette trigger, questi strumenti si basano sul paradigma: Evento-Condizione-Azione, questo modello consente computazioni reattive.
- Evento: normalmente una modifica dello stato del database: insert, delete, update, in questa fase il trigger viene attivato
- Condizione: Un predicato che identifica se l’azione del trigger deve essere eseguita, quando la condizione viene valutata il trigger è considerato
- Azione: Una sequenza di update SQL o una procedura, quando l’azione è eseguita anche il trigger è eseguito
Sintassi
Ogni trigger è caratterizzato da:
- nome
- target
- modalità (before o after)
- evento (insert, delete o update)
- granularità
- alias dei valori
- azione
- timestamp di creazione

Tipi di eventi
Before: il trigger è considerato ed eseguito prima dell’evento, di solito questa modalità è usata quando si vuole verificare una modifica prima che essa avvenga e “modificare la modifica”
create trigger LimitaAumenti
before update of Salario on Impiegato
for each row
when (New.Salario > Old.Salario * 1.2)
set New.Salario = Old.Salario * 1.2After: il trigger è considerato e eseguito dopo l’evento, è la modalità più comune ed è adatta alla maggior parte delle applicazioni
create trigger LimitaAumenti
after update of Salario on Impiegato
for each row
when (New.Salario > Old.Salario * 1.2)
UPDATE Impiegato SET Salario = Old.Salario * 1.2 WHERE Matricola = NEW.MatricolaGranularità degli eventi
Modalità statement-level: for each statement il trigger viene considerato e possibilmente eseguito solo una volta per ogni statement che lo ha attivato
- ci sono due tabelle di transizione alla quale possiamo fare riferimento usando:
- old table: che contiene la tabella con tutti i valori precedenti allo statement
- new table: che contiene la tabella con tutti i valori successivi allo statement
create trigger AccountMonitor
after update on Account
for each row
when new.Total > old.Total
insert
into Payments
values
(new.AccNumber,new.Total-old.Total)Modalità row-level: for each row il trigger viene considerato e possibilmente eseguito una volta per ogni tupla modificata
- ci sono due variabili di transizione alla quale possiamo fare riferimento usando:
- old: che rappresenta il valore precedente della tupla
- new: che rappresenta il valore successivo delle tupla
create trigger FileDeletedInvoices
after delete on Invoice
referencing old_table as OldInvoiceSet
insert into DeletedInvoices
(select *
from OldInvoiceSet)Esecuzione dei trigger in conflitto
Quando vi sono più trigger associati allo stesso evento vengono eseguiti come segue:
- Prima i BEFORE
- Viene eseguita la modifica e il controllo dei vincoli di integrità
- Infine gli AFTER
Quando i vari trigger appartengono alla stessa categoria, l’ordine di esecuzione è definito in base al loro timestamp di creazione
Modello di esecuzione dei trigger
I trigger sono associati ad un Trigger Execution Context, l’azione di un trigger può produrre eventi che attivano altri trigger che vengono valutati in un nuovo TEC interno, questa cosa può accadere in modo ricorsivo, l’esecuzione termina in due modi:
- Correttamente: si arriva correttamente in uno stato quiescente
- Erroneamente: l’esecuzione termina in errore quando si raggiunge una profondità di ricorsione troppo alta, quando succede viene fatto un rollback allo statement che ha fatto partire la catena di trigger
Trigger in Oracle
In oracle si usa una sintassi differente:
- sono consentiti eventi multipli
- non sono previste variabili per le tabelle
- la condizione è presente solo con trigger row-level

Conflitti tra trigger in Oracle
Per evitare i conflitti tra trigger questo è l’ordine di esecuzione dei trigger in oracle:
- I before statement-level trigger
- I before row-level trigger
- Viene eseguita la modifica dei vincoli di integrità
- gli after row-level trigger
- gli after statement-level trigger
quando i vari trigger appartengono alla stessa categoria, l’ordine di esecuzione è definito in base al loro timestamp di creazione
Mutating table exception: scatta se la catena di trigger attivati da un before trigger T cerca di modificare lo stato della tabella target di T
Proprietà formali dei trigger
Vi sono tre proprietà classiche:
- Terminazione: per un qualunque stato iniziale e una qualunque transazione, si produce uno stato finale
- Confluenza: l’esecuzione dei trigger termina e produce un unico stato finale, indipendente dall’ordine di esecuzione dei trigger
- Univoca osservabilità: i trigger sono confluenti e producono verso l’esterno lo stesso effetto
Analisi della terminazione
Si usa una rappresentazione delle regole detta grafo di triggering dove abbiamo un nodo per ogni trigger, un arco dal nodo al nodo se l’esecuzione dell’azione di può attivare il trigger in questo modo se:
- il grafo è aciclico: l’esecuzione termina
- il grafo ha cicli: allora può avere problemi di terminazione
Esempio
T1:
create trigger AdjustContributions
after update of Salary on Employee
referencing new table as NewEmp
update Employee set Contribution = Salary * 0.8
where RegNum in (select RegNum from NewEmp)
T2:
create trigger CheckBudgetThreshold
after update on Employee
referencing new_table as NewEmp1
when 50000 < ALL (select (Salary+Contribution) from NewEmp1)
update Employee
set Salary = 0.9*Salary
in questo caso abbiamo dei cicli ma terminano.