oracle實驗39:觸發器

觸發器

使用觸發器的目的數據庫

  • 維護數據的完整性
  • 經過視圖改基表
  • 審計數據庫的操做

實驗39:觸發器

構建實驗表app

SQL> drop table d purge;

表已刪除。

SQL> drop table e purge;

表已刪除。

SQL> create table d as select * from dept;

表已建立。

SQL>  create table e as select * from emp;

表已建立。

spa

 

建立觸發器 it

SQL> create or replace trigger d_update
     after delete or update of deptno on d
     for each row --行級觸發
     begin  
     if (updating and :old.deptno != :new.deptno)
     then update e
     set deptno =:new.deptno
     where deptno=:old.deptno;
     end if;   --當d表的部門號修改的時候e表的部門號也相應的修改
     if deleting then
     delete e where deptno=:old.deptno;
     end if;   --當d表的部門號修改的時候e表的部門號也相應的修改
     end;
     /

觸發器已建立

io

驗證觸發器的狀態table

SQL> select trigger_name,status from user_triggers;

TRIGGER_NAME                   STATUS                                           
------------------------------ --------                                         
D_UPDATE                       ENABLED                                          登錄

 

改變觸發器的狀態date

禁用某個觸發器select

SQL> alter trigger d_update disable;

觸發器已更改

SQL> select trigger_name,status from user_triggers;

TRIGGER_NAME                   STATUS                                           
------------------------------ --------                                         
D_UPDATE                       DISABLED                                         

error

禁用某個表上全部的觸發器

SQL> alter table d disable all triggers;

表已更改。

SQL> select * from d;

    DEPTNO DNAME          LOC                                                   
---------- -------------- -------------                                         
        10 ACCOUNTING     NEW YORK                                              
        20 RESEARCH       DALLAS                                                
        30 SALES          CHICAGO                                               
        40 OPERATIONS     BOSTON                                                

刪除觸發器

SQL> drop trigger d_update;

觸發器已刪除。


SQL> select trigger_name,status from user_triggers;

未選定行

驗證d_update的功能

SQL> update d set deptno=50 where deptno=30;

已更新 1 行。

SQL> select empno,ename from e;

     EMPNO ENAME                                                                
---------- ----------                                                           
      7369 SMITH                                                                
      7499 ALLEN                                                                
      7521 WARD                                                                 
      7566 JONES                                                                
      7654 MARTIN                                                               
      7698 BLAKE                                                                
      7782 CLARK                                                                
      7839 KING                                                                 
      7844 TURNER                                                               
      7900 JAMES                                                                
      7902 FORD                                                                                            
      7934 MILLER                                                               

已選擇12行。

SQL> select * from d;

    DEPTNO DNAME          LOC                                                   
---------- -------------- -------------                                         
        10 ACCOUNTING    NEW YORK                                              
        20 RESEARCH        DALLAS                                                
        50 SALES              CHICAGO                                               
        40 OPERATIONS     BOSTON                                                

SQL> delete d where deptno=20;

已刪除 1 行。

SQL> select empno,ename,deptno from e;

     EMPNO ENAME          DEPTNO                                                
---------- ---------- ----------                                                
      7499 ALLEN              50                                                
      7521 WARD               50                                                
      7654 MARTIN             50                                                
      7698 BLAKE              50                                                
      7782 CLARK              10                                                
      7839 KING               10                                                
      7844 TURNER             50                                                
      7900 JAMES              50                                                
      7934 MILLER             10                                                

已選擇9行。



SQL> select * from d;

    DEPTNO DNAME          LOC                                                   
---------- -------------- -------------                                         
        10 ACCOUNTING     NEW YORK                                              
        50 SALES          CHICAGO                                               
        40 OPERATIONS     BOSTON                                                

SQL> commit;

部門編號爲20的數據都不存在了。

觸發器的類型

行級觸發

    • 行級觸發FOR EACH ROW
    • 影響的每一行都會執行觸發器

語句集觸發

    • 默認的模式,一句話才執行一次觸發器
    • 觸發器不能嵌套,不能含有事物控制語句。


什麼時候觸發

before
在條件運行以前,執行觸發器

after
在條件運行後,執行觸發器

instead of
替代觸發,做用在視圖上

禁止對錶e的sal進行修改

SQL> create or replace trigger e_update
  2  before update of sal on e
  3  begin
  4  if updating then
  5  raise_application_error(-20001,'工資不能被改動');
  6  end if;
  7  end;
  8  /

觸發器已建立

SQL> select ename,sal from e;

ENAME             SAL                                                           
---------- ----------                                                           
ALLEN            1600                                                           
WARD             1250                                                           
MARTIN           1250                                                           
BLAKE            2850                                                           
CLARK            2450                                                           
KING             5000                                                           
TURNER           1500                                                           
JAMES             950                                                           
MILLER           1300                                                           

已選擇9行。

SQL> update e set sal=2000 where ename='ALLEN';
update e set sal=2000 where ename='ALLEN'
       *
第 1 行出現錯誤:
ORA-20001: 工資不能被改動
ORA-06512: 在 "SCOTT.E_UPDATE", line 3
ORA-04088: 觸發器 'SCOTT.E_UPDATE' 執行過程當中出錯

保存老值和新的值

SQL> DROP TABLE T1;

表已刪除。

SQL> CREATE TABLE T1 AS SELECT sal old_value,sal new_value from emp where 0=9;

表已建立。

SQL> create or replace trigger trg1
  2  before insert or update of sal on emp
  3  for each row
  4  begin
  5  insert into t1 values(:old.sal,:new.sal);
  6  end;
  7  /

觸發器已建立

SQL> select * from t1;

未選定行

SQL> update emp set sal=sal+1;

已更新12行。

SQL> commit;

提交完成。

SQL> select * from t1;

 OLD_VALUE  NEW_VALUE                                                           
---------- ----------                                                           
       800        801                                                           
      1600       1601                                                           
      1250       1251                                                           
      2975       2976                                                           
      1250       1251                                                           
      2850       2851                                                           
      2450       2451                                                           
      5000       5001                                                           
      1500       1501                                                           
       950        951                                                           
      3000       3001                                                                                                                    
      1300       1301                                                           

已選擇12行。



創建一個經過視圖來改基表的視圖v1

SQL> drop table e1;

表已刪除。

SQL> create table e1 as select * from emp;

表已建立。

SQL> drop view v1;
SQL> create view v1 as select distinct deptno from e1;

視圖已建立。

試圖修改v1時報錯

SQL> update v1 set deptno=50 where deptno=10;
update v1 set deptno=50 where deptno=10
       *
第 1 行出現錯誤:
ORA-01732: 此視圖的數據操縱操做非法

創建一個替代觸發器,當修改v1時會自動修改基表

SQL> create or replace trigger trigger_instead_of
  2  instead of insert or update or delete on v1
  3  begin
  4  if updating then
  5  update e1 set deptno=:new.deptno where deptno=:old.deptno;
  6  end if;
  7  end;
  8  /

觸發器已建立


SQL> update v1 set deptno=50 where deptno=10;

已更新 1 行。

SQL> select ename,deptno from e1;

ENAME          DEPTNO                                                           
---------- ----------                                                           
SMITH              20                                                           
ALLEN              30                                                           
WARD               30                                                           
JONES              20                                                           
MARTIN             30                                                           
BLAKE              30                                                           
CLARK              50                                                           
KING               50                                                           
TURNER             30                                                           
JAMES              30                                                           
FORD               20                                                          
ENAME          DEPTNO                                                           
---------- ----------                                                           
MILLER             50                                                           

已選擇12行。

SQL> select * from v1;

    DEPTNO                                                                      
----------                                                                      
        30                                                                      
        20                                                                      
        50                                                                      

創建一個登陸的審計觸發器

SQL> drop table login_table;
SQL>  create table login_table(user_id varchar2(15),log_date date,action varchar2(15));

表已建立。


SQL> create or replace trigger logon_trig
  2  after logon on schema  --on schema方式是隻記錄當前的用戶行爲
  3  begin
  4  insert into login_table(user_id,log_date,action)
  5  values(USER,SYSDATE,'Logging on');
  6  end;
  7  /

觸發器已建立


SQL> create or replace trigger logoff_trig
  2  before logoff on schema
  3  begin
  4  insert into login_table(user_id,log_date,action)
  5  values(USER,SYSDATE,'Logging off');
  6  end;
  7  /

觸發器已建立

SQL> conn scott/scott
已鏈接。

SQL> select * from login_table;

USER_ID         LOG_DATE       ACTION                                           
--------------- -------------- ---------------                                  
SCOTT           17-6月 -13     Logging off                                      
SCOTT           17-6月 -13     Logging on                                       


SQL> conn zhengyu/zhengyu
已鏈接。

SQL> conn scott/scott
已鏈接。

SQL> select * from login_table;USER_ID         LOG_DATE       ACTION                                           --------------- -------------- ---------------                                  SCOTT           17-6月 -13     Logging off                                      SCOTT           17-6月 -13     Logging on                                       SCOTT           17-6月 -13     Logging on                                       SCOTT           17-6月 -13     Logging off                                      SQL> select user_id,to_char(log_date,'yyyy/mm/dd:hh24:mi:ss') log_date,action from login_table;USER_ID         LOG_DATE            ACTION                                      --------------- ------------------- ---------------                             SCOTT           2013/06/17:17:04:55 Logging off                                 SCOTT           2013/06/17:17:05:42 Logging on                                  SCOTT           2013/06/17:17:04:56 Logging on                                  SCOTT           2013/06/17:17:05:33 Logging off                                 SQL> drop trigger logon_trig;觸發器已刪除。SQL> drop trigger logoff_trig;觸發器已刪除。

相關文章
相關標籤/搜索