免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: duwenhua
打印 上一主题 下一主题

能否在表的触发器中当一记录变化修改另一记录 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2004-06-10 11:47 |只看该作者

能否在表的触发器中当一记录变化修改另一记录

按光明使者老兄的改了,如下:
create or replace trigger U_EQUIPMENT_Essence_TRG1
before update

on U_EQUIPMENT_Essence

for each row

declare
PRAGMA AUTONOMOUS_TRANSACTION;
begin
update u_equipment_essence set
equipment_original_value =equipment_original_value + :new.equipment_original_value
where u_equipment_essence_id = :new.u_main_equipment_essence_id
and u_assembtype ='M';

end U_EQUIPMENT_Essence_TRG1;
但还不行:ORA-00060: 等待资源时检测到死锁
ORA-06512: 在"CQSBGL.U_EQUIPMENT_ESSENCE_TRG1", line 4

论坛徽章:
0
12 [报告]
发表于 2004-06-10 11:49 |只看该作者

能否在表的触发器中当一记录变化修改另一记录

我变动了一下,如下:
create or replace trigger U_EQUIPMENT_Essence_TRG1
before update
of equipment_original_value
on U_EQUIPMENT_Essence

for each row
when (new.u_assembtype ='P')

declare
PRAGMA AUTONOMOUS_TRANSACTION;

begin
update u_equipment_essence set
equipment_original_value =equipment_original_value + :new.equipment_original_value
where u_equipment_essence_id = :new.u_main_equipment_essence_id
and u_assembtype ='M';

end U_EQUIPMENT_Essence_TRG1;
报错是:ORA-06519: 检测到活动的自治事务处理,已经回退
ORA-06512: 在"CQSBGL.U_EQUIPMENT_ESSENCE_TRG1", line 10

论坛徽章:
0
13 [报告]
发表于 2004-06-10 12:09 |只看该作者

能否在表的触发器中当一记录变化修改另一记录

请各位同仁高手发表各种看法见解啊,我是钻破头了啊!有哪位好心人提供专门讲解(oracle) trigger的资料、书籍也好,我去找办法。谢谢大家!

论坛徽章:
0
14 [报告]
发表于 2004-06-10 12:49 |只看该作者

能否在表的触发器中当一记录变化修改另一记录

这种写法的trigger,需要commit,你再试试

论坛徽章:
0
15 [报告]
发表于 2004-08-10 09:37 |只看该作者

能否在表的触发器中当一记录变化修改另一记录

我也碰到了这个问题,请问这个问题最后解决了吗?

论坛徽章:
0
16 [报告]
发表于 2004-08-10 14:55 |只看该作者

能否在表的触发器中当一记录变化修改另一记录

建议对需要实现的业务再次分析,使之能够更便于实现。
对这种会接连触发的操作,一定要十分谨慎,否则避免触发器的更新操作再次触发了触发器的操作。在触发器中造成死循环。

论坛徽章:
0
17 [报告]
发表于 2004-08-10 21:55 |只看该作者

能否在表的触发器中当一记录变化修改另一记录

其实我个人觉得这个问题理论上应该可以解决。
对一个字段的UPDATE操作做触发器监视,触发器中在修改该字段的同时修改另一个触发器不做监视的字段,应该不会再次触发触发器,不会陷入死循环。
不知道是否会有这种比较直接的解决办法。
现在只好利用中间表记录修改情况,再借助后台存储过程的定时执行来更新源表的字段。。。

论坛徽章:
0
18 [报告]
发表于 2004-08-11 18:09 |只看该作者

能否在表的触发器中当一记录变化修改另一记录

You can do:
  1. Rename your table with another name;
  2. Create a view for select * from the table with the original name of the table;
  3. Create a instead of trigger on the view, in the view you can access and update yur base table.


Example of instead of trigger for this case:

[ Code Start ]
create table t1(
  id        number(6)    primary key
,pid       number(6)
,value     number(15,2)
,f1        varchar2(10)
,f2        varchar2(20)
);


create or replace view t1_v as select * from t1;

create or replace trigger bug_t1_v
instead of update on t1_v
for each row
declare
  procedure update_parents(i_id in number, i_value in number);
  procedure update_parents(i_id in number, i_value in number) is
  begin
    declare
      l_pid t1.pid%type;
    begin
      select pid into l_pid
        from t1
       where id = i_id;
      if l_pid <>; 0 then
        update t1 set value = nvl(value,0) + nvl(i_value,0)
         where id = l_pid;
        update_parents(l_pid, i_value);
      end if;
    exception
      when no_data_found then
        null;
    end;      
  end update_parents;
begin
  --
  -- Update Value Field for current record and Parent records
  --
  if nvl(:new.value,0) - nvl(ld.value,0) <>; 0 then
     update t1 set value = value + nvl(:new.value,0) - nvl(ld.value,0)
      where id = :new.id;
     update_parents(:new.id, nvl(:new.value,0) - nvl(ld.value,0));
  end if;
  --
  -- Update Others Fields
  --
  update t1 set f1 = :new.f1
               ,f2 = :new.f2
   where id = :new.id;
end;

--
-- Testing
--
-- With this view: t1_v
--
begin
  for i in 1..50 loop
    Insert into t1_v values(i, i-1, 0, '', '');
  end loop;
end;
/

delete from t1_v;

begin
  for i in 1..50 loop
    Insert into t1_v values(i, i-1, 0, '', '');
  end loop;
end;
/

update t1_v set f1 = 'TEST' where id = 49;


update t1_v set value = value + 5 , f1 = 'AA', F2 = 'BB'
where id = 50;


[ Code End ]

论坛徽章:
0
19 [报告]
发表于 2004-08-11 21:57 |只看该作者

能否在表的触发器中当一记录变化修改另一记录

高手,GOOD IDEA!
这个主意不错,可以借鉴一下,明天去单位试试。
利用这个思想,稍微做一下改动。
源表因为是业务表,不宜做改动,触发器还是建在源表上为好,另外建一个同源视图,赋予它相应的UPDATE权限,在该触发器中再对视图做UPDATE操作更新视图的相应其它字段。。。
还不知道这种方法是否可行,明天试了再回复。。。

论坛徽章:
0
20 [报告]
发表于 2004-08-12 12:47 |只看该作者

能否在表的触发器中当一记录变化修改另一记录

原帖由 "追风篮人" 发表:
高手,GOOD IDEA!
这个主意不错,可以借鉴一下,明天去单位试试。
利用这个思想,稍微做一下改动。
源表因为是业务表,不宜做改动,触发器还是建在源表上为好,另外建一个同源视图,赋予它相应的UPDATE权限,在?.........


应该是不行的.

触发器建在原表上, 触发器执行时, 原表及其视图是不可见的(MUTATING).

所以我给的解决方案中建议:
  1. 改原表名; 2. 用原表名建视图; 3. 建触发器在视图上.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP