1

我想编写一个触发器,它在从表中删除记录时触发,并在另一个表中插入一条记录并使用已删除记录的详细信息。

数据库:Oracle 10g

我的触发器看起来像这样

CREATE or REPLACE TRIGGER myTrigger
AFTER DELETE
    ON myTable
    REFERENCING NEW AS old_tab
    FOR EACH ROW
BEGIN
    INSERT INTO ACTIVITYLOG values ('ADMIN',:old_tab.tabletID,'MIGRATION','ERROR','TEST','T','NIL',sysdate)
END;

这里:old_tab.tabletID是删除完成tabletID的表的列。myTable我想保存我和它被删除的日志。

但是当我尝试删除记录时,出现以下错误

错误代码 4098,SQL 状态 42000:ORA-04098:触发器 'DB.MYTRIGGER' 无效并且重新验证失败

PS 在 NetBeans SQL 编辑器中创建触发器。

这里是,

编辑

STRUCTURE OF myTable (发生表删除)

tabletID varchar2(15) PRIMARY KEY
tabletName varchar2(100)

结构 ACTIVITYLOG

username varchar2(15)
tabletKey varchar2(15)
page_ref varchar2(100)
errors varchar2(100)
remarks varchar2(100)
operationcode char(2)
lastupdateip varchar2(20)
lastupdatedate date

抱歉,无法访问 SQL PLUS EDITOR。

4

2 回答 2

2

您应该使用 :OLD 值而不是 :NEW 值。DELETE 触发器(无论是 BEFORE 还是 AFTER)中的 :NEW 值为空白。这是有道理的,因为如果您考虑一下,此时该记录在逻辑上已不复存在。

但是,这不是编译错误的来源。

“删除时仍然出现相同的错误。”

我想我们可以花一整天的时间来猜测出了什么问题,所以让我们现在停下来。您可以通过这个简单的查询发现编译错误:

select * from user_errors
where name = 'MYTRIGGER'
and type = 'TRIGGER'

“我将 :NEW 更改为 :OLD,并添加了一个分号并在 SQL PLUS 上运行它,这就成功了”

为了将来的利益,这里有一个触发器版本,它将编译并正确写入所需的值:

CREATE or REPLACE TRIGGER myTrigger 
AFTER DELETE 
    ON myTable 
    REFERENCING OLD AS old_tab 
    FOR EACH ROW 
BEGIN 
    INSERT INTO ACTIVITYLOG values ('ADMIN',:old_tab.tabletID,'MIGRATION','ERROR','TEST','T','NIL',sysdate); 
END; 
/
于 2012-07-24T08:01:37.370 回答
0

问题是这样的:

REFERENCING NEW AS old_tab

您已使用标签“old_tab”重新定义了新值。这有点像添加#define FALSE TRUE到程序的顶部。

semicolon在插入语句之后添加

因为您使用的是 AFTER DELETE 触发器,所以您只需要访问 :OLD 值,例如:

CREATE or REPLACE TRIGGER myTrigger
AFTER DELETE
    ON myTable
    FOR EACH ROW
BEGIN
    INSERT INTO ACTIVITYLOG values ('ADMIN',:OLD.tabletID,'MIGRATION','ERROR','TEST','T','NIL',sysdate);
END;
于 2012-07-24T08:21:57.230 回答