Oracle中的触发器
Oracle中的觸發(fā)器
觸發(fā)器
觸發(fā)器(tigger)是在事件發(fā)生時隱式地自動運行的 PL/SQL 程序塊,不能接收參數(shù),不能被調(diào)用,就是說某個條件成立的時候,觸發(fā)器里面所定義的語句就會被自動的執(zhí)行。因此觸發(fā)器不需要人為的去調(diào)用,也不能調(diào)用。
觸發(fā)器類型
根據(jù)觸發(fā)器所創(chuàng)建的語句及所影響的對象的不同,將觸發(fā)器分為 3 類,DML 觸發(fā)器、系統(tǒng)事件觸發(fā)器、替代觸發(fā)器(instead of 觸發(fā)器)。
(1)DML 觸發(fā)器
對數(shù)據(jù)表進行 DML 語句操作(如 insert、update、delete)時所觸發(fā)的觸發(fā)器,可以分為:語句級觸發(fā)器或行級觸發(fā)器:行級觸發(fā)器會對數(shù)據(jù)庫表中的受影響的每一行觸發(fā)一次觸發(fā)器代碼,語句級觸發(fā)器則只觸發(fā)一次,與語句所影響到的行數(shù)無關
before 觸發(fā)器或 after 觸發(fā)器:before 觸發(fā)器在觸發(fā)事件發(fā)生之前執(zhí)行觸發(fā)器代碼,
after 觸發(fā)器則在觸發(fā)事件發(fā)生之后執(zhí)行。
語法:
其中:
觸發(fā)器名: 觸發(fā)器對象的名稱。由于觸發(fā)器是數(shù)據(jù)庫自動執(zhí)行的,因此該名稱只是一個名稱,沒有實質(zhì)的用途。
觸發(fā)時間: 指明觸發(fā)器何時執(zhí)行,該值可取:
before:表示在數(shù)據(jù)庫動作之前觸發(fā)器執(zhí)行;
after:表示在數(shù)據(jù)庫動作之后觸發(fā)器執(zhí)行。
觸發(fā)事件: 指明哪些數(shù)據(jù)庫動作會觸發(fā)此觸發(fā)器:
insert:數(shù)據(jù)庫插入會觸發(fā)此觸發(fā)器;
update:數(shù)據(jù)庫修改會觸發(fā)此觸發(fā)器;
delete:數(shù)據(jù)庫刪除會觸發(fā)此觸發(fā)器。
**表名:**數(shù)據(jù)庫觸發(fā)器所在的表。
for each row:對表的每一行觸發(fā)器執(zhí)行一次。如果沒有這一選項,則只對整個表執(zhí)行一次。
觸發(fā)器能實現(xiàn)如下功能:
功能:
1、允許/限制對表的修改
2、自動生成派生列,比如自增字段
3、強制數(shù)據(jù)一致性
4、提供審計和日志記錄
5、防止無效的事務處理
6、啟用復雜的業(yè)務邏輯
下面的觸發(fā)器在更新表 tb_emp 之前觸發(fā),目的是不允許在周末修改表
create or replace trigger auth_secure before insert or update or DELETE on tb_emp beginIF(to_char(sysdate,'DY')='星期日') THENRAISE_APPLICATION_ERROR(-20600,'不能在周末修改表 tb_emp');END IF; END;--- 插入一條數(shù)據(jù)以后被觸發(fā) create or replace trigger testTrigger after insert on tb_emp FOR EACH ROW -- 對表的每一行觸發(fā)器執(zhí)行一次declare -- local variables here begin dbms_output.put_line('一個員工被插入'); end testTrigger;---當用戶對 test 表執(zhí)行 DML 語句時,將相關信息記錄到日志表 --創(chuàng)建測試表 CREATE TABLE test(t_id NUMBER(4),t_name VARCHAR2(20),t_age NUMBER(2),t_sex CHAR );--創(chuàng)建記錄測試表 CREATE TABLE test_log(l_user VARCHAR2(15),l_type VARCHAR2(15),l_date VARCHAR2(30) ); --創(chuàng)建觸發(fā)器 CREATE OR REPLACE TRIGGER TEST_TRIGGERAFTER DELETE OR INSERT OR UPDATE ON TEST DECLAREV_TYPE TEST_LOG.L_TYPE%TYPE; BEGINIF INSERTING THEN--INSERT 觸發(fā)V_TYPE := 'INSERT';DBMS_OUTPUT.PUT_LINE('記錄已經(jīng)成功插入,并已記錄到日志');ELSIF UPDATING THEN--UPDATE 觸發(fā)V_TYPE := 'UPDATE';DBMS_OUTPUT.PUT_LINE('記錄已經(jīng)成功更新,并已記錄到日志');ELSIF DELETING THEN--DELETE 觸發(fā)V_TYPE := 'DELETE';DBMS_OUTPUT.PUT_LINE('記錄已經(jīng)成功刪除,并已記錄到日志');END IF;INSERT INTO TEST_LOG VALUES (USER, --USER 表示當前用戶名V_TYPE, TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss')); END;--下面我們來分別執(zhí)行 DML 語句 INSERT INTO test VALUES(101,'zhao',22,'M'); UPDATE test SET t_age = 30 WHERE t_id = 101; DELETE test WHERE t_id = 101; --然后查看效果 SELECT * FROM test; SELECT * FROM test_log;--- 創(chuàng)建觸發(fā)器,比較 emp 表中更新的工資 set serveroutput on; CREATE OR REPLACE TRIGGER SAL_EMPBEFORE UPDATE ON EMPFOR EACH ROW BEGINIF :OLD.SAL > :NEW.SAL THEN --- :old.字段名稱 :原來的值DBMS_OUTPUT.PUT_LINE('工資減少');ELSIF :OLD.SAL < :NEW.SAL THENDBMS_OUTPUT.PUT_LINE('工資增加');ELSEDBMS_OUTPUT.PUT_LINE('工資未作任何變動');END IF;DBMS_OUTPUT.PUT_LINE('更新前工資 :' || :OLD.SAL);DBMS_OUTPUT.PUT_LINE('更新后工資 :' || :NEW.SAL); -- :new.字段名稱: 待更新的值 END; --執(zhí)行 UPDATE 查看效果 UPDATE emp SET sal = 3000 WHERE empno = '7788';更多相關知識請戳我的主頁哦!
總結
以上是生活随笔為你收集整理的Oracle中的触发器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle 雪峰,讨论 - 廖雪峰的官
- 下一篇: Lua pairs与ipairs效率分析