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

Problemi di trigger PL/SQL

Hai mostrato il codice in blocchi. ma sembra che tu stia eseguendo ciò che hai mostrato insieme come script, inizialmente senza l'aggiornamento:

drop table SalUpdates cascade constraints;
create table SalUpdates(
SalSSN char(9), 
newSalary decimal(10,2), 
oldSalary decimal(10,2)
);

create or replace trigger t1
after update of salary on employee
for each row
begin
insert into SalUpdates values (:old.Ssn, :new.salary, :old.salary);  
end;

Quando viene eseguito come script in SQL Developer, la finestra di output dello script mostra:

drop table SalUpdates cascade constraints
Error report -
ORA-00942: table or view does not exist
00942. 00000 -  "table or view does not exist"
*Cause:    
*Action:

Table SALUPDATES created.


Trigger T1 compiled

Se poi aggiungi la dichiarazione di aggiornamento allo script:

drop table SalUpdates cascade constraints;
create table SalUpdates(
SalSSN char(9), 
newSalary decimal(10,2), 
oldSalary decimal(10,2)
);

create or replace trigger t1
after update of salary on employee
for each row
begin
insert into SalUpdates values (:old.Ssn, :new.salary, :old.salary);  
end;

update employee
set salary=4000
where ssn='123456789';

ottieni:

Table SALUPDATES dropped.


Table SALUPDATES created.


Trigger T1 compiled

Errors: check compiler log

Se poi provi a eseguire l'aggiornamento da solo (come un'istruzione invece di uno script; o selezionando quel test ed eseguendo come uno script) ottieni effettivamente:

SQL Error: ORA-04098: trigger 'MYSCHEMA.T1' is invalid and failed re-validation
04098. 00000 -  "trigger '%s.%s' is invalid and failed re-validation"
*Cause:    A trigger was attempted to be retrieved for execution and was
           found to be invalid.  This also means that compilation/authorization
           failed for the trigger.
*Action:   Options are to resolve the compilation/authorization errors,
           disable the trigger, or drop the trigger.

Se interroghi user_errors visualizza o esegui show errors , vedrai:

PLS-00103: Encountered the symbol "UPDATE"

Il problema è che non stai completando create trigger dichiarazione correttamente. L'update viene visto come parte dello stesso blocco PL/SQL; una parte non valida, ma comunque inclusa.

Quando hai un blocco PL/SQL devi terminarlo con una barra, come spiegato nella documentazione di SQL*Plus (che si applica principalmente anche a SQL Developer):

Lo sviluppatore SQL non si lamenta se l'ultimo blocco in uno script non ha una barra di chiusura, quindi lo script originale (senza l'aggiornamento) funziona; in SQL*Plus verrebbe visualizzato a un prompt . In un certo senso deduce che dovrebbe essere lì, cercando di essere d'aiuto. Quando aggiungi l'update istruzione non è più la fine dello script, quindi non si applica.

Se aggiungi una barra allo script tra il codice PL/SQL e la seguente istruzione SQL, funziona tutto:

drop table SalUpdates cascade constraints;
create table SalUpdates(
SalSSN char(9), 
newSalary decimal(10,2), 
oldSalary decimal(10,2)
);

create or replace trigger t1
after update of salary on employee
for each row
begin
insert into SalUpdates values (:old.Ssn, :new.salary, :old.salary);  
end;
/

update employee
set salary=4000
where ssn='123456789';

e ora vedi:

Table SALUPDATES dropped.


Table SALUPDATES created.


Trigger T1 compiled


1 row updated.