Oracle
 sql >> Base de données >  >> RDS >> Oracle

Problèmes de déclencheur PL/SQL

Vous avez montré le code en morceaux. mais il semble que vous exécutiez ce que vous avez montré ensemble sous forme de script, initialement sans la mise à jour :

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;

Lorsqu'il est exécuté en tant que script dans SQL Developer, la fenêtre de sortie du script affiche :

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

Si vous ajoutez ensuite l'instruction de mise à jour au 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';

vous obtenez :

Table SALUPDATES dropped.


Table SALUPDATES created.


Trigger T1 compiled

Errors: check compiler log

Si vous essayez ensuite d'exécuter la mise à jour seule (en tant qu'instruction au lieu d'un script ; ou en sélectionnant ce test et en l'exécutant en tant que script), vous obtenez en effet :

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.

Si vous interrogez les user_errors afficher ou exécuter show errors , vous verrez :

PLS-00103: Encountered the symbol "UPDATE"

Le problème est que vous ne complétez pas le create trigger déclaration correctement. La update est considéré comme faisant partie du même bloc PL/SQL ; une partie non valide, mais toujours incluse.

Lorsque vous avez un bloc PL/SQL, vous devez le terminer par une barre oblique, comme expliqué dans la documentation SQL*Plus (ce qui s'applique principalement à SQL Developer également) :

SQL Developer ne se plaint pas si le dernier bloc d'un script n'a pas de barre oblique de fin, de sorte que votre script d'origine (sans la mise à jour) fonctionne ; dans SQL*Plus, il resterait assis à une invite . Cela en déduit en quelque sorte qu'il devrait être là - essayant d'être utile. Lorsque vous ajoutez la update déclaration ce n'est plus la fin du script donc cela ne s'applique pas.

Si vous ajoutez une barre oblique à votre script entre le code PL/SQL et l'instruction SQL suivante, tout fonctionne :

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';

et vous voyez maintenant :

Table SALUPDATES dropped.


Table SALUPDATES created.


Trigger T1 compiled


1 row updated.