【问题标题】:Trigger to calculate subtotal触发计算小计
【发布时间】:2011-12-07 21:14:52
【问题描述】:

我一直在尝试实现此触发器一段时间并且正在取得进展(我认为!)但现在我遇到了一个突变错误。

我在这里拥有的是三个实体(与此处相关),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 并更新小计。现在,我认为在这里使用价格而不是 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 语法来使用触发语句中的数量值。我会试试这个,但我仍然希望得到确认和帮助,谢谢。

【问题讨论】:

    标签: oracle triggers subtotal


    【解决方案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,作为表中的虚拟列)会更有意义。

    【讨论】:

    • 文本+1。 (我没有测试代码。在我早期数据库设计的一个特殊转变中,我只能在家访问 Oracle。)
    【解决方案2】:

    不会发生突变错误,因为您正在更新表;发生这种情况是因为您正在从已更新的表中查询。

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

    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,应该很容易修改上述内容。)

    【讨论】:

      猜你喜欢
      • 2017-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-25
      • 2013-10-15
      • 1970-01-01
      相关资源
      最近更新 更多