sql - PL/SQL 触发器问题

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

最佳答案

您已经分 block 显示了代码。但看起来你正在运行你作为脚本一起显示的内容,最初没有更新:

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 View ,或运行show errors,您将看到:

PLS-00103: Encountered the symbol "UPDATE"

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

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

SQL*Plus treats PL/SQL subprograms in the same manner as SQL commands, except that a semicolon (;) or a blank line does not terminate and execute a block. Terminate PL/SQL subprograms by entering a period (.) by itself on a new line. You can also terminate and execute a PL/SQL subprogram by entering a slash (/) by itself on a new line.

如果脚本中的最后一个 block 没有终止斜杠,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.

关于sql - PL/SQL 触发器问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43479838/

相关文章:

mysql - 具体拆分记录(字符串)为若干字段

java - SQL更新挂起Java程序

oracle - 在oracle中创建一个返回当前日期和时间的函数

Oracle:将 Long Raw 数据从一个表复制到另一个表

oracle - 使用输出变量动态调用 PL/SQL 过程

php - 比较两个 SQL 查询结果集

sql - 在 oracle 中的 View 上触发

sql - 倒排SQL查询

sql - 如何在 PostgreSQL 中通过数组正确创建多个条目?

Python SQL 值错误