本帖最后由 qq123renmin 于 2012-05-20 16:02:36 编辑 首先有3个表 emp1(和emp一样),emp2(和emp一样),std
std表中的信息,是部门号与该部门的平均工资
创建行级触发器,当在emp1插入信息时,把工资低于所属部门的平均工资的职员信息插入到emp2表中,并且需要将std表中的平均工资每次都更新。
create table std(deptno number(2),sal number(5));
insert into std values(10,2917);
insert into std values(20,2175);
insert into std values(30,1567);
create table emp1
as select * from emp;
create table emp2
as select * from emp;
我写的触发器如下:
create or replace trigger test
after insert on emp1
for each row
declare
v_sal emp1.sal%type;
begin
select sal into v_sal from std where deptno=:new.deptno;
if
:new.sal<v_sal
then
insert into emp2 values(:new.EMPNO,:new.ENAME,:new.JOB,:new.MGR,:new.HIREDATE,:new.SAL,:new.COMM,:new.DEPTNO);
end if;
update std set sal=(select avg(sal) from emp1 group by deptno having deptno=:new.deptno) where deptno=:new.deptno;
end;
测试触发器如下:
insert into emp1 values(1222,'PING','CLERK',2222,to_date('9-27-2006','MM-DD-YYYY'),1900,NULL,20)
但是出错了!错误提示如下:
*
第 1 行出现错误:
ORA-04091: 表 SCOTT.EMP1 发生了变化, 触发器/函数不能读它
ORA-06512: 在 "SCOTT.TEST", line 10
ORA-04088: 触发器 'SCOTT.TEST' 执行过程中出错
我把after改成before就可以成功 不过更新std表的时候慢一步,因为是before触发器嘛,但为什么after就不行呢!
求各位大牛给解释并帮忙解决下
万分感谢!!!!!!!!!
------解决方案--------------------
使用before就可以了吗?
我感觉存在着突变表的问题。
------解决方案--------------------
如果是after ,表示你的触发器是在insert 完 emp1时起作用,此时 emp1应该插入了数据,但未提交,也就是存在了脏数据。而此时触发器里又用到了emp1的查询,emp1数据发生了变化,造成emp1数据不一致。
如果是before,触发器起作用的时间是在Inert emp1前,此时emp1的数据是一致的,不会报错。
个人理解,仅供参考~
------解决方案--------------------
那我想用after做怎么能做对呢!?或者用before也可以,但是before要慢一步嘛 怎么做对呢?@2楼
------解决方案--------------------
那我想用after做怎么能做对呢!?或者用before也可以,但是before要慢一步嘛 怎么做对呢?