/*觸發器
觸發器是指存放在資料庫中,並被隱含執行的預存程序。即當發生特定事件時,oracle會自動執行的代碼塊。
觸發器由觸發事件、觸發條件和觸發操作三部分組成。
觸發事件:是指引起觸發器觸發的SQL語句、資料庫事件和使用者事件。如:啟動關閉進程、使用者登入和斷開會話,特定表或視圖的DML操作等。
觸發條件:是指使用where子句指定一個BOOLEAN運算式,返回為true時,觸發器執行,反之,不執行。
觸發操作:是指包含SQL語句和其他執行代碼的PL/SQL塊。
*/
/*觸發器可分為:語句級、行級、模式級、資料庫級、管理級觸發器
這裡主要講解語句級、行級觸發器
--行級觸發器:對sql語句影響的每一行都觸發一次(比如,sql語句一次影響10行,那麼觸發10次)
--語句級觸發器:對同一個sql語句,不管影響多少行記錄,都只觸發一次
*/
/*語句級觸發器
CREATE [OR REPLACE] TRIGGER trigger_name
Timing event1[OR event2 OR event3] ON table_name
PL/SQL BLOCK;
其中:Timing指定觸發器時機
event指定觸發事件
*/
/*樣本:建立BEFORE語句級觸發器,保證員工資訊的修改只能在工作日*/
CREATE OR REPLACE TRIGGER worked_trigger
BEFORE INSERT OR UPDATE OR DELETE ON emp
BEGIN
IF to_char(SYSDATE,'DY','nls_date_language=AMERICAN') IN ('SAT','SUN') THEN
raise_application_error(-20001,'今天是休息時間,不能修改員工資訊!');
END IF;
END worked_trigger;
DELETE FROM emp; --如果是星期六或星期天此處觸發觸發器,提示如下:
/*使用條件謂詞*/
CREATE OR REPLACE TRIGGER worked_trigger
BEFORE INSERT OR UPDATE OR DELETE ON emp
BEGIN
IF to_char(SYSDATE,'DY','nls_date_language=AMERICAN') IN ('SAT','SUN') THEN
CASE
WHEN INSERTING THEN
raise_application_error(-20001,'今天是休息時間,不能插入員工資訊!');
WHEN UPDATING THEN
raise_application_error(-20001,'今天是休息時間,不能修改員工資訊!');
WHEN DELETING THEN
raise_application_error(-20001,'今天是休息時間,不能刪除員工資訊!');
END CASE;
END IF;
END worked_trigger;
--這樣就能明確知道使用者進行了什麼操作
/*行觸發器
CREATE [OR REPLACE] TRIGGER trigger_name
Timing event1[OR event2 OR event3] ON table_name
FOR EACH ROW [WHEN condition]
PL/SQL BLOCK;
其中:FOR EACH ROW表示是行觸發器
WHEN可選,指定觸發器條件
*/
/*樣本:確保員工工資不能低於原有工資*/
CREATE OR REPLACE TRIGGER empSal_trigger
BEFORE UPDATE ON emp
FOR EACH ROW
BEGIN
IF :new.sal < :old.sal THEN
raise_application_error(-20010,'工資只能漲,不能跌呀!');
END IF;
END empSal_trigger;
UPDATE emp SET sal = 100; --觸發觸發器,提示如下:
/*管理觸發器*/
/*顯示觸發器資訊*/
SELECT * FROM User_Triggers WHERE table_name = 'emp';
/*禁用觸發器*/
ALTER TRIGGER trigger_name DISABLE;
/*啟用觸發器*/
ALTER TRIGGER trigger_name ENABLE;
/*禁止或啟用表的所有觸發器*/
ALTER TABLE table_name DISABLE ALL TRIGGERS;
ALTER TABLE table_name ENABLE ALL TRIGGERS;
/*重新編譯觸發器*/
ALTER TRIGGER trigger_name COMPILE;
/*刪除觸發器*/
DROP TRIGGER trigger_name;