觸發器是被指定關聯到一個表的數據對象,它不須要調用,當對一個表的特別事件出現時,它就被激活。觸發器的代碼也是由SQL語句組成的,所以用在存儲過程當中的語句也能夠用再觸發器的定義中。觸發器是一類特殊的存儲過程,與表的關係密切,用於保護表中的數據,當有操做影響到觸發器保護的數據時,觸發器將自動執行。數據庫
(1)DML觸發器:當數據庫中發生數據操做語句(DML)事件時調用DML觸發器。DML事件包括用表或視圖的 insert語句,update語句和delect語句,所以DML觸發器可分爲3種。服務器
(2)代替觸發器:因爲oracle中不能直接對兩個以上的表創建的視圖進行操做,因此給出了代替觸發器。它是oracle專門爲進行視圖操做的一種處理方式。oracle
(3)系統觸發器:系統觸發器也由相應的事件觸發,但它的激活通常基於對數據庫系統所進行得操做,如數據定義語句(DDL),啓動或關閉觸發器,鏈接或斷開,服務器錯誤等系統事件。函數
命令建立觸發器:spa
--語法格式 create or replace trigger 觸發器的名稱 before /after/instead of insert/update/delete on for each row
說明:日誌
觸發器名稱:觸發器的名字與過程名和包的名字不同,它有單獨的名字空間,所以觸發器名能夠和表名或過程名同名,但在同一個方案中的觸發器名不能相同。code
after:觸發器在指定操縱都成功執行後觸發,如after insert 表示在向表中插入數據後激活觸發器對象
before:觸發器在指定操做執行前觸發,如before insert 表示在向表中插入數據前激活觸發器blog
instead of: 指定建立代替觸發器,觸發器指定的事件不執行,而執行觸發器自己的操做。事件
delete,insert,update:指定一個或多個觸發器,多個觸發器事件之間用 or 鏈接
of:指定在某列上update觸發器,若是爲多列,則須要使用逗號分隔。
for each row:在觸發器定義中,若是未使用for each row 子句則表示觸發器爲語句觸發器,觸發器在激活後只執行一次,而無論這一操做將影響多行。
建立觸發器有如下限制:
(1) 代碼大小。觸發器代碼大小必須小於32K。
(2) 觸發器中有效語句能夠包括DML語句,但不能包括DDL語句。ROLLBACK、COMMIT、SAVEPOINT也不能使用。可是,對於系統觸發器(system trigger)可使用CREATE、ALTER、DROP TABLE和ALTER…COMPILE語句。
(3) LONG、LONG RAW和LOB的限制:
① 不能插入數據到LONG或LONG RAW;
② 來自LONG或LONG RAW的數據能夠轉換成字符型(如char、varchar2),可是不能超過32K;
③ 使用LONG或LONG RAW不能聲明變量;
④ 在LONG或LONG RAW列中不能使用:NEW和:PARENT;
⑤ 在LOB中的:NEW變量不能修改。
(4) 引用包變量的限制。若是UPDATE或DELETE語句檢測到當前的UPDATE衝突,則Oracle執行ROLLBACK到SAVEPOINT上並從新啓動更新,這樣可能須要屢次才能成功。
建立DML觸發器:
--假設數據庫中增長一新表school_students_old,表結構和表school_students相同,用來存放從school_students表 --中刪除的記錄。建立一個觸發器,當school_students表被刪除一行,把刪除的記錄寫到日誌表school_students_old中。
create table school_students_old2 //建立新表 ( STU_ID NVARCHAR2(20) NOT NULL, STU_NAME NVARCHAR2(20) NOT NULL , STU_SEX NVARCHAR2(20) , STU_CREDITS NUMBER(2) , STU_BIRTHDAY DATE , STU_CLASS NVARCHAR2(20) ); select * from school_students_old2; create or replace trigger delete_stu //建立觸發器 before delete on school_students for each row begin insert into school_students_old2 (STU_ID,STU_NAME,STU_SEX,STU_CREDITS,STU_BIRTHDAY,STU_CLASS) values (:old.STU_ID,:old.STU_NAME,:old.STU_SEX,:old.STU_CREDITS,:old.STU_BIRTHDAY,:old.STU_CLASS); end delete_stu; select * from school_students; select * from school_students_old;
建立代替觸發器:
--在數據庫中建立視圖和觸發器,以說明替代觸發器。 create or replace view stu_avg as select RESULT_STU, avg(result_number) as stu_avg from SCHOOL_RESULT group by RESULT_STU; select * from stu_avg where RESULT_STU='201632218031'; delete from stu_avg where RESULT_STU='201632218031'; create or replace trigger tr_stu_avg_delete instead of delete on stu_avg for each row begin delete from SCHOOL_RESULT where result_stu=:old.result_stu; end tr_stu_avg_delete;
建立系統觸發器:
--建立當一個用戶userA登陸時自動記錄一些信息的觸發器。 create table login_log ( v_user varchar2(100), v_date date ); create or replace trigger tr_login_log after logon on schema declare v_name VARCHAR2(20); begin select user into v_name from dual; insert into login_log values(v_name,sysdate); end tr_login_log; select * from login_log;
啓用和禁用觸發器:
在oracle中,與過程,函數,包不一樣,觸發器是能夠被禁用和啓用的,在有大量數據要導入數據庫中時,爲了不觸發相應的觸發器以節省處理時間,能夠禁用觸發器,使其暫時失效,觸發器被禁用後任然存儲在數據庫中,只要從新啓用既可使它從新工做。
oracle提供了alter trigger語句來禁用和啓用觸發器
--語法格式 alter trigger [<用戶名方案名.>]<觸發器> disable|enable;
其中:disable表示禁用觸發器,enable表示啓用觸發器
觸發器的刪除:
--語法格式
drop trigger [<用戶名方案名.>]<觸發器>
也能夠用界面刪除觸發器