zoukankan      html  css  js  c++  java
  • 触发器 trigger

    触发器是被指定关联到一个表的数据对象,它不需要调用,当对一个表的特别事件出现时,它就被激活。触发器的代码也是由SQL语句组成的,因此用在存储过程中的语句也可以用再触发器的定义中。触发器是一类特殊的存储过程,与表的关系密切,用于保护表中的数据,当有操作影响到触发器保护的数据时,触发器将自动执行。

    (1)DML触发器:当数据库中发生数据操作语句(DML)事件时调用DML触发器。DML事件包括用表或视图的 insert语句,update语句和delect语句,因此DML触发器可分为3种。

    (2)代替触发器:由于oracle中不能直接对两个以上的表建立的视图进行操作,所以给出了代替触发器。它是oracle专门为进行视图操作的一种处理方式。

    3)系统触发器:系统触发器也由相应的事件触发,但它的激活一般基于对数据库系统所进行得操作,如数据定义语句(DDL),启动或关闭触发器,连接或断开,服务器错误等系统事件。

    命令创建触发器:

    --语法格式
    create  or replace trigger 触发器的名称
    before  /after/instead of
    insert/update/delete  
    on  for each row

    说明:

    触发器名称:触发器的名字与过程名和包的名字不一样,它有单独的名字空间,因此触发器名可以和表名或过程名同名,但在同一个方案中的触发器名不能相同。

    after:触发器在指定操纵都成功执行后触发,如after insert 表示在向表中插入数据后激活触发器

    before:触发器在指定操作执行前触发,如before insert 表示在向表中插入数据前激活触发器

    instead of: 指定创建代替触发器,触发器指定的事件不执行,而执行触发器本身的操作。

    delete,insert,update:指定一个或多个触发器,多个触发器事件之间用 or 连接

    of:指定在某列上update触发器,如果为多列,则需要使用逗号分隔。

    for each row:在触发器定义中,如果未使用for each row 子句则表示触发器为语句触发器,触发器在激活后只执行一次,而不管这一操作将影响多行。

    创建触发器有以下限制:

    (1) 代码大小。触发器代码大小必须小于32K。

    (2) 触发器中有效语句可以包括DML语句,但不能包括DDL语句。ROLLBACK、COMMIT、SAVEPOINT也不能使用。但是,对于系统触发器(system trigger)可以使用CREATE、ALTER、DROP TABLE和ALTER…COMPILE语句。

    (3) LONG、LONG RAW和LOB的限制:

         ① 不能插入数据到LONG或LONG RAW;

         ② 来自LONG或LONG RAW的数据可以转换成字符型(如char、varchar2),但是不能超过32K;

         ③ 使用LONG或LONG RAW不能声明变量;

         ④ 在LONG或LONG RAW列中不能使用:NEW和:PARENT;

         ⑤ 在LOB中的:NEW变量不能修改。

    (4) 引用包变量的限制。如果UPDATE或DELETE语句检测到当前的UPDATE冲突,则Oracle执行ROLLBACK到SAVEPOINT上并重新启动更新,这样可能需要多次才能成功。

    创建DML触发器:

    --假设数据库中增加一新表school_students_old,表结构和表school_students相同,用来存放从school_students表
    --中删除的记录。创建一个触发器,当school_students表被删除一行,把删除的记录写到日志表school_students_old中。
    create table school_students_old2 //创建新表 ( STU_ID NVARCHAR2(
    20) NOT NULL, STU_NAME NVARCHAR2(20) NOT NULL , STU_SEX NVARCHAR2(20) , STU_CREDITS NUMBER(2) , STU_BIRTHDAY DATE , STU_CLASS NVARCHAR2(20) ); select * from school_students_old2; create or replace trigger delete_stu //创建触发器 before delete on school_students for each row begin insert into school_students_old2 (STU_ID,STU_NAME,STU_SEX,STU_CREDITS,STU_BIRTHDAY,STU_CLASS) values (:old.STU_ID,:old.STU_NAME,:old.STU_SEX,:old.STU_CREDITS,:old.STU_BIRTHDAY,:old.STU_CLASS); end delete_stu; select * from school_students; select * from school_students_old;

    创建代替触发器:

    --在数据库中创建视图和触发器,以说明替代触发器。
    create or replace view stu_avg
    as
    select
    RESULT_STU,
    avg(result_number) as stu_avg from
    SCHOOL_RESULT
    group by RESULT_STU;
    
    select * from stu_avg where RESULT_STU='201632218031';
    
    delete from stu_avg where RESULT_STU='201632218031';
    
    create or replace trigger tr_stu_avg_delete
    instead of delete on stu_avg for each row
    begin
       delete from SCHOOL_RESULT 
       where result_stu=:old.result_stu;
    end tr_stu_avg_delete;

    创建系统触发器:

    --创建当一个用户userA登录时自动记录一些信息的触发器。
    create table login_log
    (
       v_user  varchar2(100),
       v_date  date
    );
    
    create or replace trigger tr_login_log
      after logon on schema
      declare 
       v_name VARCHAR2(20);
       begin
       select user into v_name from dual;
       insert into login_log values(v_name,sysdate);
       end tr_login_log;
      
      select * from login_log;
      

    启用和禁用触发器:

    在oracle中,与过程,函数,包不同,触发器是可以被禁用和启用的,在有大量数据要导入数据库中时,为了避免触发相应的触发器以节省处理时间,可以禁用触发器,使其暂时失效,触发器被禁用后任然存储在数据库中,只要重新启用既可以使它重新工作。

    oracle提供了alter trigger语句来禁用和启用触发器

    --语法格式
    alter trigger [<用户名方案名.>]<触发器>
        disable|enable;

    其中:disable表示禁用触发器,enable表示启用触发器

    触发器的删除:

    --语法格式
    drop trigger [<用户名方案名.>]<触发器>

    也可以用界面删除触发器

  • 相关阅读:
    面向对象之property
    mysql数据库基本操作
    mysql数据库操作
    初识多线程__上
    npm 安装express npm ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE
    markdown快捷键
    try_except__异常处理
    妹子图爬取__RE__BS4
    进程中的锁以及进程池
    pip升级到18.0版本过程中报错解决方法
  • 原文地址:https://www.cnblogs.com/zhangpichun-7/p/13192757.html
Copyright © 2011-2022 走看看