Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Probleme mit PL/SQL-Triggern

Sie haben den Code in Blöcken gezeigt. aber es scheint, dass Sie das ausführen, was Sie zusammen als Skript gezeigt haben, zunächst ohne das Update:

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;

Wenn es als Skript in SQL Developer ausgeführt wird, zeigt das Skript-Ausgabefenster:

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

Wenn Sie dann die Update-Anweisung zum Skript hinzufügen:

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

Sie erhalten:

Table SALUPDATES dropped.


Table SALUPDATES created.


Trigger T1 compiled

Errors: check compiler log

Wenn Sie dann versuchen, das Update alleine auszuführen (als Anweisung statt als Skript; oder indem Sie diesen Test auswählen und als Skript ausführen), erhalten Sie tatsächlich:

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.

Wenn Sie die user_errors abfragen view, oder führen Sie show errors aus , sehen Sie:

PLS-00103: Encountered the symbol "UPDATE"

Das Problem ist, dass Sie den create trigger nicht abschließen Aussage richtig. Das update wird als Teil desselben PL/SQL-Blocks gesehen; ein ungültiger Teil, aber immer noch enthalten.

Wenn Sie einen PL/SQL-Block haben, müssen Sie ihn mit einem Schrägstrich abschließen, wie es in der SQL*Plus-Dokumentation erklärt wird (was meistens auch für SQL Developer gilt):

SQL Developer beschwert sich jedoch nicht, wenn der letzte Block in einem Skript keinen abschließenden Schrägstrich hat, sodass Ihr ursprüngliches Skript (ohne das Update) funktioniert; in SQL*Plus würde es an einer Eingabeaufforderung sitzen . Es deutet irgendwie darauf hin, dass es da sein sollte – versuchend, hilfreich zu sein. Wenn Sie das update hinzufügen Aussage, dass es nicht mehr das Ende des Skripts ist, also trifft das nicht zu.

Wenn Sie Ihrem Skript einen Schrägstrich zwischen dem PL/SQL-Code und der folgenden SQL-Anweisung hinzufügen, funktioniert alles:

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

und Sie sehen jetzt:

Table SALUPDATES dropped.


Table SALUPDATES created.


Trigger T1 compiled


1 row updated.