數據庫程序設計8 觸發器

目錄

觸發器

類型

觸發器設計原則

DML觸發器

創建

觸發事件

語句觸發器

行觸發器

INSTEAD_OF觸發器

維護

刪除

數據庫觸發器和存儲過程之間的區別


觸發器

  • 是特殊的PL/SQL塊或存儲過程
  • 是基於表、視圖、方案、數據庫的
  • 是針對特定事件發生時觸發的
  • 是隱式執行的

能夠更爲複雜的控制用戶的操作,例如:週末不允許進行離職手續等。

自動處理一些值,例如:賬目低於多少錢自動發消息。

類型

應用程序觸發器

在應用程序內發生特定DML事件時,將隱式觸發它

數據庫觸發器

在表、視圖、方案或數據庫上發生特定事件時,將隱式觸發它

觸發器設計原則

設計觸發器爲了:

  • 保證當一個指定的操作被執行時,執行相關的動作
  • 集中全局操作

如果觸發器的算法很長,將算法創建於存儲過程中,再在觸發器中調用它們,觸發器的大小不能超過32K。過分地使用觸發器可能導致複雜的依賴,這在大的應用程序中可能會產生維護困難。

DML觸發器

一個觸發器語句包含:
觸發時間

  • 對於表: BEFORE, AFTER
  • 對於視圖: INSTEAD OF

觸發事件: INSERT, UPDATE或DELETE
表名: On table、view
觸發器類型: Row或statement (只執行一次)
WHEN子句:限制條件,只能在行級觸發器中使用
觸發器體: PL/SQL塊

部分 說明 可能值
觸發器時機 當觸發器涉及觸發事件時的觸發時機 BEFORE、AFTER、INSTEAD OF
觸發事件 在表或視圖上的哪一-個數據操縱操作引發了觸發器觸發 INSERT、UPDATE、DELETE
觸發器類型 觸發器體被執行多少次 Sta tement、ROW
觸發器體 觸發器執行的那些動作 PL/SQL塊

創建

語法:

CREATE [OR REPLACE] TRIGGER
    trigger_name
[ BEFOREI AFTER]
[ INSERTI UPDATE [of column] | DELETE]
ON table name
Trigger_body

例子:

員工信息只有在工作日才能進行修改

CREAT OR REPLACE TRIGGER sal_emp
BEFORE INSERT ON emp
BEGIN
    IF(to_char(sysdate),'DY') in ('星期六','星期日')
    then
        raise_application_error(-20001,'只有工作日才能錄入數據');
    END IF
END;

INSERT INTO
    emp(empno,ename,job,mgr,hiredate,sal)
VALUES(1002,'ljs','clerk',7902,sysdate,2000);

觸發事件

觸發事件可以是表上的INSERT、UPDATE或DELETE語句。

當觸發事件是一個UPDATE語句時,可以用一個字段列表來確定那些必需觸發觸發器自來改變的列。不能爲INSERT或DELETE語句指定字段列表,因爲它們總是影響整個行(...UPDATE OF sal...)。

對於語句觸發器,觸發事件對於觸發器執行一次;對於行觸發器,觸發事件僅當行被修改時觸發。

例如:

語句觸發器

例子:

create or replace trigger trg_empl_ins
    after insert on empl

begin
    INSERT INTO empl_new (empno, ename,sal)
    VALUES (999, '張三', 3000) ;
end trg_empl_ins;
CREATE TABLE empl_new
AS SELECT *FROM emp
WHERE empno IS
NULL
INSERT INTO empl ( empno, ename, sal)
VALUES (888,'李四',4000)

這樣就實現了在兩張表同時添加數據了,做成了兩張表的同步。一條是insert的一條是觸發器添加的。

行觸發器

使用關鍵字for each row

創建語法:

CREATE [OR REPLACE] TRIGGER trigger_ name
[BEFORE | AFTER ]
[ INSERT | UPDATE [of column] | DELETE]
ON table_name
[ REFERENCING OLD as old | NEW as new]
FOR EACH ROW
[WHEN (condition)]
Trigger_body

NEW代表新加的數據,OLD代表老數據。靈活使用,例如刪除的時候沒有新值,修改時old,new都有。

例子:

CREATE OR REPLACE TRIGGER sal_emp
BEFORE UPDATE OF sal ON emp
FOR EACH ROW
BEGIN
    IF(:new.sal >:old.sa1) THEN
    raise_application_error(-20001,薪水太高了); 
END IF;
END;

UPDATE emp SET sal=5000;

在BEGIN之前不用加冒號,在BEGIN內的語句體內需要加冒號(表示外部變量)

例子:

create or replace trigger trg_emp1_ins_row
    after insert on emp1
    for each row
begin
    INSERT INTO emp_new(empno, ename,sal)
    VALUES ( :NEW. empno, :NEW. ename, :NEW.sal);
end trg_empl_ins_row;

這樣也能做成兩張相同的表。

注意:回滾時兩張表的數據均會回滾掉。COMMIT命令不能出現在觸發器中。

INSTEAD_OF觸發器

視圖上是不能插入數據的,但是如果創建一個instead_of觸發器,就可以實現在視圖中向表中插入數據。

語法:

CREATE OR REPLACE TRIGGER trigger_name
INSTEAD OF
[INSERT | UPDATE [OF column] | DELETE]
ON view_ ame
[REFERENCING OLD as old | NEW as new]
FOR EACH ROW
Trigger_body

 

維護

ALTER TRIGGER trigger name DISABLE| ENABLE

 例如在提前編好觸發器,先禁用掉,等需要的時候上線使用。

刪除

DROP TRIGGER trigger_name ;

 另外,當表被刪除時,表上的所有觸發器都被刪除。

數據庫觸發器和存儲過程之間的區別

                             觸發器                               過程
用CREATE TRIGGER定 義 用CREATE PROCEDURE定義
在數據字典USER TRIGGERS中包含源代碼 在數據字典USER_SOURCE中包含源代碼
隱式調用 顯式調用
不允許COMMIT,SAVEPOINT和ROLLBACK 允許COMMIT,SAVEPOINT和ROLLBACK


 

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