Trigger (informatica)

Da Wikipedia, l'enciclopedia libera.

bussola Nota disambigua – Se stai cercando il Flip-flop ideato da IBM, vedi Trigger.


Indice

[modifica] Basi di dati

I Trigger, nelle basi di dati, forniscono una tecnica procedurale per specificare e mantenere vincoli di integrità anche complessi. I Trigger permettono agli utenti di specificare vincoli di integrità più complessi dato che un trigger è essenzialmente una procedura PL/SQL. Tale procedura è associata con una tabella e viene automaticamente richiamata dal sistema quando una certa modifica (o evento) avviene all'interno della tabella. Le modifiche sulla tabella possono includere operazioni insert, update, e delete.

[modifica] Definizione

La definizione di un trigger consiste nei seguenti componenti (opzionali):

nome trigger
CREATE [OR REPLACE] TRIGGER <nome trigger>
collocazione temporale del trigger
before | after
azione(i) del trigger
INSERT OR UPDATE [of <colonna(e)>] OR DELETE ON <tabella>
tipo di trigger (opzionale)
FOR each row
restrizioni trigger (solo per triggers for each row!)
when (<condizione>)
corpo del trigger
<blocco PL/SQL>

La clausola or replace ri-crea una precedente definizione del trigger qualora questo esista e abbia lo stesso <nome trigger>. Il nome di un trigger può essere scelto arbitrariamente, ma è una buona regola di programmazione usare un nome che rifletta la tabella e l'evento(i), nell'esempio, upd_ins_EMP. Un trigger può essere richiamato prima (before) o dopo (after) l'evento che causa l'attivazione del trigger. L'evento che causa l'attivazione del trigger specifica prima (o dopo) quale operazione nella tabella <tabella> il trigger debba essere eseguito. Un singolo evento è un inserimento (insert), un aggiornamento (update) o una cancellazione (delete); gli eventi possono essere combinati usando la logica or. Se il trigger deve essere eseguito soltanto quando certe colonne vengono aggiornate, queste colonne devono essere specificate dopo l'evento update. Se un trigger viene utilizzato per mantenere un vincolo di integrità, gli eventi che causano il trigger corrispondono tipicamente alle operazioni che violano l'integrità del vincolo.

[modifica] Trigger a livello riga e Trigger a livello di istruzione

Al fine di programmare i trigger efficientemente (e correttamente), è essenziale capire la differenza tra trigger a livello di riga e trigger a livello di istruzione. Un trigger a livello di riga viene definito utilizzando la clausola for each row. Se questa clausola viene omessa, si assume che il trigger sia un trigger a livello di istruzione.

[modifica] Esecuzione

Un trigger a livello di riga viene eseguito una volta per ogni riga dopo (o prima) dell'evento che lo ha causato. Al contrario, un trigger a livello di istruzione viene eseguito una volta dopo (o prima) dell'evento, indipendentemente da quante righe sono state interessate dall'evento. Per esempio, un trigger di riga con la specifica di evento after update viene eseguito una volta per ogni riga che viene interessata dall'aggiornamento (update). Quindi, se l'aggiornamento interessa 20 tuple, il trigger viene eseguito 20 volte, una volta per ogni riga. Al contrario, un trigger di istruzione viene eseguito una sola volta.

[modifica] Caratteristiche dei Trigger a livello riga

I trigger di riga hanno alcune speciali caratteristiche che non sono fornite con i trigger di istruzione: Solo con un trigger di riga è possibile accedere ai valori degli attributi di una tupla prima e dopo la modifica (perché il trigger viene eseguito una volta per ogni tupla).

Per un update trigger, si può accedere al vecchio valore di attributo utilizzando :

:old.<colonna>

e si può accedere al nuovo attributo utilizzando

:new.<colonna>

Per un insert trigger, solo

:new.<colonna>

può essere utilizzato, e per un delete trigger solo

:old.<colonna>

è valido (e si riferisce al valore dell'attributo della <colonna> della tupla cancellata). In un trigger di riga quindi è possibile specificare confronti tra il vecchio e il nuovo valore di attributo nel blocco PL/SQL, per esempio:

IF :old.SAL < :new.SAL then …

Se per un trigger di riga il contesto temporale before viene specificato, è anche possibile modificare il nuovo valore della riga, per es.,

:new.SAL:= :new.SAL*1.05 oppure :new.SAL:=:old.SAL.

Tali modifiche non sono possibili con i trigger di riga after. In generale, è raccomandabile utilizzare un trigger di riga after se la nuova riga non viene modificata nel blocco PL/SQL. I trigger a livello di istruzione sono usati in generale solo in combinazione con il trigger after.

[modifica] Clausola When

In una definizione di trigger la clausola when può essere usata solo in combinazione con un trigger for each row. La clausola è utilizzata per restringere ulteriormente l'attivazione del trigger. Per la specifica della condizioni nella clausola when, vengono mantenute le stesse restrizioni della clausola check. Le uniche eccezioni sono che le funzioni sysdate e user possono essere utilizzate, e che è possibile far riferimento ai vecchi/nuovi valori degli attributi della riga attuale. In quest'ultimo caso, i due punti “:” non devono essere utilizzati, per esempio solo:

old.<attributo><source/>
e
<source lang="SQL">new.<attributo>

[modifica] Corpo del trigger

Il corpo del trigger consiste in un blocco PL/SQL. Tutti i comandi SQL e PL/SQL eccetto le due istruzioni commit e rollback possono essere utilizzati in un blocco PL/SQL di un trigger. Inoltre, costrutti addizionali if permettono l'esecuzione di certe parti del blocco PL/SQL a seconda dell'evento che aziona il trigger. A questo scopo esistono tre costrutti: if inserting, if updating[(‘<colonna>')], e if deleting. Possono essere utilizzati come mostrato nel seguente esempio:

CREATE OR REPLACE TRIGGER emp_check
after INSERT OR DELETE OR UPDATE ON EMP
FOR each row
begin
    IF inserting then
        <blocco PL/SQL>
    end IF;
    IF updating then
        <blocco PL/SQL>
    end IF;
    IF deleting then
        <blocco PL/SQL>
    end IF;
end;

È importante comprendere che l'esecuzione di un blocco PL/SQL di un trigger costituisce una parte di transazione che può contenere eventi che provocano l'attivazione di altri trigger. Quindi, per esempio, un'istruzione insert in un blocco PL/SQL può causare l'attivazione di un altro trigger. Più trigger e modifiche quindi possono innescare un'esecuzione a cascata di triggers. Una tale sequenza di trigger termina con successo se

  1. nessuna eccezione viene rilevata all'interno del blocco PL/SQL, e
  2. nessuna dichiarazione di vincolo di integrità è stata violata.

Se un trigger rileva un'eccezione in un blocco PL/SQL, tutte le modifiche fino all'inizio della transazione vengono annullate (rollback). Nel blocco PL/SQL di un trigger, un'eccezione può essere provocata utilizzando l'istruzione raise_application_error. Questa istruzione provoca un rollback implicito. In combinazione con un trigger di riga, raise_application_error può far riferimento a vecchi/nuovi valori della riga modificata:

raise_application_error(-20020,'Incremento dello stipendio da '||to_char(:old.SAL)||' to '||to_char(:new.SAL)||' è troppo alto');

oppure

raise_application_error(-20030,'Id Impiegato '||to_char(:new.EMPNO)||' non esiste.');

[modifica] Voci correlate

Strumenti personali