Oracle触发器更新-转载_*[宏]*_百度空间

========================触发器========================
特殊的子程序:                    --声明变量时:declare 不是as/is
1.触发器的执行条件
    触发事件:
        DML+DDL....
        Insert、Delete、Update、Create、Alter、Drop、Grant ......
    触发时机:
        触发器是在某个触发事件前还是后执行 (before/after...)
    触发对象:
        只有对特定的对象操作,触发器才有可能触发 (on...)
    触发类型:
        语句级还是行级
        语句级:触发事件执行一次就触发一次(只关心触发事件的类型)
        行级:触发事件在具体执行时,每操作一行就触发一次(不但关系类型,还关系对行的影响)(for each row)
    触发条件:
        触发器在满足以上所有条件以外,还要满足的额外条件 (when...)
    条件谓词:
        触发器中的语法元素
        Inserting、Updating、Deleting等
       
2.应用时机:
    实现商业规则和企业逻辑的方法很多,可以使用约束、触发器、子程序(过程和函数)。
   1、约束性能{zh0},实现也最简单,所以{sx}约束。
   2、其次是触发器。
   3、{zh1}才是子程序
   4、应用程序
  
3.分类:
   1.语句级
    --以一个完整的DML语句为单位执行触发
    --与DML语句影响的行数无关
    --语句级触发器,不可以记录列数据的变化,只能审计DML操作或确保DML操作安全执行

   2.行级
   
    --由DML语句执行的DML操作所影响的行为单位触发
    --可能执行多次,因为一个DML语句可能操作多行
    --行级触发器可以访问列值
   
    --:old / :new 行级独有
    在PL/SQL块或SQL语句中应用时,前面要加‘:’,但是,在when condition子句中不用加
   
   3.替代触发器
  
    可更新视图:可以在其上执行DML语句的视图,可更新视图不包含以下内容:
    集合操作、聚集函数、分组、xx重复、连接操作
   
    注意:
    --不能指定before/after选项
    --必须指定for each row选项
    --没有必要针对一个表的视图创建替代触发器
  
4.其他操作:

数据字典:user_triggers
禁止触发器
alter trigger trigger_name disable;
xx触发器
alter trigger trigger_name enable;
禁止/xx表上的全部触发器
alter table table_name disable all triggers;
alter table table_name enable all triggers;
重新编译触发器
alter trigger trigger_name compile;
删除触发器
drop trigger trigger_name

6.注意问题:
触发器中不可以包含事务控制语句
触发器调用的过程、函数都不能包含事务控制语句
在触发器主体中不可以声明LOB、LONG或LONG RAW类型的变量
触发器不可以接受参数
触发器{zd0}不得超过32K
一个表上最多可以创建12个触发器

  
7.范例:

1.语句级:
----------------------------应用范例:安全性控制-----------------------------

   --创建触发器,阻止用户在非工作时间操作emp中的任何数据
  
   Create or replace trigger tr_emp_time
   Before insert or update or delete
   On emp
   Begin
    if
    (to_char(sysdate,'day') in ('星期六','星期天')) or
    (to_char(sysdate,'hh24') not between 8 and 18)
    then  
     raise_application_error(-20001,'不是上班时间,不能修改emp表');
    end if;
   End;

2.行级:

   1、==自动编号实现==
    .....
   
   2、====销售人员工资不能降低,销售人员补助不能降,销售人员纪录不能删除===
  
   Create or replace trigger tr_emp_sal_comm
   Before update of sal,comm or delete
   on emp
   For each row
   When (old.job=‘SALESMAN’)
   Begin
    case
    when updating(‘sal’) then
     if :new.sal<:old.sal then
      raise_application_error(-20001,’销售人员工资不能降’);
     end if;
    when updating(‘comm’) then
     if :new.comm<:old.comm then
      raise_application_error(-20002,’销售人员补助不能降’);
     end if;
    when deleting then
     raise_application_error(-20003,’销售人员纪录不能删除’);
    end case;
   End;
  
   3.============行级触发器实现数据备份=============
  
    解雇员工时,需要把员工的详细信息在emp表中删除,为了保留此信息,以备于以后使用,我们通过
    触发器实现,当删除一名员工时,自动的把这个员工的信息放置到解雇员(fire_emp)工表中.
   
    create table fire_emp as select * from emp;
    delete from fire_emp;
   
    create or replace trigger fire_emp_tri
    after delete
    on emp
    for each row
    begin
    insert into fire_emp
    values(:old.ENAME,:old.SEX,:old.ID,:old.SALARY,:old.CITY,:old.BIRTHDAY,:old.ADDRESS,:old.DNO,:old.PNO);
    end fire_emp_tri;
  
   4.===========行级触发器实现级联删除================

    利用触发器实现,当删除一个部门时,自动把部门的员工全部删除
    先对部门表和员工表数据备份,在两个备份表上作实验
   
    create table BK_emp as select * from emp;
    create table BK_dept as select * from dept;
   
   
    create or replace trigger remove_dept
    after delete
    on BK_dept
    for each row
    begin
    delete from BK_emp where dno=:old.dno;
    end remove_dept;
   
    select * from bk_emp where dno=1;
    delete from bk_dept where dno=1;
    select * from bk_emp where dno=1;
  
   5.============行级触发器实现级联更新=============
    利用触发器实现,当修改一个部门的编号,自动的把员工的部门编号也一起更改过来。
   
    create or replace trigger e_d_tri
    after update of dno
    on bk_dept
    for each row
    begin
    update bk_emp set dno=:new.dno where dno=:old.dno;
    end e_d_tri;
  
   6.==================生成流水号==================


    --创建表
    create table codes(uname varchar2(20), code varchar(50));


    --创建序列
    create sequence seq_code;


    --创建触发器实现,插入uname时自动生成流水号:系统时间+自增长列+uname


    create or replace trigger tri_code
    before insert on codes
    for each row
    declare
       v_num int;
    begin
       select seq_code.nextval into v_num from dual;
       :new.code:=to_char(sysdate,'YYMMDDHH24MISS')||v_num||:new.uname;
    end;
   
    select * from codes;
    insert into codes(uname) values('hemes');
    drop trigger tri_code;

3.替代

详见13-PLSQL高级-2-范例



郑重声明:资讯 【Oracle触发器更新-转载_*[宏]*_百度空间】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——