如果A表用触发器:new的方式不能取得更新值,因为要读的是另一个表的列,不是本表的,要从另一个表B用select方法取出来的记录而A表触发器事件是由B表触发出来的,这样如何从A表触发器取出B表新的update记录数据???不知道我说清楚没有,过程就是:B表有after update、after insert触发器,引发把B表的该条更新记录B_ID字段写入 A表,记录B表的主键B_ID字段和更新时间,A表的after insert触发器,想跟据写入的B表B_ID字段从B表中取出更新后的这条记录,更新写入C表
code:select B_ID,b1,b2 form B into v_b_id,v_b1,v_b2 where B_ID=:new.A_ID;update c set c1=v_b1,c2=v_b2  where c.c_id=v_b_id;
or
insert into c(c_id,c1,c2) values(v_b_id,v_b1,v_b2);因为业务要求必须要经过中间表A表来处理,不能直接从B表触发写入C表。现在问题是B表 after insert触发的新增记录可以经中间表A写入C表,没有问题,可B表after update触发的更新记录经中间表A写入C表的是更新前的,不是更新后的记录!!!我在B表、A表都加上了自冶事务PRAGMA   AUTONOMOUS_TRANSACTION;
每个update 语句后紧跟commit; 也没用,更新到的还是旧记录,不是更新后的记录!!!why?请教各大侠有没有办法!

解决方案 »

  1.   

    1、对于A的触发器不恰当,应该由B表的触发器调用一个更新A、C的存储过程实现。
    里有,如果其他的方式插入A表,B表的内容没有变化,A表的触发器如何处理?
    2、这种方式本身思路就存在问题,对于A表的触发器只关心发生在A表的操作,不会关心是哪个触发器对A表执行了插入操作。建议在B表的触发器中调用存储过程更新A、C。
      

  2.   

    谢谢楼上的 实际上我就是用存储过程更新A、C的,只是为了方便大家看 我省略了很多内容,只是描述了大概原理确实对于A表的触发器只关心发生在A表的操作,不会关心是哪个触发器对A表执行了插入操作。 但要写入C表的数据必须从B表读出来还有一点我想没有说清楚,实际上读取数据时是从与B表一样结构的视图中取的数据view_b
    CREATE FORCE VIEW view_b as select b_id,b1,b2 from B;现在有记录写入B表时, 用存储过程写入C表是没有问题的,
    CREATE OR REPLACE PROCEDURE pro_ADD (p_b_id in VARCHAR2)
    as
     v_b1 varchar2(20);
     v_b2 varchar2(20);
    begin   select  b1,b2 form view_b into  v_b1,v_b2 where b_id=p_b_id; 
       --这里能取到新加的记录
       insert into c(c_id,c1,c2) values(p_b_id,v_b1,v_b2); 
       commit;end;当有记录更新B表时, 用存储过程更新C表时就取不了更新的内容了,
    CREATE OR REPLACE PROCEDURE pro_MODIFY (p_b_id in VARCHAR2)
    as
     v_b1 varchar2(20);
     v_b2 varchar2(20);
    begin   select  b1,b2 form view_b into  v_b1,v_b2 where b_id=p_b_id;
       --应该就是在这里取不到更新后的内容,现在取出来的是旧的内容   update c set c1=v_b1,c2=v_b2  where c.c_id=p_b_id; 
       commit;end;
      

  3.   

    可B表after update触发的更新记录经中间表A写入C表的是更新前的,不是更新后的记录!!! update触发要从:OLD取B_ID,而不是从:NEW中
      

  4.   


    B_ID是主键 更新记录时是不会变的
      

  5.   

    表的触发器内不允许对本表进行查询,好像在由触发起调用的存储过程中也不行。
    所以,干脆直接把处理写在B标的触发器里
    create or replace .....
    insert into c(...) values(:new.XXX,:new.YYY)
    ...
      

  6.   


    现在我也在往这方面想,只有在B表视图上建触发器了
    CREATE OR REPLACE TRIGGER  TRI_VIEW_B_UPDT
    INSTEAD OF UPDATE ON  VIEW_B
    REFERENCES OLD AS OLD NEW AS NEW 
    FOR EACH ROW
    declare
    PRAGMA   AUTONOMOUS_TRANSACTION;
    begin
      update c set c1=:NEW.b1,c2=:NEW.b2  where  c_id=:NEW.b_id; 
      commit; end;
      

  7.   

    看来最后还是要用:NEW 才行,这样的话对于要取得更新后不在触发器本表或视图的数据还是取不到的了,只有逐个表的写触发器这样对于想把多个表的更新信息都放在一个中间表,记录每个表更新时的表名、记录编号、更新时间,然后只用中间表触发器从各更新表中取出更新后的数据进行业务计算后写对相应的第三个表是做不到了不知道我这样理解对不对
      

  8.   

    多个表不可能同时更新,必然有先后顺序。
    触发起的:new指针对本表,并且在更新完成后不可能保存。
    更不可能去取得别的表曾经有过的更改情况,这些东西是要放到redo和撤销表空间(或者回滚段)里的。
    所以你的这个想法不太现实。
      

  9.   

    同时这类问题也应该是别人还没有commit 触发器如何读取脏数据的问题
      

  10.   


    没错多个表是不同时更新,
    我只想一个表B更新后通过after update触发器写到中间表A,(这个时候去读表B的应该是更新后的数据吧,事实上可能就是这里不能取到更新后的数据) 再通过中间表A after update触发器 从触发这个update行为的B表中取出更新后的数据,同步更新到C表同样
    一个表B插入后通过after insert触发器写到中间表A,(这个时候去读表B是可以读到插入后的数据) 再通过中间表A after insert触发器 从触发这个insert行为的B表中取出插入后的数据,同步插入到C表现在插入记录是可以的,更新记录时只能更新到旧的记录,不能更新到更新后的记录(应该是触发器里不能读出更新后的数据)