Oracle中的触发器
Oracle中的觸發(fā)器
觸發(fā)器
觸發(fā)器(tigger)是在事件發(fā)生時(shí)隱式地自動(dòng)運(yùn)行的 PL/SQL 程序塊,不能接收參數(shù),不能被調(diào)用,就是說某個(gè)條件成立的時(shí)候,觸發(fā)器里面所定義的語句就會(huì)被自動(dòng)的執(zhí)行。因此觸發(fā)器不需要人為的去調(diào)用,也不能調(diào)用。
觸發(fā)器類型
根據(jù)觸發(fā)器所創(chuàng)建的語句及所影響的對(duì)象的不同,將觸發(fā)器分為 3 類,DML 觸發(fā)器、系統(tǒng)事件觸發(fā)器、替代觸發(fā)器(instead of 觸發(fā)器)。
(1)DML 觸發(fā)器
對(duì)數(shù)據(jù)表進(jìn)行 DML 語句操作(如 insert、update、delete)時(shí)所觸發(fā)的觸發(fā)器,可以分為:語句級(jí)觸發(fā)器或行級(jí)觸發(fā)器:行級(jí)觸發(fā)器會(huì)對(duì)數(shù)據(jù)庫(kù)表中的受影響的每一行觸發(fā)一次觸發(fā)器代碼,語句級(jí)觸發(fā)器則只觸發(fā)一次,與語句所影響到的行數(shù)無關(guān)
before 觸發(fā)器或 after 觸發(fā)器:before 觸發(fā)器在觸發(fā)事件發(fā)生之前執(zhí)行觸發(fā)器代碼,
after 觸發(fā)器則在觸發(fā)事件發(fā)生之后執(zhí)行。
語法:
其中:
觸發(fā)器名: 觸發(fā)器對(duì)象的名稱。由于觸發(fā)器是數(shù)據(jù)庫(kù)自動(dòng)執(zhí)行的,因此該名稱只是一個(gè)名稱,沒有實(shí)質(zhì)的用途。
觸發(fā)時(shí)間: 指明觸發(fā)器何時(shí)執(zhí)行,該值可取:
before:表示在數(shù)據(jù)庫(kù)動(dòng)作之前觸發(fā)器執(zhí)行;
after:表示在數(shù)據(jù)庫(kù)動(dòng)作之后觸發(fā)器執(zhí)行。
觸發(fā)事件: 指明哪些數(shù)據(jù)庫(kù)動(dòng)作會(huì)觸發(fā)此觸發(fā)器:
insert:數(shù)據(jù)庫(kù)插入會(huì)觸發(fā)此觸發(fā)器;
update:數(shù)據(jù)庫(kù)修改會(huì)觸發(fā)此觸發(fā)器;
delete:數(shù)據(jù)庫(kù)刪除會(huì)觸發(fā)此觸發(fā)器。
**表名:**數(shù)據(jù)庫(kù)觸發(fā)器所在的表。
for each row:對(duì)表的每一行觸發(fā)器執(zhí)行一次。如果沒有這一選項(xiàng),則只對(duì)整個(gè)表執(zhí)行一次。
觸發(fā)器能實(shí)現(xiàn)如下功能:
功能:
1、允許/限制對(duì)表的修改
2、自動(dòng)生成派生列,比如自增字段
3、強(qiáng)制數(shù)據(jù)一致性
4、提供審計(jì)和日志記錄
5、防止無效的事務(wù)處理
6、啟用復(fù)雜的業(yè)務(wù)邏輯
下面的觸發(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 -- 對(duì)表的每一行觸發(fā)器執(zhí)行一次declare -- local variables here begin dbms_output.put_line('一個(gè)員工被插入'); end testTrigger;---當(dāng)用戶對(duì) test 表執(zhí)行 DML 語句時(shí),將相關(guān)信息記錄到日志表 --創(chuàng)建測(cè)試表 CREATE TABLE test(t_id NUMBER(4),t_name VARCHAR2(20),t_age NUMBER(2),t_sex CHAR );--創(chuàng)建記錄測(cè)試表 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 表示當(dāng)前用戶名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('工資未作任何變動(dòng)');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';更多相關(guān)知識(shí)請(qǐng)戳我的主頁(yè)哦!
總結(jié)
以上是生活随笔為你收集整理的Oracle中的触发器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle 雪峰,讨论 - 廖雪峰的官
- 下一篇: Lua pairs与ipairs效率分析