Board logo

标题: [求助]一个触发器的问题!!! [打印本页]

作者: wenisun    时间: 2007-3-28 11:55     标题: [求助]一个触发器的问题!!!

写了个触发器,能创建成功,不过出现:
ORA-04091 特征:触发器工作不正常 原因:一个行触发读取或修改变化的表(正在修改、插入)时,产生这种错误。
---------------
具体如下:
create or replace trigger TR_A  after delete on table_1   for each row
declare
  total number;--用来记录删除该记录后表的总数
begin
  select count(*) into total from table_1;
end TR_A;
---------------
其实我就是想取得删除一条记录后这个表的行数(用到触发器来实现),这个问题,我应该怎么做啊?
作者: valenwon    时间: 2007-3-28 12:32

使用行级触发器,导致的变异表错误。
去掉 for each row
作者: wenisun    时间: 2007-3-28 13:13

create or replace trigger TR_A
  after delete on table_1  
  for each row
declare
  -- local variables here
  x number :=1;--用来记录被更改后的序号值
  y number :=2;--用来记录需要被更改的序号值
  total number;--用来记录该表删除后的总数
  mark_1 number;--用来记录是否有该序号值。0:表示没有;1:表示有
  mark_2 number;--用来记录是否有该序号值。0:表示没有;1:表示有
begin
  --以下删除与table_2表(table_2)相关的记录
  delete from table_2 a where a.khgx_id = :old.khgz_id;
  
  --以下更改table_1表(table_1)中的序号
  --其作用是当该表的数据删除后能让表的序号能够连续
  select count(*) into total from table_1;
  loop
      exit when x>total;
      select count(*) into mark_1 from table_1 where xh=x;
      if mark_1=0 then
         select count(*) into mark_2 from table_1 where xh=y;
         if mark_2!=0 then
            update t_khgx set xh=x where xh=y;
            x:=x+1;
            y:=y+1;
         else
             y:=y+1;
         end if;
      else
          x:=x+1;
          y:=y+1;
      end if;
  end loop;
end TR_A;
-------------------
删去for each row后,就不能引用:new 和:old 了...
作者: valenwon    时间: 2007-3-28 13:51

建两个触发器
在行级触发器,用全局变量记录下:new :old(例如pkg_test.x := :new.x)
在语句级别触发器,里面做你要做的事情,使用pkg_test.x
作者: wenisun    时间: 2007-3-28 14:53

最后我建了两个触发器来分别执行,具体如下:
create or replace trigger TR_A
  after delete on table_1  
  for each row
declare
  -- local variables here
begin
  --以下删除与table_2表(table_2)相关的记录
  delete from table_2 a where a.khgx_id = :old.khgz_id;
end TR_A;
-------------------
create or replace trigger TR_B
  after delete on table_1  

declare
  -- local variables here
  x number :=1;--用来记录被更改后的序号值
  y number :=2;--用来记录需要被更改的序号值
  total number;--用来记录该表删除后的总数
  mark_1 number;--用来记录是否有该序号值。0:表示没有;1:表示有
  mark_2 number;--用来记录是否有该序号值。0:表示没有;1:表示有
begin
  
  --以下更改table_1表(table_1)中的序号
  --其作用是当该表的数据删除后能让表的序号能够连续
  select count(*) into total from table_1;
  loop
      exit when x>total;
      select count(*) into mark_1 from table_1 where xh=x;
      if mark_1=0 then
         select count(*) into mark_2 from table_1 where xh=y;
         if mark_2!=0 then
            update t_khgx set xh=x where xh=y;
            x:=x+1;
            y:=y+1;
         else
             y:=y+1;
         end if;
      else
          x:=x+1;
          y:=y+1;
      end if;
  end loop;
end TR_B;
------------
这样已经达到我的要求了,至于版主的方法,一会试试。先谢谢版主!!!




欢迎光临 CNOUG (http://www.oracle.com.cn/) Powered by Discuz! 6.0.0