0

以下のトリガーの実行に問題があります。

CREATE OR REPLACE TRIGGER AFTERINSERTCREATEBILL
AFTER INSERT
ON READING
FOR EACH ROW 

DECLARE

varReadNo   Int;
varMeterID  Int;
varCustID   Varchar(10);

BEGIN 

SELECT SeqReadNo.CurrVal INTO varReadNo FROM DUAL;

Select MeterID INTO varMeterID
From Reading 
Where ReadNo = varReadNo;

Select CustID INTO varCustID
From Address A
Join Meter M 
on A.postCode = M.postCode
Where M.MeterID = varMeterID;

INSERT INTO BILL VALUES 
(SEQBILLNO.NEXTVAL, SYSDATE, 'UNPAID' , 100 , varCustID , SEQREADNO.CURRVAL); 

END;

エラーメッセージ:

*原因:トリガー(またはこの文で参照されているユーザー定義のplsql関数)が、それを起動した文によって変更されている途中の表を調べ(または変更)しようとしました。

*アクション:トリガー(または関数)を書き直して、そのテーブルを読み取らないようにします。

テーブルReadingから詳細を取得することを想定していないということですか?

値を挿入しているときにテーブル読み取りからデータを取得すると、問題が発生すると思います。

SELECT SeqReadNo.CurrVal INTO varReadNo FROM DUAL;

Select MeterID INTO varMeterID
From Reading 
Where ReadNo = varReadNo; 

とにかくこれを解決することはありますか?または、これを行うためのより良い方法はありますか?ReadNoが挿入したReadNoを参照する必要があるテーブルReadingに入った後、テーブルBILLに新しい行を挿入する必要があります。

4

4 に答える 4

4

行トリガーの同じテーブルからレコードを取得することはできません。:newと:oldを使用して、実際のレコードから値にアクセスできます(これはあなたの場合ですか?)。その後、トリガーを次のように書き換えることができます

CREATE OR REPLACE TRIGGER AFTERINSERTCREATEBILL
AFTER INSERT
ON READING
FOR EACH ROW 

DECLARE

  varCustID   Varchar(10);

BEGIN 

  Select CustID INTO varCustID
    From Address A
    Join Meter M 
      on A.postCode = M.postCode
    Where M.MeterID = :new.MeterID;

  INSERT INTO BILL VALUES 
  (SEQBILLNO.NEXTVAL, SYSDATE, 'UNPAID' , 100 , varCustID , SEQREADNO.CURRVAL); 

END;

READING表から他のレコードを照会する必要がある場合は、文トリガー、行トリガー、およびPLSQLコレクションを組み合わせて使用​​する必要があります。この良い例はAskTom.oracle.comにあります

于 2012-11-13T06:11:18.670 に答える
0

すべてのテーブルに対して必要な権限があり、挿入で使用しているシーケンスにアクセスできることを確認してください。

しばらくの間Oracleを実行していませんが、SPがコンパイルされない理由の詳細を取得するために、dba_errors(またはall_errors)のクエリを試すこともできます。

調子に合わせて:

SELECT * FROM dba_errors WHERE owner = 'THEOWNER_OF_YOUR_SP';
于 2012-11-13T03:39:36.543 に答える
0

トリガーに例外処理を追加して、何が起こっているかを確認します。そうすることで、例外を追跡するのが簡単になります。

CREATE OR REPLACE TRIGGER AFTERINSERTCREATEBILL
AFTER INSERT
ON READING
FOR EACH ROW 

DECLARE

  varCustID   Varchar(10);

BEGIN 

  -- your code

EXCEPTION
    WHEN NO_DATA_FOUND
    THEN
        DBMS_OUTPUT.PUT_LINE(TO_CHAR(SQLERRM(-20299)));
    WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE(TO_CHAR(SQLERRM(-20298)));

END;
于 2012-11-13T06:32:20.290 に答える
0

挿入ステートメントと選択ステートメントを組み合わせることができます

CREATE OR REPLACE TRIGGER AFTERINSERTCREATEBILL
AFTER INSERT
ON READING
FOR EACH ROW 

DECLARE

varCustID   Varchar(10);

BEGIN 

 insert into bill 
 values 
 select SEQBILLNO.NEXTVAL, 
        SYSDATE, 
        'UNPAID' , 
        100 ,
        CustID,SEQREADNO.CURRVAL 
 From  Address A
 Join  Meter M 
 on    A.postCode = M.postCode
 Where M.MeterID = :new.MeterID; 

END;

上記のコードを試してください。

于 2014-07-23T11:05:01.517 に答える