2009-09-14 18 views
9

in Oracle posso specificare le colonne, che dovrebbe indurre una cottura di un trigger:Oracle: escludendo gli aggiornamenti di una colonna per la cottura di un trigger

create or replace trigger my_trigger 
before update of col1, col2, col3 on my_table for each row 
begin 
    // the trigger code will be executed only if col1 or col2 or col3 was updated 
end; 

Ora voglio fare quanto segue: I don' t desidera che il trigger si attivi, quando è stata aggiornata una sola colonna. Com'è possibile?

Potrei elencare tutte le colonne tranne quella, che non dovrebbe indurre un innesco del trigger. Questo è piuttosto ingombrante per le tabelle con molte colonne.

Un altro modo sarebbe quello di utilizzare la funzione AGGIORNAMENTO come questo:

if not updating('COL3') then ... 

Ma se ho cambiato COL1 e COL3 in una sola volta, l'affermazione è falsa. Questo non è ciò che voglio poiché, voglio limitare l'esecuzione quando è stata aggiornata una sola colonna (COL3).

+0

È meno ingombrante elencare tutte le colonne utilizzando il dizionario dati. 'SELECT nome_colonna FROM user_tab_columns WHERE table_name = 'MY_TABLE' AND column_name! = 'COL3';' –

+0

È vero, ma qualcun altro dovrà mantenere il trigger. Se dovessimo aggiungere una nuova colonna o rinominarla ... posso già sentirlo esclamare ad alta voce. Mi piacerebbe trovare un modo affidabile con meno dolore per lui e soprattutto per me. ;-) –

risposta

11

Si potrebbe fare qualcosa di simile:

create or replace trigger my_trigger 
before update on my_table 
for each row 
declare 
    n_cols integer := 0; 
begin 
    for r in (select column_name from all_tab_columns 
      where table_name = 'MY_TABLE' 
      and owner = 'MY_SCHEMA') 
    loop 
     if updating(r.column_name) then 
     n_cols := n_cols + 1; 
     exit when n_cols > 1; 
     end if; 
    end loop; 
    if n_cols > 1 then 
     do_something; 
    end if; 
end; 

Probabilmente non particolarmente efficiente, anche se!

0

Non credo ci sia un modo per evitare di dover elencare tutte le altre colonne nella tabella, nel corpo del trigger o nella clausola before update of ....

Tuttavia, è possibile scrivere un trigger di alterazione sulla tabella per rigenerare automaticamente il trigger di aggiornamento se si aggiungono o rimuovono colonne. È un po 'più di lavoro, ma la manutenzione dovrebbe essere automatica.

3

Probabilmente non è la risposta che si desidera ascoltare, ma penso che si stia esagerando con l'onere della manutenzione. Non è normale che la struttura di una tabella cambi molto spesso dopo la sua produzione. Se hai una tabella che è soggetta a frequenti cambi di numero di colonna o nome, allora ti suggerirei di avere un problema architettonico più grande.

Quindi, basta digitare tutti i nomi delle colonne ora, e attendere per vedere se la manutenzione diventa un problema. Non vale sicuramente la pena di codificare un'implementazione complicata in un trigger - una tassa che pagherete su ogni singolo aggiornamento - al fine di evitare modifiche occasionali allo script DDL.

5

Ho avuto lo stesso problema ieri. Volevo codificare un trigger che sparava su ogni campo tranne uno, il tavolo aveva 103 colonne.

Per prima cosa ho codificato:

if (:OLD.col1<>:NEW.col1 or :OLD.col2<>:NEW.col2 or :OLD.col3<>:NEW.col3 ....) 

Ma ho avuto alcuni problemi con valori nulli, così ho aggiunto:

if (NVL(:OLD.col1,0)<>NVL(:NEW.col1,0) or NVL(:OLD.col2,0)<>NVL(:NEW.col2,0) ....) 

Ma poi ho avuto alcuni problemi con colonne di data, è diventato un casino. .

Penso che la soluzione migliore è quella di elencare tutte le colonne che si desidera verificare nella "OF":

AFTER INSERT OR UPDATE of cOL1, col2, col3 ... colN ON table1 

Non era "elegante" ma ...ha funzionato perfettamente.

+0

questo è in realtà il più elegante di tutti .. –

Problemi correlati