绕过 Oracle 中的变异触发器

Bypass mutating trigger in Oracle

我有两个table;在更新 table 1(购买的汽车)时,我需要用特定客户购买的汽车总数更新另一个 table。

当我尝试时,我遇到了一个变异触发器。我试图将其转换为复合触发器,但是我遇到了大量错误、空索引等。

detail_table:

+-----------+---------+--------+------+------+
| customore | car     | number | cost | sold |
+-----------+---------+--------+------+------+
| josh      | mustang | 2      | 5    | y    |
| josh      | ford    | 3      | 2    | y    |
| josh      | tesla   | 1      | 3    | n    | -->to update to y
| john      | chevy   | 4      | 1    | y    |
| john      | chevy   | 5      | 2    | y    |
+-----------+---------+--------+------+------+

在将 sold 从 n 更新为 y 时,行必须汇总并汇总到此摘要中 table

summary_table

  +----------+------------+------------+
  | customer | total cars | total cost | 
  +----------+------------+------------+
  | josh     | 5          | 7          | -- > before update  on detail
  +----------+------------+------------+

  +----------+------------+------------+
  | customer | total cars | total cost | 
  +----------+------------+------------+
  | josh     | 6          | 10         | -- > after update on detail
  +----------+------------+------------+

最后,当用户将 n 更新为 y 时,josh.total 辆汽车应该变为 1,总成​​本为 10

触发码

CREATE OR REPLACE TRIGGER update_summary_table
    AFTER UPDATE ON detail_table FOR EACH ROW 
    referencing old as old new as new
begin
    
     for i in (select sum(number) s_car, sum(cost) s_cost
               from detail_table 
               where  customer = :new.customer
                 and sold = 'y') loop

update summary_table
set total_cars = i.s_car,
   total_cost = i.s_cost
where customer = :new.customer;

end loop;
end;
end update_summary_table;

为什么要为此使用 for 循环?只需使用一次更新:

update summary_table
    set total_cars = coalesce(total_cars, 0) + :new.number - :old.number,
        total_cost = coalesce(total_cost, 0) + :new.cost - :old.cost
    where customer = :new.customer;

这会对摘要进行增量更改,而不是完全重新计算行。

使用 coalesce() 是为了防止没有为新行提供默认值。