[Db] Trigger o altro?
Giovanni R.
linfo2003 a libero.it
Sab 2 Giu 2007 15:49:27 CEST
Cristiano Verondini wrote:
> Diciamo che il metodo preferito dal DB è quello dei trigger e stored
> procedure. L'alternativa è di gestire il tutto a livello applicativo.
> Nel primo caso perdi ovviamente in portabilità, ma dovresti
> guadagnare in robustezza. Nel secondo caso aumenti la portabilità, ma
> diventa più complesso gestire l'integrità del DB.
Stavo pensando che non sarebbe stato male se si fosse potuto dire al
dbms di eseguire, invece che la stored procedure, una certa operazione
via shell (./myscript.php, eheh), ovviamente passando gli argomenti
necessari allo script ed aspettando la risposta. In questo modo potrei
cercare di coniugare la robustezza dei trigger, con la semplicità (cioè
il fatto che io già lo conosca) e la portabilità di PHP. Anche se
probabilmente perderei le ottimizzazioni del dbms.
Ipotizziamo comunque io crei un trigger per ogni query DELETE su
Offerte. Se cancello un utente da Utenti, il dbms cancella
automaticamente anche le sue offerte (on delete cascade) da Offerte: in
questo modo la procedura definita dal trigger verrebbe eseguita? A
quanto ho capito, sì. E verrebbe eseguita N volte, con N uguale al
numero di offerte dell'utente, giusto?
Nel mio caso (per ogni prodotto ogni utente può fare una e una sola
offerta) non è un grosso problema, ed anzi è necessario eseguire N volte
la procedura.
Ma prendiamo ad esempio eBay, dove un utente può fare anche più di
un'offerta per ogni prodotto: in quel caso l'ideale sarebbe quello di
raggruppare (group by) per prodotto, ed eseguire un'unica volta la
procedura. Se ad es. un utente ha fatto 10 offerte sul progetto x, è
inutile decrementare 10 volte x.Numero_Offerte: basterebbe decrementarlo
di 10 unità un'unica volta alla "fine" del "processo di on delete".
Mi sa che però non esiste un trigger su tale evento.
L'unica soluzione che mi sovviene è quella di decrementare di 10 unità
x.Numero_Offerte e poi cancellare le 10 righe dalla tabella Offerte,
quando viene richiamata per la prima volta la procedura scatenata dal
trigger *before* delete per l'utente in questione: il problema è che,
così facendo, si va a cancellare la riga che sta per essere cancellata.
In sintesi, che succede se faccio una query delete e poi nella procedura
del trigger "before delete" cancello il record che il dbms si apprestava
a cancellare? mi sa che verrebbe generato un "record not found"... :-/
Al limite, comunque, si può pensare di cancellare solo le altre 9 righe
e lasciare che il dmbs cancelli la decima. Però, accidenti, non è che
sia una soluzione così elegante. :-)
Alla fine forse è meglio far eseguire la procedura 10 volte, o trovare
soluzioni a livello applicativo...
Ciao, Giovanni
ps. scusa per la lunghezza. tra l'altro non devo neppure risolvere i
problemi di eBay :-), ma, siccome sto imparando, mi piace riflettere su
come risolverei io certi problemi: proverò a chiedere a quelli di eBay
se il loro codice sia open source. ;-)
Maggiori informazioni sulla lista
Db