0

基本的に、これらの3つのテーブルと列があります。

tbl_equipment----> ( equip_id, equip_price)

tbl_equiporder----> ( equip_id, proj_no, qty)

tbl_project------> ( proj_no, proj_balance)

proj_balanceテーブルに値を挿入するときに更新するトリガーを作成する必要がありtbl_equiporderます。

使用する必要がある式は

balance = balance -(price*qty)

同じ言及されたテーブルの挿入ステートメントを書いている間に数量値を取得して、tbl_equiporderそれを使用して残高を更新できるようにする必要がありますtbl_project

tbl_equiporderテーブルへの挿入時にproj_balanceを更新する次のトリガーを作成しました

CREATE OR REPLACE TRIGGER trigger_equiporder
AFTER INSERT OR UPDATE OR DELETE ON tbl_equiporder FOR EACH ROW    
  DECLARE
    t_equipid NUMBER(4);
    t_price   NUMBER(4);
    t_qty     NUMBER(4);
    t_balance NUMBER(4);
  BEGIN

    SELECT equip_id, equip_price INTO t_equipid, t_price
      FROM tbl_equipment@fit5043a
     WHERE equip_id = :new.equip_id;

    SELECT equip_qty INTO t_qty
      FROM tbl_equiporder
     WHERE equip_id = :new.equip_id;

    SELECT proj_balance INTO t_balance
      FROM tbl_project
     WHERE proj_no = :new.proj_no;

    t_balance := t_balance - (t_price * t_qty);

    UPDATE tbl_project
       SET proj_balance = t_balance
     WHERE proj_no = :new.proj_no;

  END;

私がinsert文を書いたとき

INSERT INTO tbl_equiporder VALUES (1, 101, 1);

次のエラーをスローしました

Error starting at line 1 in command:
INSERT INTO tbl_equiporder VALUES (1,101,'11-sep-13',1000,1)
Error report:
SQL Error: ORA-04091: table S24585181.TBL_EQUIPORDER is mutating, trigger/function may not see it
ORA-06512: at "S24585181.TRIGGER_EQUIPORDER", line 9
ORA-04088: error during execution of trigger 'S24585181.TRIGGER_EQUIPORDER'
04091. 00000 -  "table %s.%s is mutating, trigger/function may not see it"
*Cause:    A trigger (or a user defined plsql function that is referenced in
           this statement) attempted to look at (or modify) a table that was
           in the middle of being modified by the statement which fired it.
*Action:   Rewrite the trigger (or function) so it does not read that table.
4

1 に答える 1

1

このエラーについて読んだことがありますか? トリガーで変更しているテーブルから選択することはできません。

SELECT を削除し、すでに使用可能な値をそのまま使用します。

create or replace trigger trigger_equiporder 
 after insert or update or delete on tbl_equiporder
 for each row  

declare
   t_price number(4);
   t_qty number(4);
   t_balance number(4);
begin

   select equip_price into t_price 
     from tbl_equipment@fit5043a 
    where equip_id = :new.equip_id;

   select proj_balance into t_balance 
     from tbl_project 
    where proj_no = :new.proj_no;

    t_balance := t_balance -(t_price * :new.equip_qty);

   update tbl_project 
      set proj_balance = t_balance 
    where proj_no = :new.proj_no;

end;

私はこれらすべてについて非常に慎重です。トリガーでクロスデータベースのSELECTを実行しているように見えるため、大幅に遅くなります。データ モデルを調べて、改善できるかどうかを確認する価値があるようです。たとえそれがtbl_equipmentローカルの具体化されたビューを持つのと同じくらい単純なものであっても.

また、データベース リンクを介して不要なデータを選択していました。そうしないでください。削除しました

于 2013-09-11T07:57:58.117 に答える