现有foo表,表结构如下
字段 A B
1 2010-4-22 11:30:16
100 2010-3-22我想实现的功能是在对表foo进行insert和update时,如果A的值是‘1’的话,B的值自动更新为当前日期我写的触发器如下:
CREATE OR REPLACE TRIGGER AIUFER_FOO
BEFORE INSERT OR UPDATE
ON FOO
FOR EACH ROW
DECLARE
FOO_COUNT INT;
BEGIN
SELECT COUNT(*) INTO FOO_COUNT FROM FOO
WHERE :NEW.A=1;
IF FOO_COUNT>0 THEN
:NEW.B:=SYSDATE;
END IF;
END;编译没有错误我执行如下语句时
INSERT INTO FOO VALUES(1,TO_DATE('20100305','YYYY-MM-DD'))
是正确的,b字段的值自动更新为当前日期但是当我执行
UPDATE FOO SET A=1
就会出现如下错误:
ORA-04091:表abc.foo发生了变化,触发器和函数不能读等错误
请问这时什么原因,是触发器写的不正确吗?如果要实现上述的功能应该怎么写呢??
先谢谢各位了啊!!
字段 A B
1 2010-4-22 11:30:16
100 2010-3-22我想实现的功能是在对表foo进行insert和update时,如果A的值是‘1’的话,B的值自动更新为当前日期我写的触发器如下:
CREATE OR REPLACE TRIGGER AIUFER_FOO
BEFORE INSERT OR UPDATE
ON FOO
FOR EACH ROW
DECLARE
FOO_COUNT INT;
BEGIN
SELECT COUNT(*) INTO FOO_COUNT FROM FOO
WHERE :NEW.A=1;
IF FOO_COUNT>0 THEN
:NEW.B:=SYSDATE;
END IF;
END;编译没有错误我执行如下语句时
INSERT INTO FOO VALUES(1,TO_DATE('20100305','YYYY-MM-DD'))
是正确的,b字段的值自动更新为当前日期但是当我执行
UPDATE FOO SET A=1
就会出现如下错误:
ORA-04091:表abc.foo发生了变化,触发器和函数不能读等错误
请问这时什么原因,是触发器写的不正确吗?如果要实现上述的功能应该怎么写呢??
先谢谢各位了啊!!
解决方案 »
- 关于表之间数据一致性的问题,求解答
- 我建了一个表,怎么才能看它的表空间
- Mysql内置函数对应Oracle的内置函数
- oracle 外键约束加触发器问题?
- 如何通过NAT访问oracle?
- 触发器创建或者修改dblink问题
- oracle 触发器问题——急求
- 分区表上建普通索引
- 请问:把用户u1中的所有对象的所有操作授权给u2的语句是什么?
- SELECT CITYCODE into d_qsd FROM XCSDM where citytel=p_qsd;如果查不出记录赋给d_qsd 程序就会报错,怎么进行错误处理?
- 不显示删除回复显示所有回复显示星级回复显示得分回复 创建触发器时报ORA-04098: 触发器 'DANNY.DE_TRI' 无效且未通过重新确认的错
- 如何在oracle查询后生成文本文件
CREATE OR REPLACE TRIGGER AIUFER_FOO
BEFORE INSERT OR UPDATE
ON FOO
FOR EACH ROW
BEGIN
IF :NEW.A = 1 THEN
SELECT SYSDATE INTO :NEW.B FROM DUAL;
END IF;
END;
这样应该可以了,你试试。
CREATE OR REPLACE TRIGGER AIUFER_FOO
BEFORE INSERT OR UPDATE
ON FOO
FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
FOO_COUNT INT;
BEGIN
SELECT COUNT(*) INTO FOO_COUNT FROM FOO
WHERE :NEW.A=1;
IF FOO_COUNT>0 THEN
:NEW.B:=SYSDATE;
END IF;
END;
谢谢各位了啊,我在加分!
WHERE :NEW.A=1;
IF FOO_COUNT>0 THEN
:NEW.B:=SYSDATE;
END IF;改为 if NEW.A=1 then
:NEW.B:=SYSDATE;
END IF;
所以你不能在修改 :NEW.B 的值了
谢谢各位了啊,我在加分!
没找到这个资料,我瞎说一下:ORACLE有2种读,一种是一致性读(select语句在开始执行时,就确定了SCN, 如果数据块中的SCN比select时的大,就从回滚段中去取数据);一种是块读(BLOCK READ):update 时,where条件读取的是数据块中的的数据,用于处理并发。在after insert的触发器,只涉及一致性读,所以没有问题;在after update的触发器中,由于oracle已经更新了当前数据块中的值,select from FOO 需要一致性读(此时要从回滚段中读数据),此时读的数据已经不是最新的了(即是回滚段中的数据与当前块中的数据不一致),所以ORACLE就报错了那个异常出来,以避免发生脏读。