Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Problemy z wyzwalaczem PL/SQL

Pokazałeś kod porcjami. ale wygląda na to, że uruchamiasz to, co razem pokazałeś jako skrypt, początkowo bez aktualizacji:

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;

Po uruchomieniu jako skrypt w SQL Developer, okno wyjściowe skryptu pokazuje:

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

Jeśli następnie dodasz do skryptu instrukcję aktualizacji:

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

otrzymujesz:

Table SALUPDATES dropped.


Table SALUPDATES created.


Trigger T1 compiled

Errors: check compiler log

Jeśli następnie spróbujesz uruchomić aktualizację samodzielnie (jako instrukcję zamiast skryptu lub wybierając ten test i uruchamiając go jako skrypt), rzeczywiście otrzymasz:

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.

Jeśli zapytasz user_errors wyświetl lub uruchom show errors , zobaczysz:

PLS-00103: Encountered the symbol "UPDATE"

Problem polega na tym, że nie kończysz create trigger oświadczenie prawidłowo. update jest postrzegany jako część tego samego bloku PL/SQL; nieprawidłowa część, ale nadal uwzględniona.

Kiedy masz blok PL/SQL, musisz zakończyć go ukośnikiem, jak wyjaśniono w dokumentacji SQL*Plus (co dotyczy głównie SQL Developera):

SQL Developer nie narzeka jednak, jeśli ostatni blok w skrypcie nie ma końcowego ukośnika, więc twój oryginalny skrypt (bez aktualizacji) działa; w SQL*Plus byłby wyświetlany na znak zachęty . Sugeruje, że powinien tam być – starając się być pomocny. Po dodaniu update oświadczenie to nie jest już koniec skryptu, więc to nie ma zastosowania.

Jeśli dodasz ukośnik do skryptu między kodem PL/SQL a następującą instrukcją SQL, wszystko działa:

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

a teraz widzisz:

Table SALUPDATES dropped.


Table SALUPDATES created.


Trigger T1 compiled


1 row updated.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak korzystać z tabel Oracle PLSQL (tablica asocjacyjna lub tabela indeksowana)

  2. ORA-29481:Niejawne wyniki nie mogą zostać zwrócone do klienta podczas wywoływania procedury Oracle 12c z JDBC

  3. InstallAllOracleASPNETProviders nie działa poprawnie

  4. ORA - 00933 zamieszanie ze sprzężeniem wewnętrznym i as

  5. MySQL odpowiednik Oracle SEQUENCE.NEXTVAL