さて、私は 2 つのテーブル (ORDERS と ORDERLINES) を持っていますが、これらは基本的に同じ問題を抱えており、それぞれにトリガーを設定して問題に対処しています。問題は、テーブル レベルの一意性を持つ PK に加えて、RECID と呼ばれるフィールドに、別のフィールドに対して一意である必要がある別のフィールド RECNO があることです。
テーブルは次のように FK 関連です。
ORDERS.WAREHOUSEID > WAREHOUSES.CUSTOMERID > CUSTOMERS
と
ORDERSLINES.ORDERID > ORDERS
OnORDERS
で、レルム固有の一意のRECNOORDERSLINES
を割り当てるトリガーがあります。
では、RECNOはレコードの領域内で一意である必要があります。
では、RECNOはレコードの領域内で一意である必要があります。BEFORE INSERT
ORDERS
CUSTOMERS
ORDERLINES
ORDERS
トリガーはORDERS
完全に正常に機能します。新しい注文が挿入されると、その注文が属する顧客内で 次の固有のRECNOが割り当てられます。
一方、トリガーは、属するオーダー内で次の一意のRECNOORDERLINES
を割り当てる必要がありますが、恐ろしい{ORA-04091: テーブル ORDERLINES が変化しています。トリガー/関数はそれを認識しない場合があります}例外をスローします。
動作するトリガーは次のとおりです。
CREATE OR REPLACE TRIGGER ORDERS_BI
BEFORE INSERT ON ORDERS
FOR EACH ROW
DECLARE
CUSTID WAREHOUSES.CUSTOMERID%TYPE;
BEGIN
SELECT MIN(CUSTOMERID) INTO CUSTID FROM WAREHOUSES
WHERE NVL(WARE_ID, '-') = NVL(:NEW.WAREHOUSEID, '-');
SELECT NVL(MAX(RECNO), 0) + 1
INTO :NEW.RECNO
FROM deploy.ORDERS O
LEFT JOIN deploy.WAREHOUSES W
ON NVL(W.REC, '-') = NVL(O.WAREHOUSEID, '-')
WHERE NVL(W.CUSTOMERID, '-') = NVL(CUSTID, '-');
END;
そして、これが機能しないトリガーです:
CREATE OR REPLACE TRIGGER ORDERLINES_BI
BEFORE INSERT ON ORDERLINES
FOR EACH ROW
DECLARE
nORDERID ORDERLINES.ORDERID%TYPE;
BEGIN
SELECT MIN(ORDERID) INTO nORDERID FROM REVORDERS
WHERE ORDERID = :NEW.ORDERID;
SELECT NVL(MAX(RECNO), 0) + 1
INTO :NEW.RECNO
FROM deploy.ORDERLINES L
LEFT JOIN deploy.ORDERS O
ON O.ORDERID = L.ORDERID
WHERE O.ORDERID = nORDERID;
END;
誰かがなぜ最初のものは機能し、2番目のものは機能しないのか説明してもらえますか? そして、それを機能させるために2番目を書き直す方法はありますか?