1

典型的な製品と出荷のデータベースについて、次のトリガーを実行する最良の方法を模索しています。

  1. 注文明細行が「完了」に設定されると、次のようなトリガーが実行されます。
  2. その注文の他の注文明細行を探します。
  3. その注文の他のすべての注文明細も「完了」の場合
  4. 注文ヘッダーテーブルを更新して完了します。

明確にするために: 注文ヘッダー テーブルには注文の合計が格納され、orderLines テーブルには注文の各製品が格納されます。

これまでのところ、トリガーは次のように記述されています。

CREATE OR REPLACE TRIGGER orderComplete
after update ON orderline
for each row
WHEN (new.orderline_fulfilled = 'Y')
DECLARE count NUMBER := 5;
ordersNotDone NUMBER;
BEGIN

SELECT COUNT(Orderline_fulfilled) INTO ordersNotDone
FROM orderHeader
JOIN orderline ON
orderHeader.Order_id = orderLine.Orderline_order
WHERE Order_id = :old.orderline_order
AND orderline_fulfilled = 'Y';

IF ordersNotDone = 0
THEN
UPDATE orderHeader
SET completed = SYSDATE
    WHERE orderId = :old.orderline_order;
ENDIF;

END;

これにより、注文行の行を更新するときに突然変異エラーが発生します。

4

3 に答える 3

3

RDBMS読み取り整合性モードでは、互いの結果を確認できない複数の変更を同時に許可するため、トリガーを使用して整合性を強制することは本質的に問題があります。

より良い解決策は、データの非正規化を回避し、不完全な注文ラインの存在を検出して不完全な注文を識別することに依存することです。これは少数のケースであるため、次の行に沿った関数ベースのインデックスを使用して最適化できます。

create index my_index on orderline(case orderline_complete when 'NO' then orderid else null end)

これにより、orderline_completeが「NO」であるorderlineの値のみがインデックスに登録されるため、テーブルにそのような行が100個しかない場合、インデックスには100個のエントリのみが含まれます。

不完全な注文を特定することは、クエリを使用した非常にコンパクトなインデックスのフルまたは高速フルインデックススキャンのみの問題です。

select distinct
  case orderline_complete when 'NO' then orderid else null end orderid
from
  orderline
where
  case orderline_complete when 'NO' then orderid else null end is not null;
于 2012-04-28T21:51:13.140 に答える
0

最も簡単な答えは、行が更新された後ではなく、テーブルが更新された後にトリガーされる、少し異なるタイプのトリガーを使用することです。これは、この問題に悩まされることはありません。

したがって、次のようにします。

CREATE or REPLACE TRIGGER trigger_name
AFTER INSERT ON orderline --note no for each row
BEGIN

  --loop over all orders which contain no unfulfilled orders
  FOR lrec IN (SELECT order_id FROM orderline group by order_id where not exists (select 1 from orderline where orderline_fulfilled = 'Y'))
  LOOP
    -- do stuff to order id because this are complete
  END LOOP;
END;

したがって、ここでは挿入で複数の注文を完了した可能性があるため、トリガーはこれに対処する必要があります。申し訳ありませんが、自宅で遊ぶオラクルのインスタンスがありません。お役に立てれば

于 2012-04-29T22:10:35.353 に答える
0

11g を使用している場合は、複合トリガーについて確認してください。例: http://www.toadworld.com/KNOWLEDGE/KnowledgeXpertforOracle/tabid/648/TopicID/TRGC1/Default.aspx

于 2012-05-02T06:53:52.273 に答える