--测试表
create table TEST_A
(
  qybm VARCHAR2(100),
  qymc VARCHAR2(100),
  xsbm VARCHAR2(100),
  hy   VARCHAR2(100),
  km   VARCHAR2(100),
  se   NUMBER,
  rq   DATE
)--触发器,实现功能:当新的数据插入时,如果新数据的XSBM字段有变化,更新以前的数据为新的XSBM值
create or replace trigger TRI_TEST_A
  before insert on TEST_A   
  for each row
declare
  xsbm varchar2(100);
begin
  select distinct a.xsbm into xsbm from test_a a where a.qybm = :new.qybm;
  
  IF xsbm <> :new.xsbm THEN 
     update test_a a SET a.xsbm = :new.xsbm where a.qybm = :new.qybm; 
  END IF;
  
end TRI_TEST_A;报错:ORA-04091大家谁知道怎么解决啊?

解决方案 »

  1.   

    -- 这样的操作最好用 merge into-- merge into 的功能是有则更新,没有则插入!
    -- 所谓“有”,即:原表中已经存在一条符合条件(这个符合条件,什么样的条件,由你自己来定)的记录,则更新些记录,此时不再插入记录!
    -- 所谓“没有”,即:原表中找不到一条符合条件(这个符合条件,什么样的条件,由你自己来定)的记录,则插入此记录!
      

  2.   

    select distinct a.xsbm into xsbm from test_a a where a.qybm = :new.qybm;这里,如果新插入的QYBM不存在,执行就会报错了。。所以需要先判断。。
      

  3.   

    merger into TEST_A a 
    using (select ..) bon a.qybm=b.qybmwhen matched then insert 
    when not matched then update set xsbm = b.xsbm 
      

  4.   

    感谢大家帮忙,由于实际原因,不能采用MERGE方法,
    2楼的说法也不完全,我查过资料,ORACLE在行触发器中不能查询当前表
    大家说用触发器能实现吗?
      

  5.   


    不能实现,使用自治事务,update易造成死锁!!
      

  6.   

    SQL> create table t_test_tri
      2  (id number primary key,
      3   name varchar2(10),
      4   count number);
     
    Table created
     
    SQL> 
    SQL> create or replace trigger tri_test
      2    before insert on t_test_tri
      3    for each row
      4  declare
      5  PRAGMA AUTONOMOUS_TRANSACTION;
      6  v_cnt number;
      7  begin
      8   select count(*)+1 into v_cnt from t_test_tri where name=:new.name;
      9   if v_cnt>1 then
     10     update t_test_tri set count=v_cnt where name=:new.name;
     11   end if;
     12   commit;
     13   :new.count:=v_cnt;
     14  end tri_test;
     15  /
     
    Trigger created
     
    SQL> insert into t_test_tri(id,name) values(1,'a');
     
    1 row inserted
     
    SQL> insert into t_test_tri(id,name) values(2,'a');
     
    1 row inserted
     
    SQL> insert into t_test_tri(id,name) values(3,'b');
     
    1 row inserted
     
    SQL> select * from t_test_tri;
     
            ID NAME            COUNT
    ---------- ---------- ----------
             1 a                   1
             2 a                   1
             3 b                   1
     
    SQL> commit;
     
    Commit complete
     
    SQL> insert into t_test_tri(id,name) values(4,'a');
     
    1 row inserted
     
    SQL> commit;
     
    Commit complete
     
    SQL> select * from t_test_tri;
     
            ID NAME            COUNT
    ---------- ---------- ----------
             1 a                   3
             2 a                   3
             3 b                   1
             4 a                   3
     
    SQL> 
      

  7.   

    上面的代码你可能注意到了,尽管id=1和2的数据都是插入的'a',但是count依然是1,因为异步事务是脱离当前事务进行处理的,此时主事务尚未提交,所以自治事务无法看到当前事务中的数据,所以count依然是1.