2012-02-22 3 views
11

Ho un database con (anche) molti trigger. Possono fare cascate.È possibile sapere quali trigger si attivano in risposta a una query?

Ho una query, che sembra semplice, e in nessun modo riesco a ricordare l'effetto di tutti i trigger. Quindi, questa semplice query potrebbe non essere affatto semplice e non fare ciò che mi aspetto.

C'è un modo per sapere quali trigger si attivano prima di eseguire la query o quali trigger sono stati attivati ​​dopo averlo eseguito (non ancora eseguito il commit)?

Non sono interessato a query come SELECT … FROM user_triggers WHERE … perché li conosco già, e anche perché non mi dice se le condizioni di attivazione dei trigger verranno soddisfatte nella mia query.

Grazie

+0

Non conosco un modo per simulare l'esecuzione del trigger ma se si è in grado di modificare i corpi dei trigger si potrebbe voler aggiungere alcune istruzioni di registro come un inserto in una tabella dedicata con il suo nome e un timestamp. A proposito: se stai usando 11g, puoi dare uno sguardo ai trigger composti ... – Toby

+0

@Toby, aggiungere dichiarazioni di log sarebbe un'idea ... ma significherebbe riscriverli tutti. Analizzeremo i trigger composti, ma abbiamo clienti che usano ancora il 9i. – Benoit

risposta

3

"Ho un database con (anche) molti trigger, che possono essere sovrapposti."

Questo è solo uno dei motivi per cui molte persone si innervosiscono.

"C'è un modo per sapere ciò che fa scattare avrebbe sparato prima di eseguire la query "

No. Prendiamo in considerazione una cosa che si potrebbe trovare in un corpo UPDATE trigger:

if :new.sal > :old.sal * 1.2 then 
    insert into big_pay_rises values (:new.empno, :old.sal, :new.sal, sysdate); 
end if; 

Come potremmo stabilire se il trigger su BIG_PAY_RISES verrà attivato? Potrebbe, potrebbe non dipendere da un algoritmo che non possiamo analizzare dall'istruzione DML.

Quindi, il meglio che puoi sperare è una ricerca ricorsiva di DBA_TRIGGERS e DBA_DEPENDENCIES per identificare tutti i trigger che potrebbe funzione nella vostra cascata. Ma sarà impossibile identificare quali spareranno sicuramente in ogni scenario.

"o quali trigger sono stati attivati ​​dopo averlo eseguito (non ancora eseguito il commit)?"

Come altri hanno sottolineato, la registrazione è un'opzione. Ma se si utilizza Oracle 11g, si ha un'altra opzione: il profilo gerarchico PL/SQL. Questo è uno strumento non intrusivo che tiene traccia di tutte le unità di programma PL/SQL toccate da una chiamata PL/SQL, compresi i trigger.Una delle caratteristiche interessanti di Hierarchical Profiler è che include le PU che appartengono ad altri schemi, che potrebbero essere utili con i trigger a cascata.

Quindi, è sufficiente avvolgere l'SQL in un blocco anonimo e chiamarlo con Hierarchical Profiler. Quindi puoi filtrare il rapporto per rivelare solo i trigger attivati. Find out more.

+0

Quindi è esattamente quello che volevo, grazie. Suppongo che con 10g siamo bloccati con semplici vecchi log, ma alcuni dei nostri database di test sono 11g. – Benoit

0

Non esiste una cosa chiamata analizzare attraverso la ricerca e dare u i trigger coinvolti nella query. Sarà così semplice. Basta selezionare i nomi delle tabelle dalla query che si sta eseguendo e per ognuno basta elencare i trigger utilizzando la seguente query prima di eseguire la query. Non è abbastanza semplice?

select trigger_name 
, trigger_type 
, status 
from dba_triggers 
where owner = '&owner' 
and table_name = '&table' 
order by status, trigger_name 
+0

Non è così semplice, ho paura. È ricorsivo: aggiorni la tabella A, che attiva un trigger di riga di aggiornamento che inserisce un record nella tabella B (e forse 3 altre tabelle, con altre 2 modificate nell'attivazione dell'istruzione). Quel fuoco si innesca e fa qualcosa per la tavola C. E così via. Potresti avvicinarti tracciando le dipendenze, almeno a un insieme di tutti i possibili trigger che potrebbero essere interessati. Ma non solo quelli che potrebbero effettivamente sparare. –

+0

Questo è esattamente quello che sto dicendo, la query che ho dato è per un solo tavolo e non per tutti loro – reddyvaribabu

1

C'è un modo per sapere cosa fa scattare avrebbero sparato prima di eseguire la query, o che cosa inneschi hanno sparato dopo l'esecuzione (non ancora impegnati)?

Per risolvere questo problema, eseguo la query all'interno di un blocco anonimo utilizzando un debugger PL/SQL.