zoukankan      html  css  js  c++  java
  • Oracle触发器详解


    1、触发器是指存在数据库中,被隐含执行的存储过程,可以支持dml触发器,
       还支持基于系统事件[启动数据库,关闭数据库,登录]和ddl操作建立触发器

    ----------------------
    --触发器分类
    ----------------------
    1、dml触发器 - insert、delete、update
    2、ddl触发器 - create table|view ..、drop ..

    ----------------------
    --语法介绍
    ----------------------
    create[or replace] trigger trigger_name
    {before|after}
    {insert|delete|update[of column[,column ....]]}
    on[schema.]table_name
    [for each row]
    [when condition]
    begin
      tigger_body;
    end;

    ------------------------------------------------
    --dml触发器 - insert、delete、update
    ------------------------------------------------
    --案例
    1、当插入数据时,就提示添加记录信息
    create or replace trigger mytrigger
    after insert on scott.emp
    begin
      dbms_output.put_line('添加一条记录');
    end;

    insert into emp(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
    values(7945,'jiji','zhonguo',7566,to_date('1980/12/17', 'yyyy/mm/dd'), 20000,1000,20);


    2、在某张表修改多条数据的时候,提示 修改数据
    create or replace trigger mytrigger
    after update on scott.emp
    begin
      dbms_output.put_line('修改了数据');
    end;

    3、--禁止工作人员在休息日改变员工信息
       开发人员可以建立before语句触发器,从而实现数据的安全
    create or replace trigger mytrigger
    before delete on scott.emp
    begin
      if to_char(sysdate, 'day') in('星期日', '星期六', '星期五') then
        --dbms_output.put_line('对不起,休息日不能删除表');
        RAISE_APPLICATION_ERROR('-20001', '对不起,休息日不能删除员工'); --自定义错误
      end if;
    end;

    --特别说明
    ①、RAISE_APPLICATION_ERROR这个过程,是oracle提供的,可以传入两个参数
    第一个:自定义的错误号 -20000~-20999
    第二个:提示信息

    4、--dml联合使用
    create or replace trigger mytrigger
    before insert or update or delete on scott.emp
    begin
      case
        when inserting then
          RAISE_APPLICATION_ERROR(-20002, '请不要添加');
        when updating then
          RAISE_APPLICATION_ERROR(-20003, '请不要修改');
        when deleting then
          RAISE_APPLICATION_ERROR(-20004, '请不要删除');  
      end case;
    end;

    -----------------------
    5、使用 :old 和 :new
    -----------------------
    问题:当触发器被触发时,要使用被插入、更新或删除的记录中的列值,有时要使用操作前、后列的值
    -- :new 修饰符访问操作完成后列的值
    -- :old 修饰符访问操作完成前列的值

    特性    insert     update   delete
    old     NULL       有效      有效
    new     有效       有效      NULL

    --案例
    1、在修改emp表 雇员的薪水时,显示雇员工资修改前和修改后的值
    2、如何确保在修改员工工资不能低于原有工资
    create or replace trigger mytrigger
    before update on scott.emp
    for each row
    begin
      if :new.sal<:old.sal then
         RAISE_APPLICATION_ERROR(-20005, '工资不能低于原有工资');
      else
        dbms_output.put_line('原有工资:'||:old.sal||'现在工资:'||:new.sal);
      end if;
    end;

    update emp set sal=3 where empno=7934;
    update emp set sal=300 where empno=7934;


    6、编写一个触发器,保证当用户在删除一张表记录的时候
       自动把删除的记录备份到另一张表中
    create table emp_bak as select * from emp;

    create or replace trigger mytrigger
    before delete on scott.emp
    for each row
    begin
       insert into emp_bak(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)
    values(:old.EMPNO,:old.ENAME,:old.JOB,:old.MGR,:old.HIREDATE,:old.SAL,:old.COMM,:old.DEPTNO);    
    end;
       


    ------------------------------------------------
    --ddl触发器 - create table|view ..、drop ..
    ------------------------------------------------
    ①为了记录系统所发生的ddl事件,应该建立一张表[ddl_event]用来存储相关信息
    ②注意需要使用system用户登录conn system/manager as sysdba;

    --语法
    create or replace trigger 触发器名
    after ddl 方案名.schema --如:scott.schema
    begin
      执行语句
    end;

    --案例
    create table ddl_table(
      event varchar2(64),    --事件名
      username varchar2(64), --用户名
      ddl_time date          --时间
    );

    --创建触发器 可以记录某个用户进行的ddl操作
    create or replace trigger ddl_triiger
    after ddl on scott.schema
    begin
      insert into ddl_table  --插入 事件名、当前用户、当前时间
      values(ora_sysevent, ora_login_user, sysdate);
    end;


    ---------------------------------------
    --系统触发器
    ---------------------------------------
    --语法
    create or replace trigger 触发器名
    after[before] logon[logoff] on database
    begin
      执行语句
    end;

    注意事项:
    ①需要建立在sys|system上
    ②由系统管理员来完成

    --常用属性函数
      ora_client_ip_address 返回客户端的ip
      ora_database_name 返回数据库名
      ora_login_user 返回登录用户名
      ora_sysevent 返回触发触发器的系统事件名
      ora_des_encrypted_password 返回用户des(md5)加密后的密码

    --创建表,用于保存用户登录或者退出的情况
    create table log_table(
      username varchar2(20),  --登录名
      logon_time date,        --登录时间
      logoff_time date,       --退出时间
      address varchar2(20)    --登录地址
    );

    1、--登录触发器
    create or replace trigger logon_trigger
    after logon on database
    begin
      insert into log_table(username,logon_time,address)
      values(ora_login_user, sysdate, ora_client_ip_address);
    end;


    2、--退出触发器
    create or replace trigger logoff_trigger
    before logoff on database
    begin
      insert into log_table(username,logoff_time,address)
      values(ora_login_user, sysdate, ora_client_ip_address);
    end;


    ---------------------------------------
    --管理触发器
    ---------------------------------------
    1、禁止触发器
       是指让触发器临时失效
       alter trigger 触发器名 disable;

    2、激活触发器
       alter trigger 触发器名 enable;

    3、禁止或是激活表的所有触发器
       alter table emp disable all triggers;(9i)
       alter table emp enable all triggers;(9i)

    4、删除触发器
       drop trigger 触发器名
       
      

  • 相关阅读:
    消息机制
    窗口!窗口!- Windows程序设计(SDK)003
    内联函数的作用
    结构体变量用 . 结构体指针用-> 的原因
    &a和a的区别
    分布电容
    介电常数
    天线
    封装的思想
    关于中断标志位
  • 原文地址:https://www.cnblogs.com/qintangtao/p/2752065.html
Copyright © 2011-2022 走看看