Oracle
 sql >> Database >  >> RDS >> Oracle

Oracle - Problema durante la creazione del trigger che aggiorna un'altra tabella

Alcuni problemi in ordine sparso.

Innanzitutto, nel corpo di un attivatore a livello di riga, devi utilizzare :new e :old per fare riferimento ai record nuovi e vecchi. I due punti iniziali sono necessari. Quindi il tuo WHERE la clausola dovrebbe essere

WHERE PROJECTID = :new.PROJECTID

Secondo, se stai eseguendo il tuo CREATE TRIGGER in SQL*Plus, puoi ottenere un elenco degli errori e degli avvisi utilizzando SHOW ERRORS comando, cioè

SQL> show errors

Puoi anche interrogare DBA_ERRORS tabella (o ALL_ERRORS o USER_ERRORS a seconda del tuo livello di privilegio) ma non è qualcosa a cui normalmente devi ricorrere.

Terzo, supponendo che gli errori di sintassi vengano corretti, otterrai una mutante errore di tabella se usi questa logica Un trigger a livello di riga nella tabella A (TPM_TRAININGPLAN in questo caso) non può interrogare la tabella A perché la tabella potrebbe trovarsi in uno stato incoerente. Puoi aggirare il problema, come mostra Tim nel suo articolo, creando un pacchetto con una raccolta, inizializzando tale raccolta in un trigger di istruzione before, popolando i dati nella raccolta in un trigger a livello di riga e quindi elaborando le righe modificate in un trigger di istruzione dopo. Questa è una discreta quantità di complessità da aggiungere al sistema, tuttavia, dal momento che dovrai gestire più oggetti diversi.

In generale, faresti meglio a implementare questa logica come parte di qualsiasi API che utilizzi per manipolare il TPM_TRAININGPLAN tavolo. Se si tratta di una procedura memorizzata, ha molto più senso inserire la logica per aggiornare TPM_PROJECT in quella procedura memorizzata anziché inserirla in un trigger. È notoriamente doloroso provare a eseguire il debug di un'applicazione che ha molta logica incorporata nei trigger perché ciò rende molto difficile per gli sviluppatori seguire esattamente quali operazioni vengono eseguite. In alternativa, puoi rimuovere TRAININGDELIVERYSTART colonna da TPM_PROJECT tabella e calcola semplicemente la data di inizio minima in fase di esecuzione.

In quarto luogo, se il tuo trigger si attiva su inserimenti, aggiornamenti ed eliminazioni, non puoi semplicemente fare riferimento a :new i valori. :new è valido per inserimenti e aggiornamenti ma sarà NULL se si esegue un'eliminazione. :old è valido per eliminazioni e aggiornamenti ma sarà NULL se stai eseguendo un inserimento. Ciò significa che probabilmente devi avere una logica sulla falsariga di (riferendosi alla soluzione del pacchetto di Tim)

BEGIN
  IF inserting 
  THEN
    trigger_api.tab1_row_change(p_id => :new.projectid, p_action => 'INSERT');
  ELSIF updating
  THEN
    trigger_api.tab1_row_change(p_id => :new.projectid, p_action => 'UPDATE');
  ELSIF deleting
  THEN
    trigger_api.tab1_row_change(p_id => :old.projectid, p_action => 'DELETE');
  END IF;
END;