![Orcale觸發(fā)器詳解_第1頁](http://file2.renrendoc.com/fileroot_temp3/2021-10/24/180202c8-d058-4522-ad26-13386b90964b/180202c8-d058-4522-ad26-13386b90964b1.gif)
![Orcale觸發(fā)器詳解_第2頁](http://file2.renrendoc.com/fileroot_temp3/2021-10/24/180202c8-d058-4522-ad26-13386b90964b/180202c8-d058-4522-ad26-13386b90964b2.gif)
![Orcale觸發(fā)器詳解_第3頁](http://file2.renrendoc.com/fileroot_temp3/2021-10/24/180202c8-d058-4522-ad26-13386b90964b/180202c8-d058-4522-ad26-13386b90964b3.gif)
![Orcale觸發(fā)器詳解_第4頁](http://file2.renrendoc.com/fileroot_temp3/2021-10/24/180202c8-d058-4522-ad26-13386b90964b/180202c8-d058-4522-ad26-13386b90964b4.gif)
![Orcale觸發(fā)器詳解_第5頁](http://file2.renrendoc.com/fileroot_temp3/2021-10/24/180202c8-d058-4522-ad26-13386b90964b/180202c8-d058-4522-ad26-13386b90964b5.gif)
版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、ORACLE PL/SQL編程之八: 把觸發(fā)器說透 本篇主要內(nèi)容如下:8.1 觸發(fā)器類型8.1.1 DML觸發(fā)器8.1.2 替代觸發(fā)器8.1.3 系統(tǒng)觸發(fā)器8.2 創(chuàng)建觸發(fā)器8.2.1 觸發(fā)器觸發(fā)次序8.2.2 創(chuàng)建DML觸發(fā)器8.2.3 創(chuàng)建替代(INSTEAD OF)觸發(fā)器8.2.3 創(chuàng)建系統(tǒng)事件觸發(fā)器8.2.4 系統(tǒng)觸發(fā)器事件屬性8.2.5 使用觸發(fā)器謂詞8.2.6 重新編譯觸發(fā)器8.3 刪除和使能觸發(fā)器8.4 觸發(fā)器和數(shù)據(jù)字典8.5 數(shù)據(jù)庫觸發(fā)器的應用舉例 觸發(fā)器是許多關系數(shù)據(jù)庫系統(tǒng)都提供的一項技術。在ORACLE系統(tǒng)里,觸發(fā)器類似過程和函數(shù),都有聲明,執(zhí)行和異常處理過程的PL/SQL
2、塊。8.1 觸發(fā)器類型 觸發(fā)器在數(shù)據(jù)庫里以獨立的對象存儲,它與存儲過程和函數(shù)不同的是,存儲過程與函數(shù)需要用戶顯示調(diào)用才執(zhí)行,而觸發(fā)器是由一個事件來啟動運行。即觸發(fā)器是當某個事件發(fā)生時自動地隱式運行。并且,觸發(fā)器不能接收參數(shù)。所以運行觸發(fā)器就叫觸發(fā)或點火(firing)。ORACLE事件指的是對數(shù)據(jù)庫的表進行的INSERT、UPDATE及DELETE操作或?qū)σ晥D進行類似的操作。ORACLE將觸發(fā)器的功能擴展到了觸發(fā)ORACLE,如數(shù)據(jù)庫的啟動與關閉等。所以觸發(fā)器常用來完成由數(shù)據(jù)庫的完整性約束難以完成的復雜業(yè)務規(guī)則的約束,或用來監(jiān)視對數(shù)據(jù)庫的各種操作,實現(xiàn)審計的功能。 8.1.1 DML觸發(fā)器 O
3、RACLE可以在DML語句進行觸發(fā),可以在DML操作前或操作后進行觸發(fā),并且可以對每個行或語句操作上進行觸發(fā)。 8.1.2 替代觸發(fā)器 由于在ORACLE里,不能直接對由兩個以上的表建立的視圖進行操作。所以給出了替代觸發(fā)器。它就是ORACLE 8專門為進行視圖操作的一種處理方法。 8.1.3 系統(tǒng)觸發(fā)器ORACLE 8i 提供了第三種類型的觸發(fā)器叫系統(tǒng)觸發(fā)器。它可以在ORACLE數(shù)據(jù)庫系統(tǒng)的事件中進行觸發(fā),如ORACLE系統(tǒng)的啟動與關閉等。 觸發(fā)器組成: l 觸發(fā)事件:引起觸發(fā)器被觸發(fā)的事件。 例如:DML語句(INSERT, UPDATE, DELETE語句對表或視圖執(zhí)行數(shù)據(jù)處理操作)、DD
4、L語句(如CREATE、ALTER、DROP語句在數(shù)據(jù)庫中創(chuàng)建、修改、刪除模式對象)、數(shù)據(jù)庫系統(tǒng)事件(如系統(tǒng)啟動或退出、異常錯誤)、用戶事件(如登錄或退出數(shù)據(jù)庫)。l 觸發(fā)時間:即該TRIGGER 是在觸發(fā)事件發(fā)生之前(BEFORE)還是之后(AFTER)觸發(fā),也就是觸發(fā)事件和該TRIGGER 的操作順序。l 觸發(fā)操作:即該TRIGGER 被觸發(fā)之后的目的和意圖,正是觸發(fā)器本身要做的事情。 例如:PL/SQL 塊。l 觸發(fā)對象:包括表、視圖、模式、數(shù)據(jù)庫。只有在這些對象上發(fā)生了符合觸發(fā)條件的觸發(fā)事件,才會執(zhí)行觸發(fā)操作。l 觸發(fā)條件:由WHEN子句指定一個邏輯表達式。只有當該表達式的值為TRUE
5、時,遇到觸發(fā)事件才會自動執(zhí)行觸發(fā)器,使其執(zhí)行觸發(fā)操作。l 觸發(fā)頻率:說明觸發(fā)器內(nèi)定義的動作被執(zhí)行的次數(shù)。即語句級(STATEMENT)觸發(fā)器和行級(ROW)觸發(fā)器。語句級(STATEMENT)觸發(fā)器:是指當某觸發(fā)事件發(fā)生時,該觸發(fā)器只執(zhí)行一次;行級(ROW)觸發(fā)器:是指當某觸發(fā)事件發(fā)生時,對受到該操作影響的每一行數(shù)據(jù),觸發(fā)器都單獨執(zhí)行一次。編寫觸發(fā)器時,需要注意以下幾點:l 觸發(fā)器不接受參數(shù)。l 一個表上最多可有12個觸發(fā)器,但同一時間、同一事件、同一類型的觸發(fā)器只能有一個。并各觸發(fā)器之間不能有矛盾。l 在一個表上的觸發(fā)器越多,對在該表上的DML操作的性能影響就越大。l 觸發(fā)器最大為32KB。
6、若確實需要,可以先建立過程,然后在觸發(fā)器中用CALL語句進行調(diào)用。l 在觸發(fā)器的執(zhí)行部分只能用DML語句(SELECT、INSERT、UPDATE、DELETE),不能使用DDL語句(CREATE、ALTER、DROP)。l 觸發(fā)器中不能包含事務控制語句(COMMIT,ROLLBACK,SAVEPOINT)。因為觸發(fā)器是觸發(fā)語句的一部分,觸發(fā)語句被提交、回退時,觸發(fā)器也被提交、回退了。l 在觸發(fā)器主體中調(diào)用的任何過程、函數(shù),都不能使用事務控制語句。l 在觸發(fā)器主體中不能申明任何Long和blob變量。新值new和舊值old也不能是表中的任何long和blob列。l 不同類型的觸發(fā)器(如DML觸
7、發(fā)器、INSTEAD OF觸發(fā)器、系統(tǒng)觸發(fā)器)的語法格式和作用有較大區(qū)別。 8.2 創(chuàng)建觸發(fā)器創(chuàng)建觸發(fā)器的一般語法是: CREATE OR REPLACE TRIGGER trigger_nameBEFORE | AFTER INSERT | DELETE | UPDATE OF column , column OR INSERT | DELETE | UPDATE OF column , column .ON schema.table_name | schema.view_name REFERENCING OLD AS old | NEW AS new| PARENT as parentFO
8、R EACH ROW WHEN conditionPL/SQL_BLOCK | CALL procedure_name; 其中:BEFORE 和AFTER指出觸發(fā)器的觸發(fā)時序分別為前觸發(fā)和后觸發(fā)方式,前觸發(fā)是在執(zhí)行觸發(fā)事件之前觸發(fā)當前所創(chuàng)建的觸發(fā)器,后觸發(fā)是在執(zhí)行觸發(fā)事件之后觸發(fā)當前所創(chuàng)建的觸發(fā)器。 FOR EACH ROW選項說明觸發(fā)器為行觸發(fā)器。行觸發(fā)器和語句觸發(fā)器的區(qū)別表現(xiàn)在:行觸發(fā)器要求當一個DML語句操作影響數(shù)據(jù)庫中的多行數(shù)據(jù)時,對于其中的每個數(shù)據(jù)行,只要它們符合觸發(fā)約束條件,均激活一次觸發(fā)器;而語句觸發(fā)器將整個語句操作作為觸發(fā)事件,當它符合約束條件時,激活一次觸發(fā)器。當省略FOR
9、EACH ROW 選項時,BEFORE 和AFTER 觸發(fā)器為語句觸發(fā)器,而INSTEAD OF 觸發(fā)器則只能為行觸發(fā)器。 REFERENCING 子句說明相關名稱,在行觸發(fā)器的PL/SQL塊和WHEN 子句中可以使用相關名稱參照當前的新、舊列值,默認的相關名稱分別為OLD和NEW。觸發(fā)器的PL/SQL塊中應用相關名稱時,必須在它們之前加冒號(:),但在WHEN子句中則不能加冒號。WHEN 子句說明觸發(fā)約束條件。Condition 為一個邏輯表達時,其中必須包含相關名稱,而不能包含查詢語句,也不能調(diào)用PL/SQL 函數(shù)。WHEN 子句指定的觸發(fā)約束條件只能用在BEFORE 和AFTER 行觸發(fā)
10、器中,不能用在INSTEAD OF 行觸發(fā)器和其它類型的觸發(fā)器中。 當一個基表被修改( INSERT, UPDATE, DELETE)時要執(zhí)行的存儲過程,執(zhí)行時根據(jù)其所依附的基表改動而自動觸發(fā),因此與應用程序無關,用數(shù)據(jù)庫觸發(fā)器可以保證數(shù)據(jù)的一致性和完整性。 每張表最多可建立12 種類型的觸發(fā)器,它們是:BEFORE INSERTBEFORE INSERT FOR EACH ROWAFTER INSERTAFTER INSERT FOR EACH ROW BEFORE UPDATEBEFORE UPDATE FOR EACH ROWAFTER UPDATEAFTER UPDATE FOR EA
11、CH ROW BEFORE DELETEBEFORE DELETE FOR EACH ROWAFTER DELETEAFTER DELETE FOR EACH ROW 8.2.1 觸發(fā)器觸發(fā)次序1. 執(zhí)行 BEFORE語句級觸發(fā)器;2. 對與受語句影響的每一行:l 執(zhí)行 BEFORE行級觸發(fā)器l 執(zhí)行 DML語句l 執(zhí)行 AFTER行級觸發(fā)器 3. 執(zhí)行 AFTER語句級觸發(fā)器 8.2.2 創(chuàng)建DML觸發(fā)器 觸發(fā)器名與過程名和包的名字不一樣,它是單獨的名字空間,因而觸發(fā)器名可以和表或過程有相同的名字,但在一個模式中觸發(fā)器名不能相同。 DML觸發(fā)器的限制l CREATE TRIGGER語句文本的
12、字符長度不能超過32KB;l 觸發(fā)器體內(nèi)的SELECT 語句只能為SELECT INTO 結構,或者為定義游標所使用的SELECT 語句。l 觸發(fā)器中不能使用數(shù)據(jù)庫事務控制語句 COMMIT; ROLLBACK, SVAEPOINT 語句;l 由觸發(fā)器所調(diào)用的過程或函數(shù)也不能使用數(shù)據(jù)庫事務控制語句;l 觸發(fā)器中不能使用LONG, LONG RAW 類型;l 觸發(fā)器內(nèi)可以參照LOB 類型列的列值,但不能通過 :NEW 修改LOB列中的數(shù)據(jù); DML觸發(fā)器基本要點l 觸發(fā)時機:指定觸發(fā)器的觸發(fā)時間。如果指定為BEFORE,則表示在執(zhí)行DML操作之前觸發(fā),以便防止某些錯誤操作發(fā)生或?qū)崿F(xiàn)某些業(yè)務規(guī)則;
13、如果指定為AFTER,則表示在執(zhí)行DML操作之后觸發(fā),以便記錄該操作或做某些事后處理。l 觸發(fā)事件:引起觸發(fā)器被觸發(fā)的事件,即DML操作(INSERT、UPDATE、DELETE)。既可以是單個觸發(fā)事件,也可以是多個觸發(fā)事件的組合(只能使用OR邏輯組合,不能使用AND邏輯組合)。l 條件謂詞:當在觸發(fā)器中包含多個觸發(fā)事件(INSERT、UPDATE、DELETE)的組合時,為了分別針對不同的事件進行不同的處理,需要使用ORACLE提供的如下條件謂詞。1)。INSERTING:當觸發(fā)事件是INSERT時,取值為TRUE,否則為FALSE。2)。UPDATING (column_1,column_
14、2,column_x):當觸發(fā)事件是UPDATE 時,如果修改了column_x列,則取值為TRUE,否則為FALSE。其中column_x是可選的。3)。DELETING:當觸發(fā)事件是DELETE時,則取值為TRUE,否則為FALSE。解發(fā)對象:指定觸發(fā)器是創(chuàng)建在哪個表、視圖上。l 觸發(fā)類型:是語句級還是行級觸發(fā)器。l 觸發(fā)條件:由WHEN子句指定一個邏輯表達式,只允許在行級觸發(fā)器上指定觸發(fā)條件,指定UPDATING后面的列的列表。 問題:當觸發(fā)器被觸發(fā)時,要使用被插入、更新或刪除的記錄中的列值,有時要使用操作前、 后列的值.實現(xiàn): :NEW 修飾符訪問操作完成后列的值 :OLD 修飾符訪問
15、操作完成前列的值 特性INSERTUPDATEDELETEOLDNULL實際值實際值NEW實際值實際值NULL 例1: 建立一個觸發(fā)器, 當職工表 emp 表被刪除一條記錄時,把被刪除記錄寫到職工表刪除日志表中去。 CREATE TABLE emp_his AS SELECT * FROM EMP WHERE 1=2; CREATE OR REPLACE TRIGGER tr_del_emp BEFORE DELETE -指定觸發(fā)時機為刪除操作前觸發(fā) ON scott.emp FOR EACH ROW -說明創(chuàng)建的是行級觸發(fā)器 BEGIN -將修改前數(shù)據(jù)插入到日志記錄表 del_emp ,以供
16、監(jiān)督使用。 INSERT INTO emp_his(deptno , empno, ename , job ,mgr , sal , comm , hiredate ) VALUES( :old.deptno, :old.empno, :old.ename , :old.job,:old.mgr, :old.sal, :m, :old.hiredate );END;DELETE emp WHERE empno=7788;DROP TABLE emp_his;DROP TRIGGER del_emp; 例2:限制對Departments表修改(包括INSERT,DELETE,UPDATE)的時間
17、范圍,即不允許在非工作時間修改departments表。 CREATE OR REPLACE TRIGGER tr_dept_timeBEFORE INSERT OR DELETE OR UPDATE ON departmentsBEGINIF (TO_CHAR(sysdate,DAY) IN (星期六, 星期日) OR (TO_CHAR(sysdate, HH24:MI) NOT BETWEEN 08:30 AND 18:00) THEN RAISE_APPLICATION_ERROR(-20001, 不是上班時間,不能修改departments表);END IF;END; 例3:限定只對部
18、門號為80的記錄進行行觸發(fā)器操作。 CREATE OR REPLACE TRIGGER tr_emp_sal_commBEFORE UPDATE OF salary, commission_pct OR DELETEON HR.employeesFOR EACH ROWWHEN (old.department_id = 80)BEGINCASE WHEN UPDATING (salary) THEN IF :NEW.salary :old.salary THEN RAISE_APPLICATION_ERROR(-20001, 部門80的人員的工資不能降); END IF; WHEN UPDAT
19、ING (commission_pct) THEN IF :NEW.commission_pct DELETE FROM emp_view WHERE deptno=10;DELETE FROM emp_view WHERE deptno=10 ERROR 位于第 1 行:ORA-01732: 此視圖的數(shù)據(jù)操縱操作非法 但是我們可以創(chuàng)建INSTEAD_OF觸發(fā)器來為 DELETE 操作執(zhí)行所需的處理,即刪除EMP表中所有基準行: CREATE OR REPLACE TRIGGER emp_view_delete INSTEAD OF DELETE ON emp_view FOR EACH RO
20、WBEGIN DELETE FROM emp WHERE deptno= :old.deptno;END emp_view_delete; DELETE FROM emp_view WHERE deptno=10; DROP TRIGGER emp_view_delete;DROP VIEW emp_view; 例2:創(chuàng)建復雜視圖,針對INSERT操作創(chuàng)建INSTEAD OF觸發(fā)器,向復雜視圖插入數(shù)據(jù)。l 創(chuàng)建視圖: CREATE OR REPLACE FORCE VIEW HR.V_REG_COU (R_ID, R_NAME, C_ID, C_NAME)ASSELECT r.region_i
21、d, r.region_name, c.country_id, c.country_nameFROM regions r, countries cWHERE r.region_id = c.region_id; l 創(chuàng)建觸發(fā)器: CREATE OR REPLACE TRIGGER HR.TR_I_O_REG_COU INSTEAD OFINSERT ON v_reg_cou FOR EACH ROW DECLARE v_count NUMBER;BEGINSELECT COUNT(*) INTO v_count FROM regions WHERE region_id = :new.r_id;
22、IF v_count = 0 THEN INSERT INTO regions (region_id, region_name ) VALUES (:new.r_id, :new.r_name );END IF;SELECT COUNT(*) INTO v_count FROM countries WHERE country_id = :new.c_id;IF v_count = 0 THEN INSERT INTO countries ( country_id, country_name, region_id ) VALUES ( :new.c_id, :new.c_name, :new.r
23、_id );END IF;END; 創(chuàng)建INSTEAD OF觸發(fā)器需要注意以下幾點:l 只能被創(chuàng)建在視圖上,并且該視圖沒有指定WITH CHECK OPTION選項。l 不能指定BEFORE 或 AFTER選項。l FOR EACH ROW子可是可選的,即INSTEAD OF觸發(fā)器只能在行級上觸發(fā)、或只能是行級觸發(fā)器,沒有必要指定。l 沒有必要在針對一個表的視圖上創(chuàng)建INSTEAD OF觸發(fā)器,只要創(chuàng)建DML觸發(fā)器就可以了。 8.2.3 創(chuàng)建系統(tǒng)事件觸發(fā)器 ORACLE10G提供的系統(tǒng)事件觸發(fā)器可以在DDL或數(shù)據(jù)庫系統(tǒng)上被觸發(fā)。DDL指的是數(shù)據(jù)定義語言,如CREATE 、ALTER及DROP
24、等。而數(shù)據(jù)庫系統(tǒng)事件包括數(shù)據(jù)庫服務器的啟動或關閉,用戶的登錄與退出、數(shù)據(jù)庫服務錯誤等。創(chuàng)建系統(tǒng)觸發(fā)器的語法如下: 創(chuàng)建觸發(fā)器的一般語法是: CREATE OR REPLACE TRIGGER sachema.trigger_nameBEFORE|AFTER ddl_event_list | database_event_listON DATABASE | schema.SCHEMA WHEN conditionPL/SQL_block | CALL procedure_name; 其中: ddl_event_list:一個或多個DDL 事件,事件間用 OR 分開; database_event
25、_list:一個或多個數(shù)據(jù)庫事件,事件間用 OR 分開; 系統(tǒng)事件觸發(fā)器既可以建立在一個模式上,又可以建立在整個數(shù)據(jù)庫上。當建立在模式(SCHEMA)之上時,只有模式所指定用戶的DDL操作和它們所導致的錯誤才激活觸發(fā)器, 默認時為當前用戶模式。當建立在數(shù)據(jù)庫(DATABASE)之上時,該數(shù)據(jù)庫所有用戶的DDL操作和他們所導致的錯誤,以及數(shù)據(jù)庫的啟動和關閉均可激活觸發(fā)器。要在數(shù)據(jù)庫之上建立觸發(fā)器時,要求用戶具有ADMINISTER DATABASE TRIGGER權限。 下面給出系統(tǒng)觸發(fā)器的種類和事件出現(xiàn)的時機(前或后):事件允許的時機說明STARTUPAFTER啟動數(shù)據(jù)庫實例之后觸發(fā)SHUTD
26、OWNBEFORE關閉數(shù)據(jù)庫實例之前觸發(fā)(非正常關閉不觸發(fā))SERVERERRORAFTER數(shù)據(jù)庫服務器發(fā)生錯誤之后觸發(fā)LOGONAFTER成功登錄連接到數(shù)據(jù)庫后觸發(fā)LOGOFFBEFORE開始斷開數(shù)據(jù)庫連接之前觸發(fā)CREATEBEFORE,AFTER在執(zhí)行CREATE語句創(chuàng)建數(shù)據(jù)庫對象之前、之后觸發(fā)DROPBEFORE,AFTER在執(zhí)行DROP語句刪除數(shù)據(jù)庫對象之前、之后觸發(fā)ALTERBEFORE,AFTER在執(zhí)行ALTER語句更新數(shù)據(jù)庫對象之前、之后觸發(fā)DDLBEFORE,AFTER在執(zhí)行大多數(shù)DDL語句之前、之后觸發(fā)GRANTBEFORE,AFTER執(zhí)行GRANT語句授予權限之前、之后觸
27、發(fā)REVOKEBEFORE,AFTER執(zhí)行REVOKE語句收權限之前、之后觸犯發(fā)RENAMEBEFORE,AFTER執(zhí)行RENAME語句更改數(shù)據(jù)庫對象名稱之前、之后觸犯發(fā)AUDIT / NOAUDITBEFORE,AFTER執(zhí)行AUDIT或NOAUDIT進行審計或停止審計之前、之后觸發(fā) 8.2.4 系統(tǒng)觸發(fā)器事件屬性 事件屬性事件Startup/ShutdownServererrorLogon/LogoffDDLDML事件名稱數(shù)據(jù)庫名稱 數(shù)據(jù)庫實例號 錯誤號 用戶名 模式對象類型 模式對象名稱 列 除DML語句的列屬性外,其余事件屬性值可通過調(diào)用ORACLE定義的事件屬性函數(shù)來讀取。函數(shù)名稱數(shù)
28、據(jù)類型說 明Ora_syseventVARCHAR2(20)激活觸發(fā)器的事件名稱Instance_numNUMBER數(shù)據(jù)庫實例名Ora_database_nameVARCHAR2(50)數(shù)據(jù)庫名稱Server_error(posi)NUMBER錯誤信息棧中posi指定位置中的錯誤號 Is_servererror(err_number) BOOLEAN檢查err_number指定的錯誤號是否在錯誤信息棧中,如果在則返回TRUE,否則返回FALSE。在觸發(fā)器內(nèi)調(diào)用此函數(shù)可以判斷是否發(fā)生指定的錯誤。Login_userVARCHAR2(30)登陸或注銷的用戶名稱Dictionary_obj_type
29、VARCHAR2(20)DDL語句所操作的數(shù)據(jù)庫對象類型Dictionary_obj_nameVARCHAR2(30)DDL語句所操作的數(shù)據(jù)庫對象名稱Dictionary_obj_ownerVARCHAR2(30)DDL語句所操作的數(shù)據(jù)庫對象所有者名稱Des_encrypted_passwordVARCHAR2(2)正在創(chuàng)建或修改的經(jīng)過DES算法加密的用戶口令 例1:創(chuàng)建觸發(fā)器,存放有關事件信息。DESC ora_syseventDESC ora_login_user-創(chuàng)建用于記錄事件用的表CREATE TABLE ddl_event(crt_date timestamp PRIMARY KE
30、Y, event_name VARCHAR2(20), user_name VARCHAR2(10), obj_type VARCHAR2(20), obj_name VARCHAR2(20);-創(chuàng)建觸犯發(fā)器CREATE OR REPLACE TRIGGER tr_ddlAFTER DDL ON SCHEMABEGIN INSERT INTO ddl_event VALUES (systimestamp,ora_sysevent, ora_login_user, ora_dict_obj_type, ora_dict_obj_name);END tr_ddl; 例2:創(chuàng)建登錄、退出觸發(fā)器。 C
31、REATE TABLE log_event(user_name VARCHAR2(10), address VARCHAR2(20), logon_date timestamp, logoff_date timestamp); -創(chuàng)建登錄觸發(fā)器CREATE OR REPLACE TRIGGER tr_logonAFTER LOGON ON DATABASEBEGIN INSERT INTO log_event (user_name, address, logon_date) VALUES (ora_login_user, ora_client_ip_address, systimestamp)
32、;END tr_logon;-創(chuàng)建退出觸發(fā)器CREATE OR REPLACE TRIGGER tr_logoffBEFORE LOGOFF ON DATABASEBEGIN INSERT INTO log_event (user_name, address, logoff_date) VALUES (ora_login_user, ora_client_ip_address, systimestamp);END tr_logoff; 8.2.5 使用觸發(fā)器謂詞 ORACLE 提供三個參數(shù)INSERTING, UPDATING,DELETING 用于判斷觸發(fā)了哪些操作。謂詞行為INSERTIN
33、G如果觸發(fā)語句是 INSERT 語句,則為TRUE,否則為FALSEUPDATING如果觸發(fā)語句是 UPDATE語句,則為TRUE,否則為FALSEDELETING如果觸發(fā)語句是 DELETE 語句,則為TRUE,否則為FALSE 8.2.6 重新編譯觸發(fā)器如果在觸發(fā)器內(nèi)調(diào)用其它函數(shù)或過程,當這些函數(shù)或過程被刪除或修改后,觸發(fā)器的狀態(tài)將被標識為無效。當DML語句激活一個無效觸發(fā)器時,ORACLE將重新編譯觸發(fā)器代碼,如果編譯時發(fā)現(xiàn)錯誤,這將導致DML語句執(zhí)行失敗。在PL/SQL程序中可以調(diào)用ALTER TRIGGER語句重新編譯已經(jīng)創(chuàng)建的觸發(fā)器,格式為: ALTER TRIGGER schem
34、a. trigger_name COMPILE DEBUG 其中:DEBUG 選項要器編譯器生成PL/SQL 程序條使其所使用的調(diào)試代碼。8.3 刪除和使能觸發(fā)器l 刪除觸發(fā)器:DROP TRIGGER trigger_name;當刪除其他用戶模式中的觸發(fā)器名稱,需要具有DROP ANY TRIGGER系統(tǒng)權限,當刪除建立在數(shù)據(jù)庫上的觸發(fā)器時,用戶需要具有ADMINISTER DATABASE TRIGGER系統(tǒng)權限。此外,當刪除表或視圖時,建立在這些對象上的觸發(fā)器也隨之刪除。 l 禁用或啟用觸發(fā)器數(shù)據(jù)庫TRIGGER 的狀態(tài):有效狀態(tài)(ENABLE):當觸發(fā)事件發(fā)生時,處于有效狀態(tài)的數(shù)據(jù)庫觸
35、發(fā)器TRIGGER 將被觸發(fā)。無效狀態(tài)(DISABLE):當觸發(fā)事件發(fā)生時,處于無效狀態(tài)的數(shù)據(jù)庫觸發(fā)器TRIGGER 將不會被觸發(fā),此時就跟沒有這個數(shù)據(jù)庫觸發(fā)器(TRIGGER) 一樣。數(shù)據(jù)庫TRIGGER的這兩種狀態(tài)可以互相轉(zhuǎn)換。格式為:ALTER TIGGER trigger_name DISABLE | ENABLE ;-例:ALTER TRIGGER emp_view_delete DISABLE; ALTER TRIGGER語句一次只能改變一個觸發(fā)器的狀態(tài),而ALTER TABLE語句則一次能夠改變與指定表相關的所有觸發(fā)器的使用狀態(tài)。格式為: ALTER TABLE schema.t
36、able_name ENABLE|DISABLE ALL TRIGGERS;-例:使表EMP 上的所有TRIGGER 失效:ALTER TABLE emp DISABLE ALL TRIGGERS; 8.4 觸發(fā)器和數(shù)據(jù)字典相關數(shù)據(jù)字典:USER_TRIGGERS、ALL_TRIGGERS、DBA_TRIGGERS SELECT TRIGGER_NAME, TRIGGER_TYPE, TRIGGERING_EVENT, TABLE_OWNER, BASE_OBJECT_TYPE, REFERENCING_NAMES, STATUS, ACTION_TYPEFROM user_triggers;
37、 8.5 數(shù)據(jù)庫觸發(fā)器的應用舉例例1:創(chuàng)建一個DML語句級觸發(fā)器,當對emp表執(zhí)行INSERT, UPDATE, DELETE 操作時,它自動更新dept_summary 表中的數(shù)據(jù)。由于在PL/SQL塊中不能直接調(diào)用DDL語句,所以,利用ORACLE內(nèi)置包DBMS_UTILITY中的EXEC_DDL_STATEMENT過程,由它執(zhí)行DDL語句創(chuàng)建觸發(fā)器。 CREATE TABLE dept_summary( Deptno NUMBER(2), Sal_sum NUMBER(9, 2), Emp_count NUMBER); INSERT INTO dept_summary(deptno, s
38、al_sum, emp_count)SELECT deptno, SUM(sal), COUNT(*) FROM emp GROUP BY deptno;-創(chuàng)建一個PL/SQL過程disp_dept_summary-在觸發(fā)器中調(diào)用該過程顯示dept_summary標中的數(shù)據(jù)。CREATE OR REPLACE PROCEDURE disp_dept_summaryIS Rec dept_summary%ROWTYPE;CURSOR c1 IS SELECT * FROM dept_summary;BEGINOPEN c1;FETCH c1 INTO REC; DBMS_OUTPUT.PUT_L
39、INE(deptno sal_sum emp_count); DBMS_OUTPUT.PUT_LINE(-);WHILE c1%FOUND LOOP DBMS_OUTPUT.PUT_LINE(RPAD(rec.deptno, 6)| To_char(rec.sal_sum, $999,999.99)| LPAD(rec.emp_count, 13); FETCH c1 INTO rec;END LOOP;CLOSE c1;END;BEGIN DBMS_OUTPUT.PUT_LINE(插入前); Disp_dept_summary(); DBMS_UTILITY.EXEC_DDL_STATEME
40、NT( CREATE OR REPLACE TRIGGER trig1 AFTER INSERT OR DELETE OR UPDATE OF sal ON emp BEGIN DBMS_OUTPUT.PUT_LINE(正在執(zhí)行trig1 觸發(fā)器); DELETE FROM dept_summary; INSERT INTO dept_summary(deptno, sal_sum, emp_count) SELECT deptno, SUM(sal), COUNT(*) FROM emp GROUP BY deptno; END; );INSERT INTO dept(deptno, dna
41、me, loc) VALUES(90, demo_dept, none_loc);INSERT INTO emp(ename, deptno, empno, sal)VALUES(USER, 90, 9999, 3000); DBMS_OUTPUT.PUT_LINE(插入后); Disp_dept_summary();UPDATE emp SET sal=1000 WHERE empno=9999; DBMS_OUTPUT.PUT_LINE(修改后); Disp_dept_summary();DELETE FROM emp WHERE empno=9999;DELETE FROM dept W
42、HERE deptno=90; DBMS_OUTPUT.PUT_LINE(刪除后); Disp_dept_summary(); DBMS_UTILITY.EXEC_DDL_STATEMENT(DROP TRIGGER trig1);EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(SQLCODE|-|SQLERRM);END; 例2:創(chuàng)建DML語句行級觸發(fā)器。當對emp表執(zhí)行INSERT, UPDATE, DELETE 操作時,它自動更新dept_summary 表中的數(shù)據(jù)。由于在PL/SQL塊中不能直接調(diào)用DDL語句,所以,利用ORACLE內(nèi)置包
43、DBMS_UTILITY中的EXEC_DDL_STATEMENT過程,由它執(zhí)行DDL語句創(chuàng)建觸發(fā)器。 BEGIN DBMS_OUTPUT.PUT_LINE(插入前); Disp_dept_summary(); DBMS_UTILITY.EXEC_DDL_STATEMENT( CREATE OR REPLACE TRIGGER trig2_update AFTER UPDATE OF sal ON emp REFERENCING OLD AS old_emp NEW AS new_emp FOR EACH ROW WHEN (old_emp.sal != new_emp.sal) BEGIN D
44、BMS_OUTPUT.PUT_LINE(正在執(zhí)行trig2_update 觸發(fā)器); DBMS_OUTPUT.PUT_LINE(sal 舊值:| :old_emp.sal); DBMS_OUTPUT.PUT_LINE(sal 新值:| :new_emp.sal); UPDATE dept_summary SET sal_sum=sal_sum + :new_emp.sal - :old_emp.sal WHERE deptno = :new_emp.deptno; END; ); DBMS_UTILITY.EXEC_DDL_STATEMENT( CREATE OR REPLACE TRIGGER trig2_insert AFTER INSERT ON emp REFERENCING NEW AS new_emp FOR EACH ROW DECLARE I NUMBER; BEGIN DBMS_OUTPUT.
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年二年級班主任工作心得樣本(4篇)
- 2025年事故事件反思心得體會范例(2篇)
- 2025年為民服務站工作總結(五篇)
- 2025年人力資源個人工作總結及計劃(二篇)
- 2025年中考誓師大會學生觀后心得體會樣本(3篇)
- 光伏電站農(nóng)戶租賃合同范例
- 商場餐飲店租賃合同范例
- 農(nóng)村農(nóng)田占用合同范本
- 商場廢品紙箱合同范例
- 夫妻買車出租合同范例
- 小學六年級數(shù)學上冊《簡便計算》練習題(310題-附答案)
- 2024年河南省《輔警招聘考試必刷500題》考試題庫及答案【全優(yōu)】
- -情景交際-中考英語復習考點
- 安全隱患報告和舉報獎勵制度
- 地理標志培訓課件
- 2023行政主管年終工作報告五篇
- 2024年中國養(yǎng)老產(chǎn)業(yè)商學研究報告-銀發(fā)經(jīng)濟專題
- 公園衛(wèi)生保潔考核表
- 培訓如何上好一堂課
- 高教版2023年中職教科書《語文》(基礎模塊)下冊教案全冊
- 2024醫(yī)療銷售年度計劃
評論
0/150
提交評論