• oracle实验39:触发器


    触发器

    使用触发器的目的

    • 维护数据的完整性
    • 通过视图改基表
    • 审计数据库的操作

    实验39:触发器

    构建实验表

    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;

    表已创建。

    创建触发器

    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;
         /

    触发器已创建

    验证触发器的状态

    SQL> select trigger_name,status from user_triggers;

    TRIGGER_NAME                   STATUS                                           
    ------------------------------ --------                                         
    D_UPDATE                       ENABLED                                         

    改变触发器的状态

    禁用某个触发器

    SQL> alter trigger d_update disable;

    触发器已更改

    SQL> select trigger_name,status from user_triggers;

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

    禁用某个表上所有的触发器

    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;

    触发器已删除。


  • 相关阅读:
    一个非常棒的jQuery 评分插件好东西要分享
    Visual Studio 2012 更新包2发布,附离线安装方法及下载
    ECC Copy Client 之后的SAP*登陆问题 沧海
    使用现有ECC数据库进行安装或者恢复系统 沧海
    SAP 登陆平衡(SAP Logon Balancing) 沧海
    Target host or target server ***** is not in operation mode 沧海
    如何获得系统设置参数列表 沧海
    IDES安装之后的配置 沧海
    关于Basware的使用随想 沧海
    Information About the SAP Load Generator (SGEN) 沧海
  • 原文地址:https://www.cnblogs.com/downpour/p/3166063.html
Copyright © 2020-2023  润新知