2024-03-19
原文作者:吴声子夜歌 原文地址: https://blog.csdn.net/cold___play/article/details/103838728

触发器概述

触发器是一种在发生数据库事件时能够自动运行的PL/SQL代码块,它与特定表或视图上的操作相关联。触发器是大型关系数据库系统都提供的一项技术。

触发器通常用来完成由数据库的完整性约束难以完成的复杂业务规则的约束,或用来监视对数据库的各种操作,实现审计功能。

触发器是一种特殊的存储过程,它与数据表紧密联系,用于保护表中的数据,当一个定义了特定类型触发器的基表执行插入、修改或删除表中数据的操作时,将自动触发器中定义的操作,以实现数据的一致性和完整性。

触发器的作用

触发器拥有比数据库本身标准的功能更精确和更复杂的数据控制能力。

  • 在安全方面,触发器可以基于数据库的值使用户具有操作数据库的某种权利。
  • 在审计方面,触发器可以跟踪用户对数据库的操作。
  • 实现复杂的数据完整性规则。
  • 实现复杂的非标准的数据库相关完整性规则。触发器可以对数据库中相关的表进行连环更新。
  • 同步实时地复制表中的数据。
  • 自动计算数据值,如果数据的值达到了一定的要求,则进行特定的处理。

触发器的分类

按照触发事件不同,触发器可以分为不同的类型,一般有如下3种:

  • DML触发器: 对表或视图执行DML操作时触发。
  • INSTEAD OF: 只定义在视图上用来替换实际的操作语句。
  • 系统触发器: 在对数据库系统进行操作(如DDL语句、启动或关闭数据库等系统事件)时重复啊。

相关概念

  • 触发事件
    引起触发器被触发的事件,如DML语句(INSERT、UPDATE、DELETE语句对表或视图执行数据处理操作)、DDL语句(如CREATE、ALTER、DROP语句在数据库中创建、修改、删除模式对象)、数据库系统事件(如系统启动或退出、异常错误)、用户事件(如登录或退出数据库)。
  • 触发条件
    触发条件是由WHEN子句指定的一个逻辑表达式。只有当该表达式的值为TRUE时,遇到触发事件才会自动执行触发器,使其执行触发操作,否则即便遇到触发事件也不会执行触发器。
  • 触发对象
    触发对象包括表、视图、模式、数据库。只有在这些对象上发生了符合条件的触发事件,才会执行触发事件。
  • 触发操作
    触发器所要执行的PL/SQL程序,即执行部分。
  • 触发时机
    触发时机指定触发器的触发时间。如果指定为BEFORE,则表示在执行DML操作前触发,以便防止某些错误操作发生或实现某些业务规则;如果指定为AFTER,则表示在DML操作之后触发,以便记录该操作或某些事后处理。
  • 触发子类型
    触发子类型分为 行触发(row)语句触发(statement) 。行触发是对触发事件影响的每一行执行触发器。语句触发,对于触发只能触发一次,而且不能访问受触发器影响的每一行的值。一般执行SQL语句操作时都应是行触发,只有对整个表做安全检查(即防止非法操作)时才用语句触发。如果省略此项,默认为语句触发。

此外,触发器还有两个相关值,分别对应被触发的行中的旧表值和新表值,用old和new来表示。

创建触发器时需要注意几个问题

  • 触发器应该建立在哪个表之上。
  • 触发器应该对什么样的DML操作进行相应。
  • 触发器在指定的DML操作之前激发还是在之后激发。
  • 对每次DML响应一次,还是对受DML操作影响的每一行数据都响应一次。

触发器的执行顺序

存储过程和函数都是由用户直接调用的,而对于触发器的执行,用户不能直接调用,Oracle会在相应的事件发生时,自动调用触发器。触发器的执行是由触发事件激活的,并由数据库服务器自动执行的。一个数据表上可能定义了多个触发器,比如多个BEFORE触发器,多个AFTER触发器等。同一个表上的多个触发器激活时遵循如下的执行顺序:

  1. 执行该表上的BEFORE触发器。
  2. 激活触发器的SQL语句。
  3. 执行该表上的AFTER触发器。

对于同一个表上的多个BEFORE(AFTER)触发器,遵循“谁先创建谁先执行”的原则,即按照触发器创建的时间先后顺序执行。

创建触发器的语法

    CREATE [OR REPLACE] TRIGGER <trigger_name>
    BEFORE|AFTER|INSTEAD OF
    INSERT|[OR]DELETE|[OR]UPDATE[OF column_name1,... n]
    ON table_name|view_name
    [FOR EACH ROW [WHEN <trigger_condition>]]
    BEGIN
    	trigger_body
    END [trigger_name];

具体的参数说明如下:

  • trigger_name: 指定触发器的名称。
  • BEFORE|AFTER|INSTEAD OF: 指定触发器的触发时间。BEFORE和AFTER分别表示在事件执行之前和之后执行触发器。INSTEAD OF指定创建替代触发器,触发事件不执行,而执行触发器本身的操作。
  • INSERT|[OR] DELETE| [OR] UPDATE: 指定触发事件的类型分别为插入型、更新型和删除型,多个触发事件之间使用OR连接。
  • OF列: 指出在哪些列上进行UPDATE触发。
  • ON table_name | view_name: 指出将为指定用户方案的表或者视图创建触发器。
  • FOR EACH ROW: 指定该选项时,当前触发器为行触发器;否则为语句触发器。
  • WHEN <trigger_condition>: 设置执行触发器的条件,当条件表达式的值为逻辑真时,可以执行触发器;否则不执行该触发器。
  • trigger_body: 指定触发器触发时将要执行的语句块。
阅读全文