2013-10-10 146 views
0

我写了一个CREATE TRIGGER,但由于某种原因,我无法让它没有编译器错误。有任何想法吗?下面的代码和错误消息:Oracle中的触发器语句的编译器错误

CREATE OR REPLACE TRIGGER ManagerDeleteTrigger 
AFTER DELETE ON employee1 
REFERENCING 
OLD AS OldRow 
NEW AS NewRow 
FOR EACH ROW 
WHEN(OldRow.FK_EMPLOYEEEMPLOYEEID != NewRow.FK_EMPLOYEEEMPLOYEEID) 
UPDATE employee1 SET FK_EMPLOYEEEMPLOYEEID = null WHERE FK_EMPLOYEEEMPLOYEEID = OldRow.employeeID; 

的错误信息是:

Error(1,105): PLS-00103: Encountered the symbol ";" when expecting one of the following: 
(begin case declare end exception exit for goto if loop mod null pragma raise return select update while with <an identifier> <a double-quoted delimited-identifier> <a bind variable> 
<< continue close current delete fetch lock insert open rollback savepoint set sql execute 
commit forall merge pipe purge The symbol "exit" was substituted for ";" to continue. 

编辑:这里有一个澄清我的问题。我用下面的语句创建一个表。每个员工都有一个经理(由FK代表)。

CREATE TABLE Employee1 
(
    employeeID integer, 
    firstName varchar (255), 
    lastName varchar (255), 
    phone integer, 
    jobTitle varchar (255), 
    payGrade integer, 
    fk_EmployeeemployeeID integer NOT NULL, 
    PRIMARY KEY(employeeID), 
    FOREIGN KEY(fk_EmployeeemployeeID) REFERENCES Employee1 (employeeID) 
); 

我再要创建一个触发器,每当雇员一位改变他JOBTITLE,它发现了一个为他们的经理的所有员工,并将经理字段设置为null。这有意义吗?

回答

2

您错过了实际触发代码周围的BEGIN ... END块。请检查手册,完整的语法记录在那里。

下一个错误是,您不能UPDATE正在更新的表。您只需将新值分配给相关列:

另一个问题是AFTER触发器无法更改任何值,您将需要使用BEFORE触发器。

最后,你为什么要改变DELETE触发器的值?无论如何删除后该行将消失,因此无需更改该值。您可能想要使用UPDATE触发器:

CREATE OR REPLACE TRIGGER ManagerDeleteTrigger 
    BEFORE UPDATE ON employee1 
    REFERENCING OLD AS OldRow 
    NEW AS NewRow 
    FOR EACH ROW 
    WHEN (OldRow.FK_EMPLOYEEEMPLOYEEID != NewRow.FK_EMPLOYEEEMPLOYEEID) 
BEGIN 
    :NewRow.FK_EMPLOYEEEMPLOYEEID := null; 
END; 
/
+0

我早些时候BEGIN/END,但当我看到另一个参考时,我摆脱了它。但是,此代码不起作用,因为它仍然有错误。 此外,它不会做我想要完成的工作,它将FK_EMPLOYEEEMPLOYEEID = OldRow.EmployeeID的所有行都设置为FK_EMPLOYEEEMPLOYEEID = null。 – zaloo

+0

@ user2756569然后你正在做其他的事情,因为代码本身**是**正确的:http://sqlfiddle.com/#!4/5e64d/1你可能想编辑你的问题并描述你的*真实*问题。听起来好像你只是想要一个带有'on update set null'条件的外键约束。但是,如果没有涉及所有表格的定义,并且明确说明您想要达到的目标,那么这只是一个疯狂的猜测。 –

+0

好的,我会先澄清我的问题!编辑:刚刚更新了OP – zaloo

0

尝试将其封装在开始和结束语句中。

CREATE OR REPLACE TRIGGER ManagerDeleteTrigger 
AFTER DELETE ON employee1 
REFERENCING 
OLD AS OldRow 
NEW AS NewRow 
BEGIN 
FOR EACH ROW 
WHEN(OldRow.FK_EMPLOYEEEMPLOYEEID != NewRow.FK_EMPLOYEEEMPLOYEEID) 
UPDATE employee1 SET FK_EMPLOYEEEMPLOYEEID = null WHERE FK_EMPLOYEEEMPLOYEEID = OldRow.employeeID 
END ManagerDeleteTrigger; 
+0

我的代码也出现了编译错误。 错误(2,10):PLS-00103:遇到下列其中一项时遇到符号“ROW”: – zaloo

+0

即使语法正确,触发器也不起作用。您无法更新已触发触发器的表格。 –

+0

不好意思,但是在FOR EACH ROW之后BEGIN下了一行。 a_horse_with_no_name是正确的,你不能更新记录的旧值或新值。请参阅:http://www.techonthenet.com/oracle/triggers/after_delete.php –