Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在项目插入后更新订单的总和_Sql_Oracle - Fatal编程技术网

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

Sql 在项目插入后更新订单的总和,sql,oracle,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)) 我希望这能澄清这张桌子的样子。没有添加所有其他属性,因为我认为它

嗨,我不知道该怎么做,因为我是sql和数据库的新手。我在理解触发器中的每一行是如何工作的方面有点困难。基本上我有3个表,它们在这个触发器中很重要

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

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

Bought(Item_ID (pk), Receipt_ID (pk))
我希望这能澄清这张桌子的样子。没有添加所有其他属性,因为我认为它们并不重要。基本上,我想对触发器做的是,如果我在bunded中插入一个元素,我会将该元素的价格添加到收据的总和中。但在这一点上,我不太确定如何做到这一点

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

BEGIN
  UPDATE Receipt
  SET total_sum = total_sum + 
  WHERE
END;

这就是我被困的地方

我相信你想要新的:

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;

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

正如@Gordon Linoff已经指出的那样,您需要
:new
来实现您想要的,并且您还需要在触发器中处理删除和更新。但是,解决方案并不是真正安全的,因为如果在短时间内有许多插入、更新和删除,则有可能在最新事件之后运行较旧的事件。为了应对这种情况,您可能需要完全计算触发器中的和,而不是向和中添加数字。您可以为此定义一个存储过程,该存储过程将根据实际金额更新收据

但是,这种想法可能会给数据库带来很多过载,因此最好不要为此使用触发器,而是实现一个存储过程,该过程将进行必要的更新,并在cron作业中每分钟调用一次。此解决方案的优点是,您有一个相当新的值,最长为一分钟,不会对您的性能产生负面影响。它的缺点是不能实时更新值。如果缺点太大,则在需要实时值的特定情况下,可以调用此存储过程


进一步的改进是为
收据
设置一个
to_update
列,并设置insert/update/delete触发器更新此特定值,以标记需要更新的内容,并仅更新待更新的记录。如果您选择这种方法,请不要忘记将
实际更新为\u update
,以确保您不会总是
更新自那时以来已更新且未更改的值。

您的模式相当清晰,但您可以与我们共享任何代码吗?存储订单的总和将是一个设计错误(传递依赖项). 你应该搜索并阅读关于“normalization”@iDevlop是的,我知道是这样的,但是因为我会经常使用总和,所以我认为把它作为一个函数会很好attribute@TimBiegeleisen嗨,我刚开始更新了它,我没有分享它,因为我很快就被卡住了,并且认为即使触发器逻辑正确,也不会有多大帮助,我不确定。相反,您可能倾向于在事务中运行这两个插入。答案不错,但我相信在并发的情况下,这可能无法产生正确的结果。当较旧记录的插入触发器在较新的插入触发器之前运行时,可以向不推荐的值添加一个数字。更安全的做法是不要假设total_sum是新的,而是进行整个计算。它可能会严重影响性能,因此触发器也不一定是您所指出的最佳选择。