触发计算小计

时间:2011-12-07 21:14:52

标签: oracle triggers subtotal

我一直在努力实现这个触发器一段时间并且正在取得进展(我想!)但是现在我遇到了突变错误。

我这里有三个实体(这里是相关的),Customer_Order(总等),Order_Line(数量,小计等)和产品(股票,价格)。 Order_line是一个链接实体,因此产品可以在许多order_lines中,customer_order可以有许多order_lines,但order_line只能在订单中出现一次,并且只能包含一个产品。触发器的目的是从order_line(或我实际认为的产品的价格)和order_line的数量中获取小计,将它们相乘并更新新的order_line的小计。

所以我用我的产品外键插入一个order_line,数量为3,价格为4.00,触发器将两个乘以等于12并更新小计。现在,我认为在这里使用price而不是Order_line的小计是正确的,以便修复突变错误(这是因为我要求触发器更新触发语句正在访问的表,对吗?),但是如何我是否修复了数量问题?数量并不总是与库存相同,它必须小于或等于库存,那么有谁知道如何解决这个问题从产品中选择并更新order_line?感谢。

CREATE OR REPLACE TRIGGER create_subtotal  
BEFORE INSERT OR UPDATE ON Order_Line 
for each row
DECLARE 
currentSubTotal order_line.subtotal%type;
currentQuantity order_line.quantity%type;
BEGIN 
select order_line.subtotal,order_line.quantity
into currentSubTotal,currentQuantity
from order_line
where product_no = :new.product_no;
IF (currentquantity>-1 ) then 

update order_line set subtotal= currentSubTotal * currentQuantity where     line_no=:new.line_no;

END IF;
END; 
. 
run

编辑:我想我可以使用:new语法来使用触发语句中的数量值。我会尝试这个,但我仍然感谢您的确认和帮助,谢谢。

2 个答案:

答案 0 :(得分:1)

由于您正在更新表,因此不会发生突变错误;之所以发生这种情况,是因为您正在查询已经更新的表。

如果我正确理解你想做什么:

CREATE OR REPLACE TRIGGER create_subtotal  
BEFORE INSERT OR UPDATE ON Order_Line 
for each row
DECLARE 
  currentPrice  products.price%TYPE;
BEGIN
  -- Get the current price for the product
  SELECT price INTO currentPrice FROM products WHERE product_no = :new.product_no;

  -- Set the new subtotal to the current price multiplied by the order quantity
  :new.subtotal := currentPrice * :new.quantity;
END;
/

(我不清楚为什么你要测试一个低于0的数量,以及在这种情况下你想要发生什么。如果你想在这种情况下将小计设置为NULL或0,那么它应该很容易修改上述内容。)

答案 1 :(得分:1)

听起来你想要像

这样的东西
CREATE OR REPLACE TRIGGER create_subtotal
  BEFORE INSERT OR UPDATE ON order_line
  FOR EACH ROW
DECLARE
  l_price products.price%type;
BEGIN
  SELECT price
    INTO l_price
    FROM products
   WHERE product_no = :new.product_no;

  IF( :new.quantity > -1 )
  THEN
    :new.subtotal := :new.quantity * l_price;
  END IF;
END;

但是,如果这不是家庭作业,那么从这个触发器中的PRODUCTS表中提取价格并没有多大意义。据推测,产品的价格会随着时间的推移而变化。但是,当下订单时,特定订单的价格是固定的。如果触发器仅在INSERT上定义,那么获取当前价格可能是合理的。但是,如果您想在更新行时重新计算行的小计,则需要在订单下达时获取价格(并假设您不会向不同的客户收取相同的价格)时间)。

从标准化的角度来看,首先存储计算字段也没有意义。将数量和价格存储在order_line表中然后计算视图中行的小计(或者,如果您使用11g,作为表中的虚拟列)将更有意义。