2011-12-07 97 views
0

我一直在嘗試實現這個觸發器一段時間,並正在取得進展(我想!),但現在我得到一個突變錯誤。觸發器計算小計

我在這裏有三個實體(這裏是相關的),Customer_Order(總等),Order_Line(數量,小計等)和產品(庫存,價格)。 Order_line是一個鏈接實體,因此一個產品可以有很多的order_lines,而customer_order可以有很多order_lines,但是order_line只能在一個訂單中出現一次,並且只能包含一個產品。觸發器的目的是從order_line(或實際上我認爲的產品的價格)和order_line的數量中取小計,乘以它們並更新新的order_line的小計。

因此,我用我的產品外鍵,數量3和價格4.00插入一個order_line,觸發器將兩個乘以等於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語法來使用觸發語句中的數量值。我會嘗試這個,但我會很感激確認和幫助,謝謝。

回答

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作爲表中的虛擬列),將會更有意義。

+0

+1。 (我沒有測試代碼,在數據庫設計的早期階段,我只能在家*使用Oracle *)。 –

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,它應該是很容易修改以上。)