我有一个表ORDER_HISTORY,我希望在插入之后,customer_id和totalcost的总和基于要插入MAIN_ORDER的customer_id
ORDER_HISTORY表:
History_id | customer_id | totalcost
---------------------------------------
1 | 1000 | 100
2 | 1000 | 200
3 | 2000 | 50
4 | 2000 | 50
我希望在触发器触发后,Main_order显示这些数据:
MAIN_ORDER表:
customer_id | order_price
-------------------------
1000 | 300
2000 | 100
我创建了以下触发器但是我有一条错误消息
CREATE TRIGGER triggerHIS
AFTER INSERT ON ORDER_HISTORY FOR EACH ROW
BEGIN
INSERT INTO MAIN_ORDER (CUSTOMER_ID,ORDER_PRICE)
SELECT CUSTOMER_ID, SUM(TOTALCOST) as ORDER_PRICE
FROM ORDER_HISTORY
GROUP BY CUSTOMER_ID;
END;
错误信息是:
One error saving changes to table "PR"."ORDER_HISTORY":
Row 4: ORA-04091: table PR.ORDER_HISTORY is mutating, trigger/function
may not see it
ORA-06512: at "PR.TRIGGERHIS", line 3
ORA-06512: at line 1
答案 0 :(得分:1)
对于这种情况,为了避免错误table mutating
oracle有compound trigger
。
你可以用这种方式编写你的触发器。
create or replace trigger TR_ORDER_HISTORY
for insert on ORDER_HISTORY
compound trigger
type t_recs is table of number index by pls_integer;
pt_Ins t_recs;
li_Ins pls_integer := 0;
after each row is
begin
li_Ins := li_Ins + 1;
pt_Ins(li_Ins) := :new.customer_id;
end after each row;
after statement is
begin
for li in 1 .. pt_ins.count loop
update MAIN_ORDER
set ORDER_PRICE =
(select sum(TOTALCOST)
from ORDER_HISTORY
where customer_id = pt_ins(li)
group by customer_id)
where customer_id = pt_ins(li);
if sql%rowcount = 0 then
insert into MAIN_ORDER
(CUSTOMER_ID, ORDER_PRICE)
select customer_id, sum(TOTALCOST)
from ORDER_HISTORY
where customer_id = pt_ins(li)
group by customer_id;
end if;
end loop;
end after statement;
end;
答案 1 :(得分:-1)
您可以使用触发器维护值:
CREATE TRIGGER triggerHIS
AFTER INSERT ON ORDER_HISTORY FOR EACH ROW
DECLARE
v_cnt := int;
BEGIN
SELECT COUNT(*) INTO v_cnt FROM MAIN_ORDER WHERE CUSTOMER_ID := NEW.CUSTOMER_ID;
IF V_CNT > 0 THEN
UPDATE MAIN_ORDER
SET ORDER_PRICE = ORDER_PRICE + :NEW.TOTALCOST
WHERE CUSTOMER_ID := :NEW.CUSTOMER_ID;
ELSE
INSERT INTO MAIN_ORDER(CUSTOMER_ID, ORDER_PRICE)
SELECT :NEW.CUSTOMER_ID, :NEW.TOTALOST
FROM DUAL;
END;
END;