zoukankan      html  css  js  c++  java
  • Oracle基础<5>--触发器

    一、触发器

      触发器是当特定事件出现时自动执行的代码块。比如,每次对员工表进行增删改的操作时,向日志表中添加一条记录。触发器和存储过程是由区别的:触发器是根据某些条件自动执行的,存储过程是手动条用的。

      (一)触发器的类型:

        1、行级触发器:操作数据行的时候触发。   《行级触发器对DML语句影响的每一行执行一次》

      行级触发器可以在create trigger 命令中指定for each row 子句创建行级触发器

        2、语句级触发器:一个DML语句触发一次的触发器。行级触发器和语句级触发器一起也成为DML触发器。

        (语句触发器是create trigger 命令创建的触发器的默认类型)

        3、INSTEADOF 触发器:主要是在视图上定义的触发器。

        4、模式触发器:用户事务触发器。

        5、数据库触发器:创建在数据库事件上的触发器。

     

      (二)触发器可以分为三个部分:

        1、触发器语句:触发器语句是哪些可以导致触发器的事件,即在表或者视图上执行INSERT、DELETE、UPDATE之类的DML语句,在模式对象上执行的DDL语句或数据库事件。所有可以导致触发器的事件都是触发器的语句。

        2、触发器限制:触发器限制条件包含一个布尔表达式,该值必须为”真“才能激活触发器,如果该值为”假“或”未知“,将不运行触发器操作。

        3、触发器操作:触发器操作时触发器的主体,包含一些SQL语句和代码,这些代码在执行触发器有且触发器限制条件为”真“时运行。行级触发器允许触发器操作中的语句访问行的列值。

      

      (三)触发器的常用功能如下:

      1、允许/限制对表的修改。

      2、自动生成派生列。

      3、强制数据一致性。

      4、强制复杂的完整性约束条件。

      5、提供审计和日志记录。

      6、防止无效的事件处理。

      7、启动复杂的业务逻辑。

      由于触发器是对数据进行监控的一个对象,随时监控着数据库中的数据和表,造成使用触发器的性能低下。这点尤为重要。

    二、创建触发器:

      语法:

      CREATE [OR REPLACE] TRIGGER trigger_name  --触发器的名称

      {BEFORE | AFTER                --在事件发生之前 或 之后激发触发器

      | INSTEAD OF}                 -- 表示执行触发器代码来代替导致触发器调用的事件

      {INSERT | DELETE | UDPATE | [OF column[,column]]}

      [OR {INSERT | DELETE | UPDATE [OF column[,column]]}]

      ON [schema.]table_or_view_name

      [REFERENCING [NEW AS new_row_name] [OLD AS old_row_name]]

      [FOR EACH ROW]

      [WHEN (condition)]

      [DECLARE

        variable_declation]

      BEGIN

        statements;

      [EXCEPTION

        exception_handlers]

      END[trigger_name];

    说明:

      trigger_name:触发器的名称

      BEFORE | AFTER :表示在事件发生之前或之后激活触发器

       INSTEAD OF:表示可以执行触发器代码来代替导致触发器调用的事件。

      INSERT | DELETE | UDPATE :指定构成触发器事件的数据库操作类型,UPDATE还可以指定列的列表。

      REFERENCING :指定新行(即将更新)和旧行(更新前)的其他名称,默认为NEW和OLD。

      (旧值OLD:在DML 语句之前存在的语句。 UPDATE 和DELETE通常引用旧值)

      (新值NEW: DML 创建的数据值)引用的时候使用OLD后面加点或“NEW”后面加点,然后在接字段名。

      table_or_view_name:触发器所监控的表或者视图的名称。

      FOR EACH ROW:表示是否对受影响的每一行都执行触发器,即行级触发器。如果不使用此语句,则为语句触发器,使用此语句则为行级触发器。

      WHEN (condition):限制执行触发器的条件,该条件可以包括新旧数据值的检查。

      DECLARE:声明触发器所使用的局部变量

      statements:触发器所执行的PL-SQL语句。

      exception_handlers:异常处理代码。

    三.触发器的管理

      (1)触发器的状态

         desabled:未启用状态

         enabled:已启用状态

    语法:

      alter trigger trigger_name {desabled | enabled}; --启用和禁止触发器

       drop trigger trigger_name;  --删除触发器

      SQL> DESC USER_TRIGGERS;  --查看触发器

    例1:生成一个自动编号(行级触发器)


     --创建测试表,学生表
    CREATE TABLE student
    (
        stu_id NUMBER CONSTRAINT pk_id PRIMARY KEY,
        stu_name VARCHAR2(20) NOT NULL,
        stu_phone VARCHAR2(20) NOT NULL
    ); 

    --创建一个序列,从1开始累加,每次加1
    CREATE SEQUENCE seq_student
        START WITH 1       --序列开始,从1开始计数
        INCREMENT BY 1     --每次增加1
        NOMAXVALUE         --不设置最大值
        NOCYCLE            --只累加,不循环
        CACHE 20;          --缓存20

    --创建一个触发器

    create or replace trigger student_insert_seq
      before insert on student          --在插入之前
      for each row                      --行级触发器
    begin
      :new.stu_id := seq_student.nextval;  --将插入的stu_id属性设置为序列的下一个值    --触发器的操作
    end student_insert_seq;

    --插入数据
    INSERT INTO student (stu_name,stu_phone) VALUES('张三','110');
    INSERT INTO student (stu_name,stu_phone) VALUES('李四','120');

    --查询,数据插入成功
    SELECT * FROM student


    例2:实现表操作日志


    --新建日志表序列
    CREATE SEQUENCE logs_id_squ INCREMENT BY 1     
                START WITH 1 MAXVALUE 9999999 NOCYCLE NOCACHE;
                            
    --日志表  
    CREATE TABLE logs(    
            LOG_ID NUMBER(10) PRIMARY KEY,    
            LOG_TABLE VARCHAR2(10) NOT NULL,    
            LOG_DML VARCHAR2(10),    
            LOG_KEY_ID NUMBER(10),    
            LOG_DATE DATE,    
            LOG_USER VARCHAR2(15)    
    ); 

    --创建日志触发器:表级触发器
    create or replace trigger trig_log
      after INSERT OR UPDATE OR DELETE 
        on emp  
      for each row
    DECLARE
      V_USERNAME VARCHAR2(20);
    BEGIN
      SELECT USER INTO V_USERNAME FROM dual;   --获取当前用户
      IF INSERTING THEN
          INSERT INTO logs VALUES(logs_id_squ.nextval,'emp','insert',:new.Empno,sysdate,V_USERNAME);
      ELSIF UPDATING THEN
          INSERT INTO logs VALUES(logs_id_squ.nextval,'emp','update',:new.Empno,sysdate,V_USERNAME);
      ELSIF DELETING THEN
          INSERT INTO logs VALUES(logs_id_squ.nextval,'emp','delete',:new.Empno,sysdate,V_USERNAME);
      END IF;
    END TRIG_LOG;

     

    二:触发器和存储过程的区别

      1.触发器是自动执行的(遇到某种情况自动执行) 不能进行显示调试

      触发器是对数据进行监控的一个对象   触发器缺陷:性能较低

      2.存储过程是可以被调用的

     

     

  • 相关阅读:
    php DOC类型注释的用法
    Mysql 数据库更新错误
    Smarty初体验二 获取配置信息
    Smarty 模板初体验
    去网络视频广告方法——虽过时,但效果依然很好(亲测)
    织梦模板修改方法大全
    dede织梦:文章内容页调用
    织梦系统学习:文章页当前位置的写法(自认对SEO有用)
    ZOJ 3229 Shoot the Bullet
    URAL 1277 Cops and Thieves
  • 原文地址:https://www.cnblogs.com/futao123/p/4470256.html
Copyright © 2011-2022 走看看