需求为:当向表中插入数据时,先判断该行数据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的目的)。或者有什么办法可以提高向视图中插入数据的效率也可。希望高手能提供一些思路,不胜感激。
表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的目的)。或者有什么办法可以提高向视图中插入数据的效率也可。希望高手能提供一些思路,不胜感激。
表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
表A的before insert触发器里么?那不会死循环么
因为在存储过程里又insert
那要是批量插入数据不是疯了。
2、要么保存插入的ID唯一,可以通过sequences做
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;
后来自己查到一个方法: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);结贴了。