2017-02-10 9 views
0

更新後に更新をトリガーしようとしています。更新の特定の変数を含むPL/SQLトリガー

マイテーブル:

CREATE TABLE STUDENT (
    STUDENT_ID   INTEGER  PRIMARY KEY, 
    NAME    CHAR(40) NOT NULL, 
    SURNAME    CHAR(40) NOT NULL, 
    TOKEN    CHAR(5)  NOT NULL, 
    STUDYCOURSE   CHAR(20) NOT NULL, 
    NOTE    VARCHAR(255) NULL, 
    WARNING_ID   INTEGER  REFERENCES MAHNUNG (ID), 
    BLOCKED    CHAR(1)  CHECK (Gesperrt IN('J', 'N')); 

create table RENTAL (
    RENTAL_ID   INTEGER  PRIMARY KEY, 
    RENTALDATE   DATE  DEFAULT SYSDATE, 
    RENTALDURATION  INTEGER  NOT NULL, 
    OVERDRAWN   CHAR(1)  CHECK (OVERDRAWN IN('Y', 'N')); 

マイトリガー:

CREATE OR REPLACE TRIGGER OVERDRAWN_RETURN 
AFTER UPDATE OF OVERDRAWN ON RENTAL 
    REFERENCING OLD AS OLD AND NEW AS NEW 

BEGIN 
    IF :NEW.OVERDRAWN := 'Y' THEN 
    UPDATE STUDENT SET WARNING_ID = WARNING_ID+1 
    WHERE STUDENT.STUDENT_ID = RENTAL.STUDENT_ID; 
    END IF; 
END OVERDRAWN_RETURN; 
/

私は基本的に誇張が 'Y'(はい)に更新されたときにWARNING_IDをインクリメントされてやろうとしています。 エラーレポート -

ORA-04079: invalid trigger specification 
04079. 00000 - "invalid trigger specification" 
*Cause: The create TRIGGER statement is invalid. 
*Action: Check the statement for correct syntax. 

どうしたのですか?

+0

btwの場合、 'VARCHAR'または' CHAR'ではなく 'VARCHAR2'を使用してください。また、あなたのキャップロックがオンです;) –

答えて

1

IFステートメントで代入演算子(:=)を使用していました。

CREATE OR REPLACE TRIGGER OVERDRAWN_RETURN 
    AFTER UPDATE OF OVERDRAWN ON RENTAL 
     REFERENCING OLD AS OLD AND NEW AS NEW 

    BEGIN 
     IF :NEW.OVERDRAWN = 'Y' THEN 
     UPDATE STUDENT SET WARNING_ID = WARNING_ID+1 
     WHERE STUDENT.STUDENT_ID = RENTAL.STUDENT_ID; 
     END IF; 
    END OVERDRAWN_RETURN; 
    /
1

としてだけでなく、比較のため:=代わりに=の使用は@Prashantは、指摘することを他のいくつかの問題があります。実際に表示されるエラーはREFERENCING行のためです(ANDは含まない)。

しかし、あなたは文トリガーに新旧を使用することはできませんので、あなたもそれFOR EACH ROWトリガーにする必要があります。

CREATE OR REPLACE TRIGGER OVERDRAWN_RETURN 
AFTER UPDATE OF OVERDRAWN ON RENTAL 
REFERENCING OLD AS OLD NEW AS NEW 
FOR EACH ROW 

BEGIN 
    IF :NEW.OVERDRAWN = 'Y' THEN 
    UPDATE STUDENT SET WARNING_ID = WARNING_ID+1 
    WHERE STUDENT_ID = :NEW.STUDENT_ID; 
    END IF; 
END OVERDRAWN_RETURN; 
/

あなたはRENTAL.STUDENT_IDに言及されたが、それはSQLの範囲外でありますステートメント。だから私は:NEW.STUDENT_IDで現在の行を参照するように変更しました。しかしどちらの方法でも、RENTALテーブルにはSTUDENT_IDという列はありませんが、投稿の定義を編集するときはこれを省略することができます。

+0

はい、申し訳ありませんが、ALTER TABLEコマンドでSTUDENT_IDを挿入し、テーブルに直接挿入するのを忘れてしまいました。そうです:NEW.STUDENT_IDは上記のRENTALの更新された行を参照していますか? – HandsomeJane

+0

@HandsomeJane - はい、 ':NEW.xxx'はトリガが発生した影響を受ける行の' xxx'の新しい値を意味します。 [続きを読む](http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/triggers.htm#LNPLS99955)。 updateステートメントが 'STUDENT_ID'を変更した場合、':OLD.STUDENT_ID'はテーブルのその行に最後に設定された古い値になり、 ':NEW.STUDENT_ID'はupdateステートメントで提供される新しい値になります。更新が完了した後にテーブル行が格納されます。この場合、おそらくあなたはそれが変わることを期待していません。 –

関連する問題