Sql &引用;触发器---无效且重新验证失败“;
上面是每次我运行查询时的触发器,它会导致我得到一个错误,表明触发器无效且重新验证失败创建给定触发器时,它会报告一个编译错误:Sql &引用;触发器---无效且重新验证失败“;,sql,oracle,plsql,database-trigger,Sql,Oracle,Plsql,Database Trigger,上面是每次我运行查询时的触发器,它会导致我得到一个错误,表明触发器无效且重新验证失败创建给定触发器时,它会报告一个编译错误: CREATE TRIGGER Supervisors BEFORE INSERT OR UPDATE ON Employee FOR EACH ROW WHEN(new.EmpRank = 0 OR new.EmpRank = 1) DECLARE supervisorRank INT; BEGIN SELECT EmpRank INTO supervis
CREATE TRIGGER Supervisors
BEFORE INSERT OR UPDATE ON Employee
FOR EACH ROW
WHEN(new.EmpRank = 0 OR new.EmpRank = 1)
DECLARE
supervisorRank INT;
BEGIN
SELECT EmpRank INTO supervisorRank
FROM Employee
WHERE new.SupervisorID = Employee.Id;
IF((new.SupervisorID IS NULL) OR (supervisorRank - new.EmpRank != 1)) THEN
RAISE_APPLICATION_ERROR(-20004, 'Cannot insert/update record into table Employee. Invalid supervisor.');
END IF;
END;
编译错误源于触发器体中对“new”和“old”的引用之前缺少几个冒号(:”)
注意:此处触发器的“WHEN”子句中不需要冒号前缀:
Trigger SUPERVISORS compiled
Errors: check compiler log
此外,尽早失败总是一个好主意,使用更细粒度的异常来简化调试,因此我又添加了两个异常来处理NULL场景和NO_DATA_FOUND场景,与“bad rank”异常分开处理
以下是更新的代码,包括测试表定义和示例insert语句:
WHEN(new.EmpRank = 0 OR new.EmpRank = 1)
下面是上述脚本的输出,显示了各种异常消息。请注意,我使用的是新的SQLcl(sql.exe)而不是sql*Plus,但是结果应该是相同的
drop table employee
/
create table employee (
id number,
EmpRank number,
SupervisorID number,
primary key(id))
/
CREATE or replace TRIGGER Supervisors
BEFORE INSERT OR UPDATE ON Employee
FOR EACH ROW
WHEN(new.EmpRank = 0 OR new.EmpRank = 1)
DECLARE
supervisorRank INT;
BEGIN
if (:new.SupervisorID is null) then
RAISE_APPLICATION_ERROR(-20006, 'Cannot insert/update record into table Employee. Required supervisor ID is missing.');
end if;
begin
SELECT EmpRank INTO supervisorRank
FROM Employee
WHERE :new.SupervisorID = Employee.Id;
exception when no_data_found then
RAISE_APPLICATION_ERROR(-20005, 'Cannot insert/update record into table Employee. Supervisor ID not found.');
end;
IF (supervisorRank - :new.EmpRank != 1) THEN
RAISE_APPLICATION_ERROR(-20004, 'Cannot insert/update record into table Employee. Employee rank is not valid for given supervisor.');
END IF;
END;
/
insert into employee values ( 6, 1, null );
insert into employee values ( 5, 1, 6 );
insert into employee values ( 4, 2, null );
insert into employee values ( 3, 1, 4 );
insert into employee values ( 2, 0, 3 );
insert into employee values ( 1, 0, 3 );
insert into employee values ( 0, 0, 4 );
exit
/
我不知道“新”是从哪里来的,我想这可能会导致你的错误。它应该是别名吗?如果您标记Oracle,可能会得到更多帮助。将
new
替换为:new
;查询前检查:new.SpervisiorID是否为NULL
;如有必要,处理“未找到行”异常。如果从sqlplus运行,请键入show errors
,以在编译触发器后获取有关错误的更多详细信息。是否有名为old
或new
的字段?显示错误的结果是什么?
SQLcl: Release 4.2.0.15.295.1605 RC on Tue Dec 08 17:07:23 2015
Copyright (c) 1982, 2015, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Table EMPLOYEE dropped.
Table EMPLOYEE created.
Trigger SUPERVISORS compiled
Error starting at line : 36 in command -
insert into employee values ( 6, 1, null )
Error report -
SQL Error: ORA-20006: Cannot insert/update record into table Employee. Required supervisor ID is missing.
ORA-06512: at "APPS.SUPERVISORS", line 5
ORA-04088: error during execution of trigger 'APPS.SUPERVISORS'
Error starting at line : 37 in command -
insert into employee values ( 5, 1, 6 )
Error report -
SQL Error: ORA-20005: Cannot insert/update record into table Employee. Supervisor ID not found.
ORA-06512: at "APPS.SUPERVISORS", line 13
ORA-04088: error during execution of trigger 'APPS.SUPERVISORS'
1 row inserted.
1 row inserted.
1 row inserted.
1 row inserted.
Error starting at line : 42 in command -
insert into employee values ( 0, 0, 4 )
Error report -
SQL Error: ORA-20004: Cannot insert/update record into table Employee. Employee rank is not valid for given supervisor.
ORA-06512: at "APPS.SUPERVISORS", line 17
ORA-04088: error during execution of trigger 'APPS.SUPERVISORS'
Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options