1. 程式人生 > >Oracle觸發器用法例項詳解

Oracle觸發器用法例項詳解

本文例項講述了Oracle觸發器用法。分享給大家供大家參考,具體如下:

一、觸發器簡介

觸發器的定義就是說某個條件成立的時候,觸發器裡面所定義的語句就會被自動的執行。因此觸發器不需要人為的去呼叫,也不能呼叫。然後,觸發器的觸發條件其實在你定義的時候就已經設定好了。這裡面需要說明一下,觸發器可以分為語句級觸發器和行級觸發器。詳細的介紹可以參考網上的資料,簡單的說就是語句級的觸發器可以在某些語句執行前或執行後被觸發。而行級觸發器則是在定義的了觸發的表中的行資料改變時就會被觸發一次。

具體舉例:

1、 在一個表中定義的語句級的觸發器,當這個表被刪除時,程式就會自動執行觸發器裡面定義的操作過程。這個就是刪除表的操作就是觸發器執行的條件了。
2、 在一個表中定義了行級的觸發器,那當這個表中一行資料發生變化的時候,比如刪除了一行記錄,那觸發器也會被自動執行了。

二、觸發器語法

觸發器的語法:

?
1 2 3 4 5 6 create [or replace] tigger 觸發器名 觸發時間 觸發事件 on 表名 [for each row] begin pl/sql語句 end

其中:

觸發器名:觸發器物件的名稱。由於觸發器是資料庫自動執行的,因此該名稱只是一個名稱,沒有實質的用途。
觸發時間:指明觸發器何時執行,該值可取:
before:表示在資料庫動作之前觸發器執行;
after:表示在資料庫動作之後觸發器執行。
觸發事件:指明哪些資料庫動作會觸發此觸發器:
insert:資料庫插入會觸發此觸發器;
update:資料庫修改會觸發此觸發器;
delete

:資料庫刪除會觸發此觸發器。
表 名:資料庫觸發器所在的表。
for each row:對錶的每一行觸發器執行一次。如果沒有這一選項,則只對整個表執行一次。

觸發器能實現如下功能:

功能

1、 允許/限制對錶的修改
2、 自動生成派生列,比如自增欄位
3、 強制資料一致性
4、 提供審計和日誌記錄
5、 防止無效的事務處理
6、 啟用複雜的業務邏輯

舉例

1)、下面的觸發器在更新表tb_emp之前觸發,目的是不允許在週末修改表:

?
1 2 3 4 5 6 7 8 create or replace trigger auth_secure before insert or update
or DELETE on tb_emp begin IF(to_char(sysdate,'DY')='星期日') THEN RAISE_APPLICATION_ERROR(-20600,'不能在週末修改表tb_emp'); END IF; END; /

2)、使用觸發器實現序號自增

建立一個測試表:

?
1 2 3 4 5 create table tab_user( id number(11) primary key, username varchar(50), password varchar(50) );

建立一個序列:

複製程式碼 程式碼如下: create sequence my_seq increment by 1 start with 1 nomaxvalue nocycle cache 20;

建立一個觸發器:

?
1 2 3 4 5 6 7 8 9 CREATE OR REPLACE TRIGGER MY_TGR BEFORE INSERT ON TAB_USER FOR EACH ROW--對錶的每一行觸發器執行一次 DECLARE NEXT_ID NUMBER; BEGIN SELECT MY_SEQ.NEXTVAL INTO NEXT_ID FROM DUAL; :NEW.ID := NEXT_ID; --:NEW表示新插入的那條記錄 END;

向表插入資料:

?
1 2 3 4 insert into tab_user(username,password) values('admin','admin'); insert into tab_user(username,password) values('fgz','fgz'); insert into tab_user(username,password) values('test','test'); COMMIT;

查詢表結果:SELECT * FROM TAB_USER;

3)、當用戶對test表執行DML語句時,將相關資訊記錄到日誌表

?
1 2 3 4 5 6 7 8 9 10 11 12 13 --建立測試表 CREATE TABLE test( t_id  NUMBER(4), t_name VARCHAR2(20), t_age NUMBER(2), t_sex CHAR ); --建立記錄測試表 CREATE TABLE test_log( l_user  VARCHAR2(15), l_type  VARCHAR2(15), l_date  VARCHAR2(30) );

建立觸發器:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 --建立觸發器 CREATE OR REPLACE TRIGGER TEST_TRIGGER AFTER DELETE OR INSERT OR UPDATE ON TEST DECLARE V_TYPE TEST_LOG.L_TYPE%TYPE; BEGIN IF INSERTING THEN --INSERT觸發 V_TYPE := 'INSERT'; DBMS_OUTPUT.PUT_LINE('記錄已經成功插入,並已記錄到日誌'); ELSIF UPDATING THEN --UPDATE觸發 V_TYPE := 'UPDATE'; DBMS_OUTPUT.PUT_LINE('記錄已經成功更新,並已記錄到日誌'); ELSIF DELETING THEN --DELETE觸發 V_TYPE := 'DELETE'; DBMS_OUTPUT.PUT_LINE('記錄已經成功刪除,並已記錄到日誌'); END IF; INSERT INTO TEST_LOG VALUES (USER, V_TYPE, TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss')); --USER表示當前使用者名稱 END; / --下面我們來分別執行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;

執行結果如下:

3)、建立觸發器,它將對映emp表中每個部門的總人數和總工資

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 --建立對映表 CREATE TABLE dept_sal AS SELECT deptno, COUNT(empno) total_emp, SUM(sal) total_sal FROM scott.emp GROUP BY deptno; --建立觸發器 CREATE OR REPLACE TRIGGER EMP_INFO AFTER INSERT OR UPDATE OR DELETE ON scott.EMP DECLARE CURSOR CUR_EMP IS SELECT DEPTNO, COUNT(EMPNO) AS TOTAL_EMP, SUM(SAL) AS TOTAL_SAL FROM scott.EMP GROUP BY DEPTNO; BEGIN DELETE DEPT_SAL; --觸發時首先刪除對映表資訊 FOR V_EMP IN CUR_EMP LOOP --DBMS_OUTPUT.PUT_LINE(v_emp.deptno || v_emp.total_emp || v_emp.total_sal); --插入資料 INSERT INTO DEPT_SAL VALUES (V_EMP.DEPTNO, V_EMP.TOTAL_EMP, V_EMP.TOTAL_SAL); END LOOP; END; --對emp表進行DML操作 INSERT INTO emp(empno,deptno,sal) VALUES('123','10',10000); SELECT * FROM dept_sal; DELETE EMP WHERE empno=123; SELECT * FROM dept_sal;

顯示結果如下:

4)、建立觸發器,用來記錄表的刪除資料

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 --建立表 CREATE TABLE employee( id  VARCHAR2(4) NOT NULL, name VARCHAR2(15) NOT NULL, age NUMBER(2)  NOT NULL, sex CHAR NOT NULL ); --插入資料 INSERT INTO employee VALUES('e101','zhao',23,'M'); INSERT INTO employee VALUES('e102','jian',21,'F'); --建立記錄表(包含資料記錄) CREATE TABLE old_employee AS SELECT * FROM employee; --建立觸發器 CREATE OR REPLACE TRIGGER TIG_OLD_EMP AFTER DELETE ON EMPLOYEE FOR EACH ROW --語句級觸發,即每一行觸發一次 BEGIN INSERT INTO OLD_EMPLOYEE VALUES (:OLD.ID, :OLD.NAME, :OLD.AGE, :OLD.SEX); --:old代表舊值 END; / --下面進行測試 DELETE employee; SELECT * FROM old_employee;

5)、建立觸發器,利用檢視插入資料

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 --建立表 CREATE TABLE tab1 (tid NUMBER(4) PRIMARY KEY,tname VARCHAR2(20),tage NUMBER(2)); CREATE TABLE tab2 (tid NUMBER(4),ttel VARCHAR2(15),tadr VARCHAR2(30)); --插入資料 INSERT INTO tab1 VALUES(101,'zhao',22); INSERT INTO tab1 VALUES(102,'yang',20); INSERT INTO tab2 VALUES(101,'13761512841','AnHuiSuZhou'); INSERT INTO tab2 VALUES(102,'13563258514','AnHuiSuZhou'); --建立檢視連線兩張表 CREATE OR REPLACE VIEW tab_view AS SELECT tab1.tid,tname,ttel,tadr FROM tab1,tab2 WHERE tab1.tid = tab2.tid; --建立觸發器 CREATE OR REPLACE TRIGGER TAB_TRIGGER INSTEAD OF INSERT ON TAB_VIEW BEGIN INSERT INTO TAB1 (TID, TNAME) VALUES (:NEW.TID, :NEW.TNAME); INSERT INTO TAB2 (TTEL, TADR) VALUES (:NEW.TTEL, :NEW.TADR); END; / --現在就可以利用檢視插入資料 INSERT INTO tab_view VALUES(106,'ljq','13886681288','beijing'); --查詢 SELECT * FROM tab_view; SELECT * FROM tab1; SELECT * FROM tab2;

6)、建立觸發器,比較emp表中更新的工資

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 --建立觸發器 set serveroutput on; CREATE OR REPLACE TRIGGER SAL_EMP BEFORE UPDATE ON EMP FOR EACH ROW BEGIN IF :OLD.SAL > :NEW.SAL THEN DBMS_OUTPUT.PUT_LINE('工資減少'); ELSIF :OLD.SAL < :NEW.SAL THEN DBMS_OUTPUT.PUT_LINE('工資增加'); ELSE DBMS_OUTPUT.PUT_LINE('工資未作任何變動'); END IF; DBMS_OUTPUT.PUT_LINE('更新前工資 :' || :OLD.SAL); DBMS_OUTPUT.PUT_LINE('更新後工資 :' || :NEW.SAL); END; / --執行UPDATE檢視效果 UPDATE emp SET sal = 3000 WHERE empno = '7788';

執行結果如下:

7)、建立觸發器,將操作CREATE、DROP儲存在log_info表

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 --建立表 CREATE TABLE log_info( manager_user VARCHAR2(15), manager_date VARCHAR2(15), manager_type VARCHAR2(15), obj_name   VARCHAR2(15), obj_type   VARCHAR2(15) ); --建立觸發器 set serveroutput on; CREATE OR REPLACE TRIGGER TRIG_LOG_INFO AFTER CREATE OR DROP ON SCHEMA BEGIN INSERT INTO LOG_INFO VALUES (USER, SYSDATE, SYS.DICTIONARY_OBJ_NAME, SYS.DICTIONARY_OBJ_OWNER, SYS.DICTIONARY_OBJ_TYPE); END; / --測試語句 CREATE TABLE a(id NUMBER); CREATE TYPE aa AS OBJECT(id NUMBER); DROP TABLE a; DROP TYPE aa; --檢視效果 SELECT * FROM log_info; --相關資料字典----------------------------------------------------- SELECT * FROM USER_TRIGGERS; --必須以DBA身份登陸才能使用此資料字典 SELECT * FROM ALL_TRIGGERS;SELECT * FROM DBA_TRIGGERS; --啟用和禁用 ALTER TRIGGER trigger_name DISABLE; ALTER TRIGGER trigger_name ENABLE;

希望本文所述對大家Oracle資料庫程式設計有所幫助。

相關推薦

Oracle觸發器用法例項

本文例項講述了Oracle觸發器用法。分享給大家供大家參考,具體如下: 一、觸發器簡介 觸發器的定義就是說某個條件成立的時候,觸發器裡面所定義的語句就會被自動的執行。因此觸發器不需要人為的去呼叫,也不能呼叫。然後,觸發器的觸發條件其實在你定義的時候就已經設定好了。這裡面需

javascript中this用法例項

JavaScript中的this含義非常豐富,它可以是全域性物件,當前物件或者是任意物件,這都取決於函式的呼叫方式。函式有以下幾種呼叫方式:作為物件方法呼叫、作為函式呼叫、作為建構函式呼叫、apply或call呼叫。 物件方法呼叫 作為物件方法呼叫的時候,this會被繫結到該物件。 ?

js事件監聽器用法例項

本文例項講述了js事件監聽器用法。分享給大家供大家參考。具體分析如下: 1、當同一個物件使用.onclick的寫法觸發多個方法的時候,後一個方法會把前一個方法覆蓋掉,也就是說,在物件的onclick事件發生時,只會執行最後繫結的方法。而用事件監聽則不會有覆蓋的現象,每個繫結的事件都會被執行。

vue 元件高階用法例項

  一、遞迴元件    元件在它的模板內可以遞迴地呼叫自己, 只要給元件設定name 的選項就可以了。    示例如下:    <div id="app19">    <my-component19 :count="1"></my-component19>    </

mysql觸發器trigger 例項

MySQL好像從5.0.2版本就開始支援觸發器的功能了,本次部落格就來介紹一下觸發器,首先還是談下概念性的東西吧: 什麼是觸發器 觸發器是與表有關的資料庫物件,在滿足定義條件時觸發,並執行觸發器中定義的語句集合。觸發器的這種特性可以協助應用在資料庫端確保資料的完整性。

資料庫工作筆記012---mysql觸發器trigger 例項_保證資料庫完整性還是不錯的

 mysql的觸發器,可以挺好的保證資料庫的資料的完整性,這個還是不錯的     JAVA技術交流QQ群:170933152   比如: 我一個表中的資料有變化,那麼與之關聯的幾個表可以通過觸發器來實現同步 --------

MySQL欄位自增長AUTO_INCREMENT用法例項

之前有碰到過開發同事指出一張InnoDB表的自增列 AUTO_INCREMENT 值莫明的變大,由於這張表是通過mysqldump匯出匯入的。 問題排查: 1、首先,查看錶表義的sql部分的 auto_increment 值部分是正常,所以排除是匯入表問題所引起的;2、最後,經過溝通了解懷疑是插入時

Python多程序併發(multiprocessing)用法例項

python多執行緒的限制python多執行緒有個討厭的限制,全域性直譯器鎖(global interpreter lock),這個鎖的意思是任一時間只能有一個執行緒使用直譯器,跟單cpu跑多個程式一個意思,大家都是輪著用的,這叫“併發”,不是“並行”。手冊上的解釋是為了保證

C++ pair的用法例項(結構體模板應用初探)

1 pair的應用(結構體模板)pair是將2個數據組合成一個數據,當需要這樣的需求時就可以使用pair,如stl中的map就是將key和value放在一起來儲存。另一個應用是,當一個函式需要返回2個數據的時候,可以選擇pair。標頭檔案:#include<utilit

Ajax用法例項

本文例項講述了jQuery學習筆記之Ajax用法。分享給大家供大家參考,具體如下: 一、Ajax請求 1、jQuery.ajax(options) 通過 HTTP 請求載入遠端資料。jQuery 底層 AJAX 實現。簡單易用的高層實現見 .get,.post 等。

PHP單例模式和工廠模式用法例項

設計模式是一套被反覆使用、多數人知曉的、經過分類編目的、程式碼設計經驗的總結。使用設計模式是為了可重用程式碼、讓程式碼更容易被他人理解、保證程式碼可靠性。毫無疑問,設計模式於己於他人於系統都是多贏的;設計模式使程式碼編制真正工程化;設計模式是軟體工程的基石脈絡,如同大廈的結

JavaScript中window.open用法例項

本文較為詳細的分析了JavaScript中window.open用法。分享給大家供大家參考。具體如下: 複製程式碼 程式碼如下: <script LANGUAGE="javascript"> window.open ('page.html', 'newwind

SQL建立觸發器以及觸發器的使用例項+

MySQL的觸發器使用例項: 解決   觸發器被觸發後,向表裡插入資料時判斷該條記錄是否存在,如果存在則更新,不存在則插入 的問題 首先,宣告一下 mysql  中寫的sql執行語句全部在  begin    &nbs

oracle 建立表空間例項

建立臨時表空間----->建立表空間---->建立使用者指定表空間----->授權     --查詢表空間 select * from dba_tablespaces --查詢表空間路徑 select * from dba_data_file

mysql觸發器new old 例項

mysql觸發器new old: "NEW . column_name"或者"OLD . column_name".這樣在技術上處理(NEW | OLD . column_name)新和舊 的列名屬於建立了過渡變數("transition variables")。

java中List的用法例項

的用法List包括List介面以及List介面的所有實現類。因為List介面實現了Collection介面,所以List介面擁有Collection介面提供的所有常用方法,又因為List是列表型別,所以List介面還提供了一些適合於自身的常用方法,如表1所示。表1 List介面定義的常用方法及功能從表1可以看

Oracle expdp/impdp 用法例子 舉例 例子 他的這篇文章沒有辦法寫出來 要這麼改

在之前的blog:        Oracle 10g Data Pump Expdp/Impdp 詳解        exp/imp 與 expdp/impdp 對比及使用中的一些優化事項        中對資料泵這塊的理論知識有一些說明,但是沒有實際操作的例子。 所以在這裡就對expdp/im

Linux top命令的用法詳細

command load 命令 技術分享 服務 範圍 web服務器 睡眠狀態 打開 查看多核CPU命令mpstat -P ALL 和 sar -P ALL 說明:sar -P ALL > aaa.txt 重定向輸出內容到文件 aaa.txt top命令經

oracle pctfree和pctused

blank 可用 htm post alt lock tables span 重新 一、建立表時候,註意PCTFREE參數的作用 PCTFREE:為一個塊保留的空間百分比,表示數據塊在什麽情況下可以被insert,默認是10,表示當數據塊的可用空間低於

oracle常用函數(詳細)

sub 最後一天 run -1 fonts ase 必須 顯示 分享 作者:紅旗飄揚 Oracle SQL 提供了用於執行特定操作的專用函數。這些函數大大增強了 SQL 語言的功能。函數可以接受零個或者多個輸入參數,並返回一個輸出結果。 oracle 數據庫中主要使用兩種