我一直在努力实现这个触发器一段时间并且正在取得进展(我想!)但是现在我遇到了突变错误。
我这里有三个实体(这里是相关的),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语法来使用触发语句中的数量值。我会尝试这个,但我仍然感谢您的确认和帮助,谢谢。
答案 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,作为表中的虚拟列)将更有意义。