2011-12-07 12 views
0

私は今このトリガーを実装しようとしてきましたが、進歩していますが、今は変異エラーが発生しています。小計を計算するためのトリガー

ここには、3つのエンティティ(ここでは関連性があります)、Customer_Order(合計など)、Order_Line(数量、小計など)、商品(在庫、価格)があります。 Order_lineはリンクエンティティであるため、商品は多くのorder_lines内にあり、customer_orderは多くのorder_linesを持つことができますが、order_lineは1つの注文で1回しか表示できず、1つの商品のみを含むことができます。引き金の目的は、order_line(または私が実際に考える製品からの価格)とorder_lineからの数量を小計に乗算し、それらを掛けて新しいorder_lineの小計を更新することです。

私は、製品の外部キーである数量3と価格4.00でorder_lineを挿入し、トリガーは2を2に等しくして小計を更新します。さて、私は、トリガーステートメントによってアクセスされているテーブルを更新するようにトリガーに依頼しているために起こる突然変異エラーを修正するために、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 

EDIT:私は、新しい構文を使用してトリガーステートメントから数量値を使用することができたと考えます。私はこれを試してみるだろうが、私は確認を感謝し、まだ助けていただき、ありがとう。

答えて

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に小計を設定したい、上記を修正するのは非常に簡単にする必要があります。)

関連する問題