触发计算小计

发布于 2024-12-20 00:02:03 字数 1131 浏览 2 评论 0原文

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

我这里有三个实体(与此处相关):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 语法来使用触发语句中的数量值。我会尝试这个,但我仍然希望得到确认和帮助,谢谢。

I've been trying to implement this trigger for a while now and am making progress (I think!) but now I am getting a mutation error.

What I have here is three entities (that are relevant here), Customer_Order(total etc), Order_Line(quantity, subtotal etc) and Products(stock, price). Order_line is a link entity and so a product can be in many order_lines and a customer_order can have many order_lines, but an order_line can only appear once in an order and can only contain one product. The purpose of the trigger is to take the subtotal from order_line(or price from products I think actually) and the quantity from order_line, multiply them and update the new order_line's subtotal.

So I insert an order_line with my product foreign key, quantity of 3 and price of 4.00, the trigger multiplies the two to equal 12 and updates the subtotal. Now, I am thinking it's right to use price here instead of Order_line's subtotal in order to fix the mutation error (which occurs because I am asking the trigger to update the table which is being accessed by the triggering statement, right?), but how do I fix the quantity issue? Quantity won't always be the same value as stock, it has to be less than or equal to stock, so does anyone know how I can fix this to select from product and update order_line? Thanks.

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

EDIT: I think I could use the :new syntax to use the quantity value from the triggering statement. I'll try this but I'd appreciate confirmation and help still, thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

痞味浪人 2024-12-27 00:02:03

听起来您想要类似“

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,作为虚拟列)会更有意义。桌子)。

It sounds like you want something like

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;

If this is something other than homework, however, it doesn't really make sense to pull the price from the PRODUCTS table in this trigger. Presumably, a product's price will change over time. But the price is fixed for a particular order when the order is placed. If the trigger was only defined on INSERT, it would probably be reasonable to just fetch the current price. But if you want to recalculate the subtotal of the line when a row is updated, you'd need to fetch the price as of the time the order was placed (and that assumes that you don't charge different customers different prices at the same time).

From a normalization standpoint, it also tends not to make sense to store calculated fields in the first place. It would make more sense to store the quantity and the price in the order_line table and then calculate the subtotal for the line in a view (or, if you're using 11g, as a virtual column in the table).

陈甜 2024-12-27 00:02:03

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

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

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这种情况下,修改上面的内容应该很容易。)

The mutation error does not occur because you are updating the table; it occurs because you are querying from the table that is already being updated.

If I'm understanding correctly what you want to do:

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;
/

(I'm unclear why you have a test for a quantity below 0, and what you want to occur in this case. If you want to set the subtotal to NULL or 0 in this case, it should be quite easy to modify the above.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文