日期:2014-05-17  浏览次数:20933 次

oracle触发器 修改后触发删除操作:当修改一个表中的某一个字段为1后,删除该表中该字段为 -1的记录
本帖最后由 feixiang136136 于 2011-05-25 13:19:23 编辑
 oracle触发器 修改后触发删除操作:当修改一个表中的某一个字段为1后,删除该表中该字段为 -1的记录 

例如:
CREATE TABLE TITLE_STUDENT 
   ( id Number  not null primary key
                titleId NUMBER, 
studentId NUMBER, 
titleName VARCHAR2(20), 
tutype NUMBER
     );
create or replace  trigger deleteFirst
 before  update  on title_student
 referencing old as old_value
     new as new_value
 for each row
 when (new_value.tutype=1 )
begin
  delete from title_student  where studentId=:old_value.studentId and tutype=0;
end;
我这么写的

然后我执行
update title_student set tutype=1 where titleId=82 and studentId=2;
总是报错误:
[SQL] update title_student set tutype=1 where titleId=82 and studentId=2
[Err] ORA-04091: 表 BYSJ.TITLE_STUDENT 发生了变化, 触发器/函数不能读它
ORA-06512: 在 "BYSJ.DELETEFIRST", line 2
ORA-04088: 触发器 'BYSJ.DELETEFIRST' 执行过程中出错

------解决方案--------------------
一般来说,在本表上的触发器内部修改或删除本表数据,由于ORACLE一致性是不允许的,
尽量不要这样操作。
CREATE OR REPLACE TRIGGER deleteFirst
  BEFORE UPDATE ON title_student
  REFERENCING OLD AS old_value NEW AS new_value
  FOR EACH ROW
  WHEN (new_value.tutype = 1)
DECLARE
  PRAGMA AUTONOMOUS_TRANSACTION;--自治事务
BEGIN
  DELETE FROM title_student
   WHERE studentId = :old_value.studentId
     AND tutype = 0;
  COMMIT;--提交自治事务
END;
/

------解决方案--------------------
如果确要删除,可以使用自治事务。如上例。
------解决方案--------------------
自治事务,使用时千万要小心!
自治事务,即强大又危险!
------解决方案--------------------
ORA-00060: 等待资源时检测到死锁
你这次是碰到了死锁,你请求的资源被锁定了。
自治事务不是不能用,用时一定要细心
------解决方案--------------------
1、不要期待在一外触发器中完成所有业务。
2、象这种需求,最好在业务侧来完成。
3、建议一般可不用外键来保证完整性,如果外键上没有建立索引,
     可能造成性能问题。