初學Oracle PL/SQL 【筆記四】

1.觸發器:

    CREATE [OR REAPLACE] TRIGGER Trigger_name

    {BEFORE | AFTER}  Triggering_event  ON table_name

    {FOR EACH ROW}

    [FOLLOWS another_trigger]

    [ENABLE/DISABLE]

    [WHEN condition]

    DECLARE

             declaration statements

     BEGIN

              executable  statements

     EXCEPTION

              exception-handing statements

     END;

 

     BEFORE  或者  AFTER   指明何時觸發器執行,即在觸發事件發生之前,還是之後。

     子句 FOR EACH ROW 指定行觸發器,只適用於所插入、修改或者刪除的數據行。

     使用FOLLOWS 選項,可以指定觸發器被觸發的順序,這個選項適用於在相同 表上所定義的,並且在相同時間點會執行的觸發器。

 

     如不使用  [ENABLE / DISABLE ] 子句 , 爲禁用或啓用觸發器,需要執行ALTER TRIGGER 命令:

           ALTER TRIGGER trigger_name  DISABLE/ENABLE;

 

     如果刪除一個表,則在該表上所定義的數據庫觸發器也會被刪除 。觸發器是定義於數據庫表的。

    不允許在觸發器體中聲明LONG 或者 LONG RAW 變量。

 

    例如 :

    CREATE OR REPLACE TRIGGER student_bi

    BEFORE INSERT ON student

    FOR EACH ROW

    BEGIN

          :NEW.student_id     := STUDENT_ID_SEQ.NEXTVAL;

          :NEW.created_by    := USER;

          :NEW.created_date   :=SYSDATE;

          :NEW.modified_by     := USER;

          :NEW.modified_date   := SYSDATE;

    END;

觸發器體中包含僞記錄::NEW,使得你可以訪問當前正在被處理的數據行。:NEW 僞記錄是一種TRIGGERING_TABLE%TYPE,所以在這種情況下,這是student%TYPE的類型。爲訪問僞記錄:NEW 的單獨成員,需要使用點符號。

 

    CREATE  OR REPLACE TRIGGER instructor_aud

    AFTER  UPDATE OR DELETE  ON INSTRUCTOR

    DECLARE

          v_type  VARCHAR2(10);

    BEGIN

          IF  UPDATING THEN

              v_type  :=  'UPDATE';

          ELSIF  DELETING THEN

              v_type  :=  'DELETE';

          END IF;

       UPDATE statistics

             SET  transaction_user=USER,

                     transaction_date=SYSDATE

                  WHERE   table_name = 'INSTRUCTOR'   AND  transaction_name=v_type;

       IF  SQL%NOTFOUND  THEN

           INSERT INTO statistics

              VALUES('INSTRUCTOR',v_type,USER,SYSDATE);

       END IF;

    END;

 

------------------------------------------------------------------------------------

 

CREATE TRIGGER student_au

AFTER  UPDATE ON STUDENT

FOR EACH ROW

WHEN (NVL(NEW.ZIP,' ') <> OLD.ZIP )

        UPDATE  student

         SET   zip='01247'   WHERE   zip='02189'

使用僞記錄:OLD 可以訪問當前被處理的數據行。 當在WHEN 語句 的條件中使用時,:NEW 和:OLD 都不再使用冒號作爲前綴

:NEW 標識被更新的值,:OLD 標識被更新之前的那個值。所以:ZIP列的值01247 是個新值,用:NEW.ZIP 來引用它。02189  是ZIP 列的先前值,使用:OLD.ZIP 來引用。

 

CREATE  OR  REPLACE  TRIGGER  instructor_biud

DEFORE  INSERT OR  UPDATE  OR DELETE  ON INSTRUCTOR

DECLARE

    v_day   VARCHAR2(10);

BEGIN

    v_day  :=  RTRIM(TO_CHAR(SYSDATE, 'DAY' ));

 

    IF  v_day  LIKE ('S%')  THEN

        RAISE_APPLICATION_ERROR(-20000, 'A table  cannot be modified during off hours ');

    END IF;

END;

 

 

 

創建針對 視圖(VIEW) 的  INSTEAD OF  觸發器

CREATE  VIEW  student_address AS

    SELECT  s.student_id, s.first_name, s.last_name, s.street_address, z.city, z.state, z.zip 

           FROM  student   s  JOIN  zipcode  z  ON (s.zip= z.zip );

 

CREATE  OR REPLACE  TRIGGER  student_address_ins

INSTEAD  OF INSERT  ON student_address

 FOR  EACH  ROW

BEGIN

    INSERT  INTO  STUDENT

         (student_id,first_name,last_name,street_address,zip,registration_date,created_by,created_date,

                      modified_by,modified_date)

     VALUES(:NEW.student_id , :NEW.first_name, :NEW.last_name,:NEW.street_address,

                      :NEW.zip,  SYSDATE,  USER ,  SYSDATE , USER, SYSDATE );

END;

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章