觸發器是被指定關聯到一個表的數據對象,它不需要調用,當對一個表的特別事件出現時,它就被激活。觸發器的代碼也是由SQL語句組成的,因此用在存儲過程中的語句也可以用再觸發器的定義中。觸發器是一類特殊的存儲過程,與表的關係密切,用於保護表中的數據,當有操作影響到觸發器保護的數據時,觸發器將自動執行。 (1 ...
觸發器是被指定關聯到一個表的數據對象,它不需要調用,當對一個表的特別事件出現時,它就被激活。觸發器的代碼也是由SQL語句組成的,因此用在存儲過程中的語句也可以用再觸發器的定義中。觸發器是一類特殊的存儲過程,與表的關係密切,用於保護表中的數據,當有操作影響到觸發器保護的數據時,觸發器將自動執行。
(1)DML觸發器:當資料庫中發生數據操作語句(DML)事件時調用DML觸發器。DML事件包括用表或視圖的 insert語句,update語句和delect語句,因此DML觸發器可分為3種。
(2)代替觸發器:由於oracle中不能直接對兩個以上的表建立的視圖進行操作,所以給出了代替觸發器。它是oracle專門為進行視圖操作的一種處理方式。
(3)系統觸發器:系統觸發器也由相應的事件觸發,但它的激活一般基於對資料庫系統所進行得操作,如數據定義語句(DDL),啟動或關閉觸發器,連接或斷開,伺服器錯誤等系統事件。
命令創建觸發器:
--語法格式 create or replace trigger 觸發器的名稱 before /after/instead of insert/update/delete on for each row
說明:
觸發器名稱:觸發器的名字與過程名和包的名字不一樣,它有單獨的名字空間,因此觸發器名可以和表名或過程名同名,但在同一個方案中的觸發器名不能相同。
after:觸發器在指定操縱都成功執行後觸發,如after insert 表示在向表中插入數據後激活觸發器
before:觸發器在指定操作執行前觸發,如before insert 表示在向表中插入數據前激活觸發器
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 [<用戶名方案名.>]<觸發器>
也可以用界面刪除觸發器