Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Problemas de gatilho PL/SQL


Você mostrou o código em pedaços. mas parece que você está executando o que mostrou junto como um script, inicialmente sem a atualização:
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 executado como um script no SQL Developer, a janela de saída do 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 você adicionar a instrução de atualização ao 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';

você obtém:
Table SALUPDATES dropped.


Table SALUPDATES created.


Trigger T1 compiled

Errors: check compiler log

Se você tentar executar a atualização por conta própria (como uma instrução em vez de um script; ou selecionando esse teste e executando como um script), você realmente obterá:
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 você consultar os user_errors visualize ou execute show errors , Você vai ver:
PLS-00103: Encountered the symbol "UPDATE"

O problema é que você não está completando o create trigger declaração corretamente. A update está sendo visto como parte do mesmo bloco PL/SQL; uma parte inválida, mas ainda incluída.

Quando você tem um bloco PL/SQL, você precisa encerrá-lo com uma barra, como explicado na documentação do SQL*Plus (que se aplica principalmente ao SQL Developer também):

O SQL Developer não reclama se o último bloco em um script não tem uma barra final, então seu script original (sem a atualização) funciona; no SQL*Plus, ele ficaria em um prompt . Isso meio que infere que deveria estar lá - tentando ser útil. Quando você adiciona a update declaração não é mais o final do script, então isso não se aplica.

Se você adicionar uma barra ao seu script entre o código PL/SQL e a seguinte instrução SQL, tudo funcionará:
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 agora você vê:
Table SALUPDATES dropped.


Table SALUPDATES created.


Trigger T1 compiled


1 row updated.