PL / SQL触发器问题

时间:2017-04-18 18:39:42

标签: sql oracle plsql triggers

我正在尝试编写一个触发器来填充包含员工更新薪水信息的表格。我有一个问题,我现在无法解决这个问题。

以下是要填充的表格:

 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;

触发器编译时没有任何问题,但是当我尝试运行此更新时,Oracle告诉我我的触发器无效。可能导致这种情况的原因是什么?

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

1 个答案:

答案 0 :(得分:7)

您已经以块的形式显示了代码。但似乎你正在运行你作为一个脚本一起显示的内容,最初没有更新:

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;

在SQL Developer中作为脚本运行时,脚本输出窗口显示:

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

如果您随后将更新语句添加到脚本中:

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

你得到:

Table SALUPDATES dropped.


Table SALUPDATES created.


Trigger T1 compiled

Errors: check compiler log

如果您尝试自己运行更新(作为语句而不是脚本;或者选择该测试并作为脚本运行),您确实可以获得:

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.

如果您查询user_errors视图或运行show errors,您会看到:

PLS-00103: Encountered the symbol "UPDATE"

问题是您没有正确完成create trigger声明。 update被视为同一个PL / SQL块的一部分;无效的部分,但仍包括在内。

当你有一个PL / SQL块时,你必须用斜杠as it explains in the SQL*Plus documentation来终止它(它也主要适用于SQL Developer):

  

SQL * Plus以与SQL命令相同的方式处理PL / SQL子程序,除了分号(;)或空行不终止并执行块。通过在新行上单独输入句点(。)来终止PL / SQL子程序。您还可以通过在新行上单独输入斜杠(/)来终止并执行PL / SQL子程序。

如果脚本中的最后一个块没有终止斜杠,SQL Developer不会抱怨,因此您的原始脚本(没有更新)可以正常工作; in SQL*Plus it would sit at a prompt。它推断它应该在那里 - 试图有所帮助。当您添加update语句时,它不再是脚本的结尾,因此不适用。

如果在PL / SQL代码和以下SQL语句之间向脚本添加斜杠,则它都可以正常工作:

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

你现在看到了:

Table SALUPDATES dropped.


Table SALUPDATES created.


Trigger T1 compiled


1 row updated.