九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
oracle 觸發(fā)器的種類和觸發(fā)事件,DML觸發(fā)器,DDL事件觸發(fā)器,替代觸發(fā)器,查看觸發(fā)...
2009-04-14

oracle 觸發(fā)器的種類和觸發(fā)事件,DML觸發(fā)器,DDL事件觸發(fā)器,替代觸發(fā)器,查看觸發(fā)器,

關(guān)鍵字: oracle 觸發(fā)器 種類 觸發(fā) 事件 dml ddl 事件 替代 查看
觸發(fā)器的種類和觸發(fā)事件
觸發(fā)器必須由事件才能觸發(fā)。觸發(fā)器的觸發(fā)事件分可為3類,分別是DML事件、DDL事件和數(shù)據(jù)庫(kù)事件。
每類事件包含若干個(gè)事件,如下所示。數(shù)據(jù)庫(kù)的事件是具體的,在創(chuàng)建觸發(fā)器時(shí)要指明觸發(fā)的事件。
種  類 關(guān) 鍵 字 含    義
Sql代碼
 
  1. DML事件(3種)   INSERT  在表或視圖中插入數(shù)據(jù)時(shí)觸發(fā)   
  2.     UPDATE  修改表或視圖中的數(shù)據(jù)時(shí)觸發(fā)   
  3.     DELETE  在刪除表或視圖中的數(shù)據(jù)時(shí)觸發(fā)   
  4. DDL事件(3種)   CREATE  在創(chuàng)建新對(duì)象時(shí)觸發(fā)   
  5.     ALTER   修改數(shù)據(jù)庫(kù)或數(shù)據(jù)庫(kù)對(duì)象時(shí)觸發(fā)   
  6.     DROP    刪除對(duì)象時(shí)觸發(fā)   
  7. 數(shù)據(jù)庫(kù)事件(5種)   STARTUP 數(shù)據(jù)打開時(shí)觸發(fā)   
  8.     SHUTDOWN    在使用NORMAL或IMMEDIATE選項(xiàng)關(guān)閉數(shù)據(jù)庫(kù)時(shí)觸發(fā)   
  9.     LOGON   當(dāng)用戶連接到數(shù)據(jù)庫(kù)并建立會(huì)話時(shí)觸發(fā)   
  10.     LOGOFF  當(dāng)一個(gè)會(huì)話從數(shù)據(jù)庫(kù)中斷開時(shí)觸發(fā)   
  11.     SERVERERROR 發(fā)生服務(wù)器錯(cuò)誤時(shí)觸發(fā)  

觸發(fā)器的類型可劃分為4種:數(shù)據(jù)操縱語(yǔ)言(DML)觸發(fā)器、替代(INSTEAD OF)觸發(fā)器、數(shù)據(jù)定義語(yǔ)言(DDL)觸發(fā)器和數(shù)據(jù)庫(kù)事件觸發(fā)器。
各類觸發(fā)器的作用如下所示。
Sql代碼
 
  1. 種  類    簡(jiǎn)  稱    作    用   
  2. 數(shù)據(jù)操縱語(yǔ)言觸發(fā)器   DML觸發(fā)器  創(chuàng)建在表上,由DML事件引發(fā)的觸發(fā)器   
  3. 替代觸發(fā)器   INSTEAD OF觸發(fā)器   創(chuàng)建在視圖上,用來(lái)替換對(duì)視圖進(jìn)行的插入、刪除和修改操作   
  4. 數(shù)據(jù)定義語(yǔ)言觸發(fā)器   DDL觸發(fā)器  定義在模式上,觸發(fā)事件是數(shù)據(jù)庫(kù)對(duì)象的創(chuàng)建和修改   
  5. 數(shù)據(jù)庫(kù)事件觸發(fā)器    —   定義在整個(gè)數(shù)據(jù)庫(kù)或模式上,觸發(fā)事件是數(shù)據(jù)庫(kù)事件  

DML觸發(fā)器的要點(diǎn)
DML觸發(fā)器是定義在表上的觸發(fā)器,由DML事件引發(fā)。編寫DML觸發(fā)器的要素是:
* 確定觸發(fā)的表,即在其上定義觸發(fā)器的表。
* 確定觸發(fā)的事件,DML觸發(fā)器的觸發(fā)事件有INSERT、UPDATE和DELETE三種,說(shuō)明見(jiàn)下。
* 確定觸發(fā)時(shí)間。觸發(fā)的時(shí)間有BEFORE和AFTER兩種,分別表示觸發(fā)動(dòng)作發(fā)生在DML語(yǔ)句執(zhí)行之前和語(yǔ)句執(zhí)行之后。
* 確定觸發(fā)級(jí)別,有語(yǔ)句級(jí)觸發(fā)器和行級(jí)觸發(fā)器兩種。語(yǔ)句級(jí)觸發(fā)器表示SQL語(yǔ)句只觸發(fā)一次觸發(fā)器,行級(jí)觸發(fā)器表示SQL語(yǔ)句影響的每一行都要觸發(fā)一次。
由于在同一個(gè)表上可以定義多個(gè)DML觸發(fā)器,因此觸發(fā)器本身和引發(fā)觸發(fā)器的SQL語(yǔ)句在執(zhí)行的順序上有先后的關(guān)系。它們的順序是:
* 如果存在語(yǔ)句級(jí)BEFORE觸發(fā)器,則先執(zhí)行一次語(yǔ)句級(jí)BEFORE觸發(fā)器。
* 在SQL語(yǔ)句的執(zhí)行過(guò)程中,如果存在行級(jí)BEFORE觸發(fā)器,則SQL語(yǔ)句在對(duì)每一行操作之前,都要先執(zhí)行一次行級(jí)BEFORE觸發(fā)器,然后才對(duì)行進(jìn)行操作。如果存在行級(jí)AFTER觸發(fā)器,則SQL語(yǔ)句在對(duì)每一行操作之后,都要再執(zhí)行一次行級(jí)AFTER觸發(fā)器。
* 如果存在語(yǔ)句級(jí)AFTER觸發(fā)器,則在SQL語(yǔ)句執(zhí)行完畢后,要最后執(zhí)行一次語(yǔ)句級(jí)AFTER觸發(fā)器。
DML觸發(fā)器還有一些具體的問(wèn)題,說(shuō)明如下:
* 如果有多個(gè)觸發(fā)器被定義成為相同時(shí)間、相同事件觸發(fā),且最后定義的觸發(fā)器是有效的,則最后定義的觸發(fā)器被觸發(fā),其他觸發(fā)器不執(zhí)行。
* 一個(gè)觸發(fā)器可由多個(gè)不同的DML操作觸發(fā)。在觸發(fā)器中,可用INSERTING、DELETING、UPDATING謂詞來(lái)區(qū)別不同的DML操作。這些謂詞可以在IF分支條件語(yǔ)句中作為判斷條件來(lái)使用。
* 在行級(jí)觸發(fā)器中,用:new 和:old(稱為偽記錄)來(lái)訪問(wèn)數(shù)據(jù)變更前后的值。但要注意,INSERT語(yǔ)句插入一條新記錄,所以沒(méi)有:old記錄,而DELETE語(yǔ)句刪除掉一條已經(jīng)存在的記錄,所以沒(méi)有:new記錄。UPDATE語(yǔ)句既有:old記錄,也有:new記錄,分別代表修改前后的記錄。引用具體的某一列的值的方法是:
       
ld.字段名或:new.字段名
* 觸發(fā)器體內(nèi)禁止使用COMMIT、ROLLBACK、SAVEPOINT語(yǔ)句,也禁止直接或間接地調(diào)用含有上述語(yǔ)句的存儲(chǔ)過(guò)程。
定義一個(gè)觸發(fā)器時(shí)要考慮上述多種情況,并根據(jù)具體的需要來(lái)決定觸發(fā)器的種類。
DML觸發(fā)器的創(chuàng)建
創(chuàng)建DML觸發(fā)器需要CREATE TRIGGER系統(tǒng)權(quán)限。創(chuàng)建DML觸發(fā)器的語(yǔ)法如下:
CREATE [OR REPLACE] TRIGGER 觸發(fā)器名
{BEFORE|AFTER|INSTEAD OF} 觸發(fā)事件1 [OR 觸發(fā)事件2...]
ON 表名
WHEN 觸發(fā)條件
[FOR EACH ROW]
DECLARE
聲明部分
BEGIN
主體部分
END;
其中:
OR REPLACE:表示如果存在同名觸發(fā)器,則覆蓋原有同名觸發(fā)器。
BEFORE、AFTER和INSTEAD OF:說(shuō)明觸發(fā)器的類型。
WHEN 觸發(fā)條件:表示當(dāng)該條件滿足時(shí),觸發(fā)器才能執(zhí)行。
觸發(fā)事件:指INSERT、DELETE或UPDATE事件,事件可以并行出現(xiàn),中間用OR連接。
對(duì)于UPDATE事件,還可以用以下形式表示對(duì)某些列的修改會(huì)引起觸發(fā)器的動(dòng)作:
UPDATE OF 列名1,列名2...
ON 表名:表示為哪一個(gè)表創(chuàng)建觸發(fā)器。
FOR EACH ROW:表示觸發(fā)器為行級(jí)觸發(fā)器,省略則為語(yǔ)句級(jí)觸發(fā)器。
觸發(fā)器的創(chuàng)建者或具有DROP ANY TIRGGER系統(tǒng)權(quán)限的人才能刪除觸發(fā)器。刪除觸發(fā)器的語(yǔ)法如下:
DROP TIRGGER 觸發(fā)器名
可以通過(guò)命令設(shè)置觸發(fā)器的可用狀態(tài),使其暫時(shí)關(guān)閉或重新打開,即當(dāng)觸發(fā)器暫時(shí)不用時(shí),可以將其置成無(wú)效狀態(tài),在使用時(shí)重新打開。該命令語(yǔ)法如下:
ALTER TRIGGER 觸發(fā)器名 {DISABLE|ENABLE}
其中,DISABLE表示使觸發(fā)器失效,ENABLE表示使觸發(fā)器生效。
同存儲(chǔ)過(guò)程類似,觸發(fā)器可以用SHOW ERRORS 檢查編譯錯(cuò)誤。
行級(jí)觸發(fā)器的應(yīng)用
在行級(jí)觸發(fā)器中,SQL語(yǔ)句影響的每一行都會(huì)觸發(fā)一次觸發(fā)器,所以行級(jí)觸發(fā)器往往用在對(duì)表的每一行的操作進(jìn)行控制的場(chǎng)合。若在觸發(fā)器定義中出現(xiàn)FOR EACH ROW子句,則為語(yǔ)句級(jí)觸發(fā)器。
【訓(xùn)練1】  創(chuàng)建包含插入、刪除、修改多種觸發(fā)事件的觸發(fā)器DML_LOG,對(duì)EMP表的操作進(jìn)行記錄。用INSERTING、DELETING、UPDATING謂詞來(lái)區(qū)別不同的DML操作。
在創(chuàng)建觸發(fā)器之前,需要先創(chuàng)建事件記錄表LOGS,該表用來(lái)對(duì)操作進(jìn)行記錄。該表的字段含義解釋如下:
LOG_ID:操作記錄的編號(hào),數(shù)值型,它是該表的主鍵,由序列自動(dòng)生成。
LOG_TABLE:進(jìn)行操作的表名,字符型,非空,該表設(shè)計(jì)成可以由多個(gè)觸發(fā)器共享使用。比如我們可以為dept表創(chuàng)建類似的觸發(fā)器,同樣將操作記錄到該表。
LOG_DML:操作的動(dòng)作,即INSERT、DELETE或UPDATE三種之一。
LOG_KEY_ID:操作時(shí)表的主鍵值,數(shù)值型。之所以記錄表的主鍵,是因?yàn)橹麈I是表的記錄的惟一標(biāo)識(shí),可以識(shí)別是對(duì)哪一條記錄進(jìn)行了操作。對(duì)于emp表,主鍵是empno。
LOG_DATE:操作的日期,日期型,取當(dāng)前的系統(tǒng)時(shí)間。
LOG_USER:操作者,字符型,取當(dāng)時(shí)的操作者賬戶名。比如登錄SCOTT賬戶進(jìn)行操作,在該字段中,記錄賬戶名為SCOTT。
步驟1:在SQL*Plus中登錄STUDENT賬戶,創(chuàng)建如下的記錄表LOGS:
Sql代碼
 
  1. CREATE TABLE logs(   
  2.         LOG_ID NUMBER(10) PRIMARY KEY,   
  3.         LOG_TABLE VARCHAR2(10) NOT NULL,   
  4.         LOG_DML VARCHAR2(10),   
  5.         LOG_KEY_ID NUMBER(10),   
  6.         LOG_DATE DATE,   
  7.         LOG_USER VARCHAR2(15)   
  8.         );  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 表已創(chuàng)建。  

步驟2:創(chuàng)建一個(gè)LOGS表的主鍵序列LOGS_ID_SEQ:
Sql代碼
 
  1. CREATE SEQUENCE logs_id_squ INCREMENT BY 1    
  2.         START WITH 1 MAXVALUE 9999999 NOCYCLE NOCACHE;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 序列已創(chuàng)建。  

步驟3:創(chuàng)建和編譯以下觸發(fā)器:
Sql代碼
 
  1. CREATE OR REPLACE TRIGGER DML_LOG   
  2.         BEFORE --觸發(fā)時(shí)間為操作前   
  3.         DELETE OR INSERT OR UPDATE -- 由三種事件觸發(fā)   
  4.         ON emp   
  5.         FOR EACH ROW -- 行級(jí)觸發(fā)器   
  6.         BEGIN  
  7. IF INSERTING THEN    
  8.         INSERT INTO logs        VALUES(logs_id_squ.NEXTVAL,'EMP','INSERT',:new.empno,SYSDATE,USER);   
  9.          ELSIF DELETING THEN  
  10.          INSERT INTO logs       VALUES(logs_id_squ.NEXTVAL,'EMP','DELETE',:old.empno,SYSDATE,USER);   
  11.          ELSE  
  12.              INSERT INTO logs       VALUES(logs_id_squ.NEXTVAL,'EMP','UPDATE',:new.empno,SYSDATE,USER);   
  13.         END IF;   
  14.         END;  

執(zhí)行結(jié)果:
觸發(fā)器已創(chuàng)建
步驟4:在EMP表中插入記錄:
Sql代碼
 
  1. INSERT INTO emp(empno,ename,job,sal) VALUES(8001,'MARY','CLERK',1000);   
  2.         COMMIT;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 已創(chuàng)建1行。   
  2.         提交完成。  

步驟5:檢查L(zhǎng)OGS表中記錄的信息:
Sql代碼
 
  1. SELECT * FROM LOGS;  

執(zhí)行結(jié)果為:
   
Sql代碼
 
  1. LOG_ID LOG_TABLE  LOG_DML    LOG_KEY_ID LOG_DATE   LOG_USER   
  2.         ----------------- ----------------- ------------------ ----------------------- ---------------- -------------------   
  3.           1 EMP         INSERT            8001    29-3月 -04     STUDENT   
  4.         已選擇 1 行。  

說(shuō)明:本例中在emp表上創(chuàng)建了一個(gè)由INSERT或DELETE或UPDATE事件觸發(fā)的行級(jí)觸發(fā)器,觸發(fā)器的名稱是LOG_EMP。對(duì)于不同的操作,記錄的內(nèi)容不同。本例中只插入了一條記錄,如果用一條不帶WHERE條件的UPDATE語(yǔ)句來(lái)修改所有雇員的工資,則將逐行觸發(fā)觸發(fā)器。
INSERT、DELETE和UPDATE都能引發(fā)觸發(fā)器動(dòng)作,在分支語(yǔ)句中使用INSERTING、DELETING和UPDATING來(lái)區(qū)別是由哪種操作引發(fā)的觸發(fā)器動(dòng)作。
在本例的插入動(dòng)作中,LOG_ID字段由序列LOG_ID_SQU自動(dòng)填充為1;LOGS表LOG_KEY_ID字段記錄的是新插入記錄的主鍵8001;LOD_DML字段記錄的是插入動(dòng)作INSERT;LOG_TABLE字段記錄當(dāng)前表名EMP;LOG_DATE字段記錄插入的時(shí)間04年3月1日;LOG_USER字段記錄插入者STUDENT。
【練習(xí)1】修改、刪除剛剛插入的雇員記錄,提交后檢查L(zhǎng)OGS表的結(jié)果。
【練習(xí)2】為DEPT表創(chuàng)建同樣的觸發(fā)器,使用LOGS表進(jìn)行記錄,并檢驗(yàn)結(jié)果。
【訓(xùn)練2】  創(chuàng)建一個(gè)行級(jí)觸發(fā)器LOG_SAL,記錄對(duì)職務(wù)為CLERK的雇員工資的修改,且當(dāng)修改幅度超過(guò)200時(shí)才進(jìn)行記錄。用WHEN條件限定觸發(fā)器。
在創(chuàng)建觸發(fā)器之前,需要先創(chuàng)建事件記錄表LOGERR,該表用來(lái)對(duì)操作進(jìn)行記錄。該表的字段含義解釋如下:
NUM:數(shù)值型,用于記錄序號(hào)。
MESSAGE:字符型,用于記錄錯(cuò)誤信息。
步驟1:在SQL*Plus中登錄STUDENT賬戶,創(chuàng)建如下的記錄表LOGERR:
Sql代碼
 
  1. CREATE TABLE logerr(   
  2.         NUM NUMBER(10) NOT NULL,   
  3.         MESSAGE VARCHAR2(50) NOT NULL  
  4.         );  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 表已創(chuàng)建。  

步驟2:創(chuàng)建和編譯以下觸發(fā)器:
Sql代碼
 
  1. CREATE OR REPLACE TRIGGER log_sal   
  2.         BEFORE   
  3.         UPDATE OF sal   
  4.         ON emp   
  5.         FOR EACH ROW   
  6.         WHEN (new.job='CLERK' AND (ABS(new.sal-old.sal)>200))    
  7. DECLARE    
  8.         v_no NUMBER;   
  9.         BEGIN  
  10.         SELECT COUNT(*) INTO v_no FROM logerr;    
  11.         INSERT INTO logerr VALUES(v_no+1,'雇員'||:new.ename||'的原工資:'||:old.sal||'新工資:'||:new.sal);   
  12.         END;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 觸發(fā)器已創(chuàng)建。  

步驟3:在EMP表中更新記錄:
Sql代碼
 
  1. UPDATE emp SET sal=sal+550 WHERE empno=7788;   
  2.         UPDATE emp SET sal=sal+500 WHERE empno=7369;   
  3.         UPDATE emp SET sal=sal+50 WHERE empno=7876;   
  4.         COMMIT;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 已更新 1 行。   
  2.         已更新 1 行。   
  3.         已更新 1 行。   
  4.         提交完成。  

步驟4:檢查L(zhǎng)OGSAL表中記錄的信息:
Sql代碼
 
  1. SELECT * FROM logerr;  

執(zhí)行結(jié)果為:
      
Sql代碼
 
  1. NUM MESSAGE   
  2. ------------------ --------------------------------------------------------   
  3.              1 雇員SMITH的原工資:800新工資:1300   
  4.         已選擇 1 行。  

  說(shuō)明:本例中,在emp表的sal列上創(chuàng)建了一個(gè)由UPDATE事件觸發(fā)的行級(jí)觸發(fā)器,觸發(fā)器的名稱是LOG_SAL。該觸發(fā)器由WHEN語(yǔ)句限定,只有當(dāng)被修改工資的雇員職務(wù)為CLERK,且修改的工資超過(guò)200時(shí)才進(jìn)行觸發(fā),否則不進(jìn)行觸發(fā)。
所以在驗(yàn)證過(guò)程中,雖然修改了3條記錄,但通過(guò)查詢語(yǔ)句發(fā)現(xiàn):第一條修改語(yǔ)句修改編號(hào)為7788的SCOTT記錄,因?yàn)镾COTT的職務(wù)是ANALYST,不符合WHEN條件,沒(méi)有引起觸發(fā)器動(dòng)作;第二條修改語(yǔ)句修改編號(hào)為7369的SMITH的記錄,職務(wù)為CLERK,因?yàn)樵黾拥墓べY(500)超過(guò)了200,所以引起觸發(fā)器動(dòng)作,并在LOGERR表中進(jìn)行了記錄;第三條修改語(yǔ)句修改編號(hào)為7876的雇員ADAMS的記錄,雖然ADAMS的職務(wù)為CLERK,但修改的工資(50)沒(méi)有超過(guò)200,所以沒(méi)有引起觸發(fā)器動(dòng)作。
注意:在WHEN條件中引用new和old不需要在前面加“: ”。
在以上實(shí)例中,記錄了對(duì)工資的修改超出范圍的信息,但沒(méi)有限制對(duì)工資的修改。那么當(dāng)對(duì)雇員工資的修改幅度不滿足條件時(shí),能否直接限制對(duì)工資的修改呢?答案是肯定的。
【訓(xùn)練3】  創(chuàng)建觸發(fā)器CHECK_SAL,當(dāng)對(duì)職務(wù)為CLERK的雇員的工資修改超出500至2000的范圍時(shí),進(jìn)行限制。
步驟1:創(chuàng)建和編譯以下觸發(fā)器:
Sql代碼
 
  1. CREATE OR REPLACE TRIGGER CHECK_SAL   
  2.         BEFORE   
  3.         UPDATE  
  4.         ON emp   
  5.         FOR EACH ROW   
  6.         BEGIN  
  7. IF :new.job='CLERK' AND (:new.sal<500 OR :new.sal>2000) THEN  
  8.          RAISE_APPLICATION_ERROR(-20001, '工資修改超出范圍,操作取消!');   
  9.         END IF;   
  10.         END;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 觸發(fā)器已創(chuàng)建。  

步驟2:在EMP表中插入記錄:
Sql代碼
 
  1. UPDATE emp SET sal=800 WHERE empno=7876;   
  2.         UPDATE emp SET sal=450 WHERE empno=7876;   
  3.         COMMIT;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. UPDATE emp SET sal=450 WHERE empno=7876   
  2.                 *   
  3.         ERROR 位于第 1 行:   
  4.         ORA-20001: 工資修改超出范圍,操作取消!   
  5.         ORA-06512: 在"STUDENT.CHECK_SAL", line 3   
  6.         ORA-04088: 觸發(fā)器 'STUDENT.CHECK_SAL' 執(zhí)行過(guò)程中出錯(cuò)提交完成。  

步驟3:檢查工資的修改結(jié)果:
Sql代碼
 
  1. SELECT empno,ename,job,sal FROM emp WHERE empno=7876;  

執(zhí)行結(jié)果為:
   
Sql代碼
 
  1. EMPNO ENAME      JOB              SAL   
  2. ----------------- ------------- ------------- ------------------------   
  3.         7876  ADAMS      CLERK            800  

說(shuō)明:在觸發(fā)器中,當(dāng)IF語(yǔ)句的條件滿足時(shí),即對(duì)職務(wù)為CLERK的雇員工資的修改超出指定范圍時(shí),用RAISE_APPLICATION_ERROR語(yǔ)句來(lái)定義一個(gè)臨時(shí)定義的異常,并立即引發(fā)異常。由于觸發(fā)器是BEFORE類型,因此觸發(fā)器先執(zhí)行,觸發(fā)器因異常而終止,SQL語(yǔ)句的執(zhí)行就會(huì)取消。
通過(guò)步驟2的執(zhí)行信息可以看到,第一條語(yǔ)句修改編號(hào)為7876的雇員ADAMS的工資為800,成功執(zhí)行。第二條語(yǔ)句修改雇員ADAMS的工資為450,發(fā)生異常,執(zhí)行失敗。這樣就阻止了不符合條件的工資的修改。通過(guò)步驟3的查詢可以看到,雇員ADAMS最后的工資是800,即發(fā)生異常之前的修改結(jié)果。
【練習(xí)3】限定對(duì)emp表的修改,只能修改部門10的雇員工資。
   【訓(xùn)練4】  創(chuàng)建一個(gè)行級(jí)觸發(fā)器CASCADE_UPDATE,當(dāng)修改部門編號(hào)時(shí),EMP表的相關(guān)行的部門編號(hào)也自動(dòng)修改。該觸發(fā)器稱為級(jí)聯(lián)修改觸發(fā)器。
步驟1:創(chuàng)建和編譯以下觸發(fā)器:
Sql代碼
 
  1. CREATE TRIGGER CASCADE_UPDATE   
  2. AFTER    
  3. UPDATE OF deptno   
  4. ON DEPT   
  5. FOR EACH ROW   
  6. BEGIN  
  7. UPDATEEMP SET EMP.DEPTNO=:NEW.DEPTNO   
  8.          WHERE EMP.DEPTNO=:OLD.DEPTNO;   
  9.         END;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 觸發(fā)器已創(chuàng)建  

步驟2:驗(yàn)證觸發(fā)器:
Sql代碼
 
  1. UPDATE dept SET deptno=11 WHERE deptno=10;   
  2.         COMMIT;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 已更新 1 行。   

執(zhí)行查詢:
Sql代碼
 
  1. SELECT empno,ename,deptno FROM emp;  

執(zhí)行結(jié)果:
  
Sql代碼
 
  1.  EMPNO ENAME          DEPTNO   
  2.     ----------------- ----------- -------------------------   
  3.          7369 SMITH                 20   
  4.          7499 ALLEN                 30   
  5.         7521 WARD                   30   
  6.         7566 JONES                  20   
  7. 7654 MARTIN                 30   
  8.         7698 BLAKE                  30   
  9.          7782 CLARK                 11   
  10.          7839 KING                  11   
  11.         7844 TURNER                 30   
  12.         7876 ADAMS                  20   
  13.         7900 JAMES                  30   
  14.          7902 FORD                  20   
  15.          7934 MILLER                11   
  16.         7788 SCOTT                  20  

說(shuō)明:通過(guò)檢查雇員的部門編號(hào),發(fā)現(xiàn)原來(lái)編號(hào)為10的部門編號(hào)被修改為11。
本例中的UPDATE OF deptno表示只有在修改表的DEPTNO列時(shí)才引發(fā)觸發(fā)器,對(duì)其他列的修改不會(huì)引起觸發(fā)器的動(dòng)作。在觸發(fā)器中,對(duì)雇員表的部門編號(hào)與修改之前的部門編號(hào)一樣的雇員,修改其部門編號(hào)為新的部門編號(hào)。注意,在語(yǔ)句中同時(shí)用到了:new和:old來(lái)引用修改部門編號(hào)前后的部門編號(hào)。
【練習(xí)4】建立級(jí)聯(lián)刪除觸發(fā)器CASCADE_DELETE,當(dāng)刪除部門時(shí),級(jí)聯(lián)刪除EMP表的雇員記錄。
利用觸發(fā)器還可以修改數(shù)據(jù)。
【訓(xùn)練5】  將插入的雇員的名字變成以大寫字母開頭。
步驟1:創(chuàng)建和編譯以下觸發(fā)器:
Sql代碼
 
  1. CREATE OR REPLACE TRIGGER INITCAP   
  2. BEFORE INSERT    
  3. ON EMP   
  4. FOR EACH ROW   
  5. BEGIN  
  6.  :new.ename:=INITCAP(:new.ename);   
  7. END;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 觸發(fā)器已創(chuàng)建。  

步驟2:驗(yàn)證運(yùn)行結(jié)果:
Sql代碼
 
  1. INSERT INTO emp(empno,ename,job,sal) VALUES(1000,'BILL','CLERK',1500);  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 已創(chuàng)建 1 行。  

執(zhí)行查詢:
Sql代碼
 
  1. SELECT ename,job,sal FROM emp WHERE empno=1000;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. ENAME      JOB              SAL   
  2.         ------------- ------------- ------------------------   
  3.         Bill          CLERK           1500  

說(shuō)明:在本例中,通過(guò)直接為:new.ename進(jìn)行賦值,修改了插入的值,但是這種用法只能在BEFORE型觸發(fā)器中使用。驗(yàn)證結(jié)果為,在插入語(yǔ)句中雇員名稱為大寫的BILL,查詢結(jié)果中雇員名稱已經(jīng)轉(zhuǎn)換成以大寫開頭的Bill。
【練習(xí)5】限定一次對(duì)雇員的工資修改不超過(guò)原工資的10%。
語(yǔ)句級(jí)觸發(fā)器的應(yīng)用
同行級(jí)觸發(fā)器不同,語(yǔ)句級(jí)觸發(fā)器的每個(gè)操作語(yǔ)句不管操作的行數(shù)是多少,只觸發(fā)一次觸發(fā)器,所以語(yǔ)句級(jí)觸發(fā)器適合于對(duì)整個(gè)表的操作權(quán)限等進(jìn)行控制。在觸發(fā)器定義中若省略FOR EACH ROW子句,則為語(yǔ)句級(jí)觸發(fā)器。
【訓(xùn)練1】  創(chuàng)建一個(gè)語(yǔ)句級(jí)觸發(fā)器CHECK_TIME,限定對(duì)表EMP的修改時(shí)間為周一至周五的早8點(diǎn)至晚5點(diǎn)。
步驟1:創(chuàng)建和編譯以下觸發(fā)器:
Sql代碼
 
  1. CREATE OR REPLACE TRIGGER CHECK_TIME   
  2. BEFORE   
  3. UPDATE OR INSERT OR DELETE    
  4. ON EMP   
  5. BEGIN  
  6.  IF (TO_CHAR(SYSDATE,'DY'IN ('SAT','SUN'))    
  7.  OR TO_CHAR(SYSDATE,'HH24')< '08'    
  8.  OR TO_CHAR(SYSDATE,'HH24')>='17' THEN  
  9. RAISE_APPLICATION_ERROR(-20500,'非法時(shí)間修改表錯(cuò)誤!');   
  10.          END IF;    
  11.         END;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 觸發(fā)器已創(chuàng)建。  

步驟2:當(dāng)前時(shí)間為18點(diǎn)50分,在EMP表中插入記錄:
Sql代碼
 
  1. UPDATE EMP SET SAL=3000 WHERE EMPNO=7369;  

顯示結(jié)果為:
Sql代碼
 
  1. UPDATE EMP SET SAL=3000 WHERE EMPNO=7369   
  2.                                        *   
  3. ERROR 位于第 1 行:   
  4.         ORA-20500: 非法時(shí)間修改表錯(cuò)誤!   
  5.         ORA-06512: 在"STUDENT.CHECK_TIME", line 5   
  6.         ORA-04088: 觸發(fā)器 'STUDENT.CHECK_TIME' 執(zhí)行過(guò)程中出錯(cuò)  

  說(shuō)明:通過(guò)引發(fā)異常限制對(duì)數(shù)據(jù)庫(kù)進(jìn)行的插入、刪除和修改操作的時(shí)間。SYSDATE用來(lái)獲取系統(tǒng)當(dāng)前時(shí)間,并按不同的格式字符串進(jìn)行轉(zhuǎn)換。“DY”表示獲取英文表示的星期簡(jiǎn)寫,“HH24”表示獲取24小時(shí)制時(shí)間的小時(shí)。
當(dāng)在18點(diǎn)50分修改表中的數(shù)據(jù)時(shí),由于時(shí)間在8點(diǎn)至17點(diǎn)(晚5點(diǎn))之外,所以產(chǎn)生“非法時(shí)間修改表錯(cuò)誤”的用戶自定義錯(cuò)誤,修改操作終止。
【練習(xí)1】設(shè)計(jì)一個(gè)語(yǔ)句級(jí)觸發(fā)器,限定只能對(duì)數(shù)據(jù)庫(kù)進(jìn)行修改操作,不能對(duì)數(shù)據(jù)庫(kù)進(jìn)行插入和刪除操作。在需要進(jìn)行插入和刪除時(shí),將觸發(fā)器設(shè)置為無(wú)效狀態(tài),完成后重新設(shè)置為生效狀態(tài)。
數(shù)據(jù)庫(kù)事件觸發(fā)器
數(shù)據(jù)庫(kù)事件觸發(fā)器有數(shù)據(jù)庫(kù)級(jí)和模式級(jí)兩種。前者定義在整個(gè)數(shù)據(jù)庫(kù)上,觸發(fā)事件是數(shù)據(jù)庫(kù)事件,如數(shù)據(jù)庫(kù)的啟動(dòng)、關(guān)閉,對(duì)數(shù)據(jù)庫(kù)的登錄或退出。后者定義在模式上,觸發(fā)事件包括模式用戶的登錄或退出,或?qū)?shù)據(jù)庫(kù)對(duì)象的創(chuàng)建和修改(DDL事件)。
數(shù)據(jù)庫(kù)事件觸發(fā)器的觸發(fā)事件的種類和級(jí)別如表9-3所示。
Sql代碼
 
  1. 種  類    關(guān) 鍵 字   說(shuō)    明   
  2. 模式級(jí) CREATE  在創(chuàng)建新對(duì)象時(shí)觸發(fā)   
  3.     ALTER   修改數(shù)據(jù)庫(kù)或數(shù)據(jù)庫(kù)對(duì)象時(shí)觸發(fā)   
  4.     DROP    刪除對(duì)象時(shí)觸發(fā)   
  5. 數(shù)據(jù)庫(kù)級(jí)    STARTUP 數(shù)據(jù)庫(kù)打開時(shí)觸發(fā)   
  6.     SHUTDOWN    在使用NORMAL或IMMEDIATE選項(xiàng)關(guān)閉數(shù)據(jù)庫(kù)時(shí)觸發(fā)   
  7.     SERVERERROR     發(fā)生服務(wù)器錯(cuò)誤時(shí)觸發(fā)   
  8. 數(shù)據(jù)庫(kù)級(jí)與模式級(jí)    LOGON   當(dāng)用戶連接到數(shù)據(jù)庫(kù),建立會(huì)話時(shí)觸發(fā)   
  9.     LOGOFF  當(dāng)會(huì)話從數(shù)據(jù)庫(kù)中斷開時(shí)觸發(fā)  

定義數(shù)據(jù)庫(kù)事件和模式事件觸發(fā)器
創(chuàng)建數(shù)據(jù)庫(kù)級(jí)觸發(fā)器需要ADMINISTER DATABASE TRIGGER系統(tǒng)權(quán)限,一般只有系統(tǒng)管理員擁有該權(quán)限。
對(duì)于模式級(jí)觸發(fā)器,為自己的模式創(chuàng)建觸發(fā)器需要CREATE TRIGGER權(quán)限,如果是為其他模式創(chuàng)建觸發(fā)器,需要CREATE ANY TRIGGER權(quán)限。
數(shù)據(jù)庫(kù)事件和模式事件觸發(fā)器的創(chuàng)建語(yǔ)法與DML觸發(fā)器的創(chuàng)建語(yǔ)法類似。數(shù)據(jù)庫(kù)事件或模式事件觸發(fā)器的創(chuàng)建語(yǔ)法如下:
CREATE [OR REPLACE] TRIGGER 觸發(fā)器名
{BEFORE|AFTER }
{DDL事件1 [DDL事件2...]| 數(shù)據(jù)庫(kù)事件1 [數(shù)據(jù)庫(kù)事件2...]}
ON {DATABASE| [模式名.]SCHEMA }
[WHEN (條件)]
DECLARE
聲明部分
BEGIN
主體部分
END;
其中:DATABASE表示創(chuàng)建數(shù)據(jù)庫(kù)級(jí)觸發(fā)器,數(shù)據(jù)庫(kù)級(jí)要給出數(shù)據(jù)庫(kù)事件;SCHEMA表示創(chuàng)建模式級(jí)觸發(fā)器,模式級(jí)要給出模式事件或DDL事件。
在數(shù)據(jù)庫(kù)事件觸發(fā)器中,可以使用如表9-4所示的一些事件屬性。不同類型的觸發(fā)器可以使用的事件屬性有所不同。
Sql代碼
 
  1. 屬  性    適用觸發(fā)器類型 說(shuō)    明   
  2. Sys.sysevent    所有類型    返回觸發(fā)器觸發(fā)事件字符串   
  3. Sys.instance_num    所有類型    返回Oracle實(shí)例號(hào)   
  4. Sys.database_name   所有類型    返回?cái)?shù)據(jù)庫(kù)名字   
  5. Sys.server_error(stack_position)    SERVERERROR 從錯(cuò)誤堆棧指定位置返回錯(cuò)誤號(hào),參數(shù)為1表示最近的錯(cuò)誤   
  6. Is_servererror(error_number)    SERVERERROR 判斷堆棧中是否有參數(shù)指定的錯(cuò)誤號(hào)   
  7. Sys.login_user  所有類型    返回導(dǎo)致觸發(fā)器觸發(fā)的用戶名   
  8. Sys.dictionary_obj_type CREATE、ALTER、DROP   返回DDL觸發(fā)器觸發(fā)時(shí)涉及的對(duì)象類型   
  9. Sys. dictionary_obj_name    CREATEALTER、DROP   返回DDL觸發(fā)器觸發(fā)時(shí)涉及的對(duì)象名稱   
  10. Sys.des_encrypted_password  CREATE、ALTERDROP   創(chuàng)建或修改用戶時(shí),返回加密后的用戶密碼  

數(shù)據(jù)庫(kù)事件觸發(fā)器
下面是一個(gè)綜合的數(shù)據(jù)庫(kù)事件觸發(fā)器練習(xí)。先為STUDENT賬戶授予創(chuàng)建數(shù)據(jù)庫(kù)事件觸發(fā)器的權(quán)限,ADMINISTER DATABASE TRIGGER,然后創(chuàng)建有關(guān)的表和觸發(fā)器,最后予以驗(yàn)證。
  【訓(xùn)練1】  創(chuàng)建觸發(fā)器,對(duì)本次數(shù)據(jù)庫(kù)啟動(dòng)以來(lái)的用戶登錄時(shí)間進(jìn)行記錄,每次數(shù)據(jù)庫(kù)啟動(dòng)后,先清空該表。
步驟1:創(chuàng)建登錄事件記錄表:
Sql代碼
 
  1. CREATE TABLE userlog (   
  2. USERNAME VARCHAR2(20),   
  3. LOGON_TIME DATE);  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 表已創(chuàng)建。  

步驟2:創(chuàng)建數(shù)據(jù)庫(kù)STARTUP事件觸發(fā)器:
Sql代碼
 
  1. CREATE OR REPLACE TRIGGER INIT_LOGON   
  2. AFTER  
  3. STARTUP    
  4. ON DATABASE  
  5. BEGIN  
  6.  DELETE FROM userlog;   
  7. END;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 觸發(fā)器已創(chuàng)建。  

步驟3:創(chuàng)建數(shù)據(jù)庫(kù)LOGON事件觸發(fā)器:
Sql代碼
 
  1. CREATE OR REPLACE TRIGGER DATABASE_LOGON   
  2. AFTER  
  3. LOGON    
  4. ON DATABASE  
  5. BEGIN  
  6.  INSERT INTO userlog    
  7.  VALUES(sys.login_user,sysdate);   
  8. END;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 觸發(fā)器已創(chuàng)建。  

步驟4:驗(yàn)證DATABASE_LOGON觸發(fā)器:
Sql代碼
 
  1. CONNECT SCOTT/TIGER@MYDB;   
  2.         CONNECT STUDENT/STUDENT@MYDB;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 已連接。   
  2. 已連接。  

執(zhí)行查詢:
Sql代碼
 
  1. SELECT username,TO_CHAR(logon_time,'YYYY/MM/DD HH24:MI:SS'FROM userlog;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. USERNAME             TO_CHAR(LOGON_TIME,   
  2. ----------------------------- -----------------------------------------   
  3. SCOTT                   2004/03/29 22:42:20   
  4.         STUDENT                 2004/03/29 22:42:20  

步驟5:驗(yàn)證INIT_LOGON觸發(fā)器。
重新啟動(dòng)數(shù)據(jù)庫(kù),登錄STUDENT賬戶:
Sql代碼
 
  1. SELECT username,TO_CHAR(logon_time,'YYYY/MM/DD HH24:MI:SS'FROM userlog;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. USERNAME             TO_CHAR(LOGON_TIME,   
  2. -------------------------------- ---------------------------------------   
  3.         STUDENT              2004/03/29 22:43:59   
  4.         已選擇 1 行  

說(shuō)明:本例中共創(chuàng)建了兩個(gè)數(shù)據(jù)庫(kù)級(jí)事件觸發(fā)器。DATABASE_LOGON在用戶登錄時(shí)觸發(fā),向表userlog中增加一條記錄,記錄登錄用戶名和登錄時(shí)間。INIT_LOGON在數(shù)據(jù)庫(kù)啟動(dòng)時(shí)觸發(fā),清除userlog表中記錄的數(shù)據(jù)。所以當(dāng)數(shù)據(jù)庫(kù)重新啟動(dòng)后,重新登錄STUDENT賬戶,此時(shí)userlog表中只有一條記錄。
【訓(xùn)練2】  創(chuàng)建STUDENT_LOGON模式級(jí)觸發(fā)器,專門記錄STUDENT賬戶的登錄時(shí)間:
Sql代碼
 
  1. CREATE OR REPLACE TRIGGER STUDENT_LOGON    
  2. AFTER  
  3. LOGON ON STUDENT.SCHEMA    
  4. BEGIN     
  5.  INSERT INTO userlog   
  6.  VALUES(sys.login_user,sysdate);   
  7. END;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 觸發(fā)器已創(chuàng)建。  

說(shuō)明:為當(dāng)前模式創(chuàng)建觸發(fā)器,可以省略SCHEMA前面的模式名。
【練習(xí)1】修改DATABASE_LOGON觸發(fā)器和userlog表,增加對(duì)退出時(shí)間的記錄。
DDL事件觸發(fā)器
【訓(xùn)練1】  通過(guò)觸發(fā)器阻止對(duì)emp表的刪除。
步驟1:創(chuàng)建DDL觸發(fā)器:
Sql代碼
 
  1. CREATE OR REPLACE TRIGGER NODROP_EMP   
  2.          BEFORE   
  3.         DROP ON SCHEMA    
  4.         BEGIN  
  5.         IF Sys.Dictionary_obj_name='EMP' THEN  
  6. RAISE_APPLICATION_ERROR(-20005,'錯(cuò)誤信息:不能刪除emp表!');   
  7.          END IF;    
  8.         END;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 觸發(fā)器已創(chuàng)建。  

步驟2:通過(guò)刪除emp表驗(yàn)證觸發(fā)器:
Sql代碼
 
  1. DROP TABLE emp;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. DROP TABLE emp   
  2.         *   
  3. ERROR 位于第 1 行:   
  4.         ORA-00604: 遞歸 SQL 層 1 出現(xiàn)錯(cuò)誤   
  5.         ORA-20005: 錯(cuò)誤信息:不能刪除emp表!   
  6.         ORA-06512: 在line 3  

     說(shuō)明:該觸發(fā)器阻止在當(dāng)前模式下對(duì)emp表的刪除,但不阻止刪除其他對(duì)象。Sys.Dictionary_obj_name屬性返回要?jiǎng)h除的對(duì)象名稱。
替代觸發(fā)器
【訓(xùn)練1】  在emp表的視圖上,通過(guò)觸發(fā)器修改emp表。
步驟1:創(chuàng)建視圖emp_name:
Sql代碼
 
  1. CREATE VIEW emp_name AS SELECT ename FROM emp;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 視圖已建立。  

步驟1:創(chuàng)建替代觸發(fā)器:
Sql代碼
 
  1. CREATE OR REPLACE TRIGGER change_name   
  2.         INSTEAD OF INSERT ON emp_name   
  3.         DECLARE  
  4. V_EMPNO NUMBER(4);   
  5.         BEGIN  
  6.         SELECT MAX(EMPNO)+1 INTO V_EMPNO FROM EMP;   
  7.         INSERT INTO emp(empno,ename)    
  8.         VALUES(V_EMPNO,:new.ename);   
  9.         END;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 觸發(fā)器已創(chuàng)建。  

步驟2:向emp_name視圖插入記錄:
Sql代碼
 
  1. INSERT INTO emp_name VALUES('BROWN');   
  2.         COMMIT;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 已創(chuàng)建 1 行。   
  2.         提交完成。  

  說(shuō)明:向視圖直接插入雇員名將會(huì)發(fā)生錯(cuò)誤,因?yàn)閑mp表的雇員編號(hào)列不允許為空。通過(guò)創(chuàng)建替代觸發(fā)器,將向視圖插入雇員名稱轉(zhuǎn)換為向emp表插入雇員編號(hào)和雇員名稱,雇員編號(hào)取當(dāng)前的最大雇員編號(hào)加1。試檢查emp表的雇員列表。
【訓(xùn)練2】  在emp表的視圖emp_name上,通過(guò)觸發(fā)器阻止對(duì)emp表的刪除。
步驟1:阻止通過(guò)視圖刪除雇員,并顯示用戶自定義錯(cuò)誤信息:
Sql代碼
 
  1. CREATE OR REPLACE TRIGGER delete_from_ename   
  2.         INSTEAD OF DELETE ON emp_name   
  3.         BEGIN  
  4.          RAISE_APPLICATION_ERROR(-20006,'錯(cuò)誤信息:不能在視圖中刪除emp表的雇員!');   
  5.         END;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 觸發(fā)器已創(chuàng)建。  

步驟2:通過(guò)對(duì)視圖進(jìn)行刪除來(lái)驗(yàn)證觸發(fā)器:
Sql代碼
 
  1. DELETE FROM emp_name;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. DELETE FROM emp_name   
  2.                 *   
  3.         ERROR 位于第 1 行:   
  4.         ORA-20006: 錯(cuò)誤信息:不能在視圖中刪除emp表的雇員!   
  5.         ORA-06512:    
  6.         在"STUDENT.DELETE_FROM_ENAME", line 2   
  7.         ORA-04088: 觸發(fā)器 'STUDENT.DELETE_FROM_ENAME' 執(zhí)行過(guò)程中出錯(cuò)  

說(shuō)明:可以通過(guò)視圖emp_name對(duì)雇員進(jìn)行刪除,比如執(zhí)行DELETE FROM emp_name語(yǔ)句將刪除雇員表的全部雇員。但是由于在emp_name視圖中只能看到一部分雇員信息,所以刪除可能會(huì)產(chǎn)生誤操作。通過(guò)定義一個(gè)替代觸發(fā)器,可阻止通過(guò)emp_name視圖對(duì)emp表雇員進(jìn)行刪除,但不阻止直接對(duì)emp表進(jìn)行刪除。
查看觸發(fā)器
【訓(xùn)練1】  顯示觸發(fā)器CHECK_TIME的體部分:
Sql代碼
 
  1. SELECT TRIGGER_BODY FROM USER_TRIGGERS WHERE TRIGGER_NAME='CHECK_TIME';  

結(jié)果為:
Sql代碼
 
  1. TRIGGER_BODY   
  2.         ----------------------------------------------------------------------------------------   
  3.         BEGIN  
  4.         IF (TO_CHAR(SYSDATE,'DY'IN ('SAT','SUN'))   
  5.          OR TO_CHAR(SYSDATE,'HH24')<   
  6.        TRIGGER_BODY字段為L(zhǎng)ONG類型,只顯示出腳本的一部分內(nèi)容。  

階段訓(xùn)練
【訓(xùn)練1】  創(chuàng)建觸發(fā)器,進(jìn)行表的同步復(fù)制。
步驟1:創(chuàng)建emp表的復(fù)本employee:
Sql代碼
 
  1. CREATE TABLE employee AS SELECT * FROM emp;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 表已創(chuàng)建。   

步驟2:創(chuàng)建和編譯以下觸發(fā)器:
Sql代碼
 
  1. CREATE OR REPLACE TRIGGER DUPLICATE_EMP   
  2.         AFTER    
  3.         UPDATE OR INSERT OR DELETE  
  4.         ON EMP   
  5.         FOR EACH ROW   
  6.         BEGIN      
  7.          IF INSERTING THEN    
  8.          INSERT INTO employee    
  9.          VALUES(:new.empno,:new.ename,:new.job,:new.mgr,   
  10.            :new.hiredate,:new.sal,:new.comm,:new.deptno);   
  11. ELSIF DELETING THEN  
  12.   DELETE FROM employee    
  13.   WHERE empno=:old.empno;   
  14.  ELSE  
  15.   UPDATE employee SET    
  16.   empno=:new.empno,   
  17.   ename=:new.ename,   
  18.   job=:new.job,   
  19. mgr=:new.mgr,   
  20.   hiredate=:new.hiredate,   
  21.   sal=:new.sal,   
  22.   comm=:new.comm,   
  23.   deptno=:new.deptno   
  24.   WHERE empno=:old.empno;   
  25.  END IF;   
  26. END;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 觸發(fā)器已創(chuàng)建。  

步驟3:對(duì)emp表進(jìn)行插入、刪除和更新:
Sql代碼
 
  1. DELETE FROM emp WHERE empno=7934;   
  2.         INSERT INTO emp(empno,ename,job,sal)        VALUES(8888,'ROBERT','ANALYST',2900);   
  3.         UPDATE emp SET sal=3900 WHERE empno=7788;   
  4.         COMMIT;  

執(zhí)行結(jié)果:
Sql代碼
 
  1. 已刪除 1 行。   
  2. 已創(chuàng)建 1 行。   
  3. 已更新 1 行。   
  4. 提交完成。   

步驟4:檢查emp表和employee表中被插入、刪除和更新的雇員。
運(yùn)行結(jié)果略,請(qǐng)自行驗(yàn)證。
  說(shuō)明:在觸發(fā)器中判斷觸發(fā)事件,根據(jù)不同的事件對(duì)employee表進(jìn)行不同的操作。
【練習(xí)1】創(chuàng)建一個(gè)emp表的觸發(fā)器EMP_TOTAL,每當(dāng)向雇員表插入、刪除或更新雇員信息時(shí),將新的統(tǒng)計(jì)信息存入統(tǒng)計(jì)表EMPTOTAL,使統(tǒng)計(jì)表總能夠反映最新的統(tǒng)計(jì)信息。
統(tǒng)計(jì)表是記錄各部門雇員總?cè)藬?shù)、總工資的統(tǒng)計(jì)表,結(jié)構(gòu)如下:
部門編號(hào) number(2)
總?cè)藬?shù) number(5)
總工資 number(10,2)
練習(xí)
1. 下列有關(guān)觸發(fā)器和存儲(chǔ)過(guò)程的描述,正確的是:
A. 兩者都可以傳遞參數(shù)
B. 兩者都可以被其他程序調(diào)用
C. 兩種模塊中都可以包含數(shù)據(jù)庫(kù)事務(wù)語(yǔ)句
D. 兩者創(chuàng)建的系統(tǒng)權(quán)限不同
2. 下列事件,屬于DDL事件的是:
    A.  INSERT B.  LOGON
    C.  DROP D.  SERVERERROR
3. 假定在一個(gè)表上同時(shí)定義了行級(jí)和語(yǔ)句級(jí)觸發(fā)器,在一次觸發(fā)當(dāng)中,下列說(shuō)法正確的是:
    A. 語(yǔ)句級(jí)觸發(fā)器只執(zhí)行一次
    B. 語(yǔ)句級(jí)觸發(fā)器先于行級(jí)觸發(fā)器執(zhí)行
           C. 行級(jí)觸發(fā)器先于語(yǔ)句級(jí)觸發(fā)器執(zhí)行
                D. 行級(jí)觸發(fā)器對(duì)表的每一行都會(huì)執(zhí)行一次
4. 有關(guān)行級(jí)觸發(fā)器的偽記錄,下列說(shuō)法正確的是:
   A.  INSERT事件觸發(fā)器中,可以使用:old偽記錄。
   B.  DELETE事件觸發(fā)器中,可以使用:new偽記錄。
   C.  UPDATA事件觸發(fā)器中,只能使用:new偽記錄。
                D.  UPDATA事件觸發(fā)器中,可以使用:old偽記錄。
5. 下列有關(guān)替代觸發(fā)器的描述,正確的是:
    A. 替代觸發(fā)器創(chuàng)建在表上
                B. 替代觸發(fā)器創(chuàng)建在數(shù)據(jù)庫(kù)上
                C. 通過(guò)替代觸發(fā)器可以向基表插入數(shù)據(jù)
                D. 通過(guò)替代觸發(fā)器可以向視圖插入數(shù)據(jù)
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Oracle PL/SQL開發(fā)基礎(chǔ)(第五彈:視圖)
兩個(gè)經(jīng)典的Oracle觸發(fā)器示例
梓軒--sql語(yǔ)句編程手冊(cè)(實(shí)用+練習(xí))
oracle數(shù)據(jù)庫(kù)基本操作
Oracle筆記-第8天
MySQL操作筆記(五萬(wàn)字詳解)
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服