需求为:当向表中插入数据时,先判断该行数据ID是否在表中已存在,如存在,则仅update数据列(累计数量),否则insert该行例:
表A
ID  数量
1    10insert into A
values(1,5)
insert into A
values(2,5)则需要结果为:
ID  数量
1    15
2    5我现在的解决方法是在表A上建立一个同结构的视图,然后在视图上建立instead of insert触发器。在向视图中insert的时候进行判断,根据判断结果决定是执行insert操作,还是update操作。但是在实际使用中发现向视图中insert的效率远低于直接向表中insert的效率(即使没有触发器也是如此)因此希望可以通过直接建立表的触发器达到这一效果,目前碰到的问题主要有:oracle不支持表的instead of触发器,如使用before触发器,又不能在触发器中直接对本表进行操作(即无法达到update的目的)。或者有什么办法可以提高向视图中插入数据的效率也可。希望高手能提供一些思路,不胜感激。

解决方案 »

  1.   

    需求为:当向表中插入数据时,先判断该行数据ID是否在表中已存在,如存在,则仅update数据列(累计数量),否则insert该行 例: 
    表A 
    ID     数量 
    1         10 insert   into   A 
    values(1,5) 
    insert   into   A 
    values(2,5) 则需要结果为: 
    ID     数量 
    1         15 
    2         5 
    --使用存储过程也行.
    create procedure my_proc @id int
    as 
    begin
      if not exists(select 1 from tb where id = @id) --不存在
         insert into ...
      else 
        update tb ...
    end
    goexec my_proc id
      

  2.   

    呃。。可是我在哪调用存储过程呢。。
    表A的before insert触发器里么?那不会死循环么
    因为在存储过程里又insert
      

  3.   

    晕,我就是要实时改变表的插入行为。总不能所有insert这个表的地方都改成调用存储过程吧
    那要是批量插入数据不是疯了。
      

  4.   

    1、要么你在插入记录前 判断
    2、要么保存插入的ID唯一,可以通过sequences做
      

  5.   

    使用Exception即可。create table a (a number primary key,b number);insert   into   A values(1,5) ;
    insert   into   A values(2,5) ;commit;declare
      new_a number:=1;
      new_b number:=10;
    begin
      insert into a values(new_a,new_b);
      commit;
    exception
      when DUP_VAL_ON_INDEX then
        update a
          set a.b=a.b+new_b
        where a.a=new_a;
        commit;  
      when others then
        rollback;
    end;select * from a;--drop table a;
      

  6.   

    楼上各位的方法貌似都不能满足我的需求
    后来自己查到一个方法:oracle9以上的版本的话,可以考虑使用“merge into”语法
    使用如下:
    MERGE <hint> INTO <table_name>
    USING <table_view_or_query>
    ON (<condition>)
    WHEN MATCHED THEN <update_clause>
    WHEN NOT MATCHED THEN <insert_clause>; 
    CREATE TABLE employee (
    employee_id NUMBER(5),
    first_name  VARCHAR2(20),
    last_name   VARCHAR2(20),
    dept_no     NUMBER(2),
    salary      NUMBER(10))
    TABLESPACE data_sml;INSERT INTO employee VALUES (1, 'Dan', 'Morgan', 10, 100000);
    INSERT INTO employee VALUES (2, 'Jack', 'Cline', 20, 100000);
    INSERT INTO employee VALUES (3, 'Elizabeth', 'Scott', 20, 50000);
    INSERT INTO employee VALUES (4, 'Jackie', 'Stough', 20, 40000);
    INSERT INTO employee VALUES (5, 'Richard', 'Foote', 20, 30000);
    INSERT INTO employee VALUES (6, 'Joe', 'Johnson', 20, 70000);
    INSERT INTO employee VALUES (7, 'Clark', 'Urling', 20, 90000);
    COMMIT;CREATE TABLE bonuses (
    employee_id NUMBER, bonus NUMBER DEFAULT 100)
    TABLESPACE data_sml;INSERT INTO bonuses (employee_id) VALUES (1);
    INSERT INTO bonuses (employee_id) VALUES (2);
    INSERT INTO bonuses (employee_id) VALUES (4);
    INSERT INTO bonuses (employee_id) VALUES (6);
    INSERT INTO bonuses (employee_id) VALUES (7);
    COMMIT;MERGE INTO bonuses B
    USING (
      SELECT employee_id, salary
      FROM employee
      WHERE dept_no =20) E
    ON (B.employee_id = E.employee_id)
    WHEN MATCHED THEN
      UPDATE SET B.bonus = E.salary * 0.1
    WHEN NOT MATCHED THEN
      INSERT (B.employee_id, B.bonus)
      VALUES (E.employee_id, E.salary * 0.05);结贴了。