在项目插入后更新订单的总和

时间:2017-01-15 12:12:14

标签: sql oracle

嗨我不知道怎么做,因为我是sql和数据库的新手。我在理解触发器中每行的工作方式时遇到了一些麻烦。基本上我有3个表在这个触发器中很重要。

Item(Item_ID (pk), price, ...more attributes )

Receipt( Receipt_ID (pk), total_sum,.. more attributes )

Bought(Item_ID (pk), Receipt_ID (pk))

我希望这可以澄清表格的样子。没有添加所有其他属性,因为我认为它们并不重要。基本上我想用触发器做的是如果我插入一个元素,我会将该元素的价格加到收据的总和中。但我现在还不太清楚如何做到这一点。

CREATE OR REPLACE TRIGGER update_sum
AFTER INSERT ON bought
FOR EACH ROW

BEGIN
  UPDATE Receipt
  SET total_sum = total_sum + 
  WHERE
END;

这就是我被困的地方

2 个答案:

答案 0 :(得分:2)

我相信你想要:new

CREATE OR REPLACE TRIGGER update_sum
AFTER INSERT ON bought
FOR EACH ROW
BEGIN
  UPDATE Receipt
      SET total_sum = (total_sum +
                       (select i.price from items i where i.item_id = :new.item_id)
                      )
      WHERE receipt_id = :new.receipt_id
END;

但是,我建议您在需要时进行计算,而不是存储总和。如果你确实存储了总和,你肯定也需要一个“删除”触发器,可能还有一个“更新”触发器。

答案 1 :(得分:1)

正如@Gordon Linoff已经指出你需要:new来实现你想要的,你还需要在触发器中处理删除和更新。但是,解决方案不是很安全,就好像在短时间内有许多插入,更新和删除一样,有可能在最新事件之后运行较旧的事件。要应对这种情况,您可能需要完全计算触发器中的总和,而不是在总和中添加数字。您可以为此目的定义存储过程,它将根据实际总和更新Receipt。

但是,这个想法可能会为您的数据库带来很多重载,所以最好不要为此目的使用触发器,而是实现一个存储过程,该过程将进行必要的更新并在每分钟调用一次cron job。此解决方案的优势在于,您拥有一个相当新的值,该值最长只有一分钟,并且不会对您的性能产​​生负面影响。它的缺点是你没有真正实时更新值。如果缺点太大,那么当您需要实时值时,可以在特定情况下调用此存储过程。

进一步改进是为to_update添加Receipts列,并使插入/更新/删除触发器更新此特定值以标记需要更新的内容,并且仅update要更新的记录。如果您选择此方法,请不要忘记实际更新to_update,以确保您不会始终update从那时起已经更新和更改的值。