Oracle(十二)PL/SQL 触发器

来源:互联网 发布:淘宝为什么打压外贸店 编辑:程序博客网 时间:2024/06/05 23:53
    触发器是许多关系型数据库都提供的一种技术。在 ORACLE 系统中,触发器类似过程和函数,都有声明,执行和异常处理过程的 PL/SQL 块。
一、触发器类型
1、    触发器在数据库里以独立的对象存储,它与存储过程不同的是,存储过程通过其他程序来启动运行或直接启动运行,而触发器是由一个事件来启动运行。即触发器是当某个事件发生时自动的隐式运行。并且,触发器不能接收参数。所以运行触发器就叫触发或点火ORACLE 事件指的是对数据库的表进行的 INSERT、 UPDATE 及 DELETE 操作或对视图进行类似的操作。ORACLE 将触发器的功能扩展到了触发 ORACLE,如数据库的启动与关闭等。
1)DML 触发器
   ORACLE 可以在 DML 语句进行触发,可以在 DML 操作前或操作后进行触发,并且可以对每个行或语句操作上进行触发。
2)替代触发器
   由于在 ORACLE 里,不能直接对由两个以上的表建立的视图进行操作。所以给出了替代触发器。
3)系统触发器
   可以在 ORACLE 数据库系统的事件中进行触发,如 ORACLE 系统的启动或关闭等。

2、触发器组成:
    ·触发事件:即在何种情况下触发 TRIGGER;例如 insert、update、delete
    ·触发时间:即该 TIGGER 是在触发事件之前(before)还是之后(after)触发,也就是触发时间和该 trigger 的操作顺序。
    ·触发器本身:即该 trigger 被触发之后的目的和意图,正是触发器本身要做的事情。例如:pl/sql 块。
    ·触发频率:说明触发器内定义的动作被执行的次数。即语句级(statement)触发器和行级(row)触发器语句级触发器:是指当某触发事件发生时,该触发器只执行一次;行级触发器:是指当某触发事件发生时,对受到该操作影响的每一行数据触发器都单独执行一次。

3、创建触发器的一般语法是:

其中:
    before 和 after 指出触发器的触发时序分别为前触发和后触发方式,前触发是在执行触发时间之前触发当前所创建的触发器,后触发器是在执行出发时间之后触发当前所创建的触发器。
    for each row 选项说明触发器为行触发器。行触发器和语句触发器的区别表现在:行触发器要求当一个 DML 语句操作影响数据库的多行数据时,对于其中的每个数据行,只要他们符合触发约束套件,均激活一次触发器;而语句触发器将整个语句作为触发条件,当它符合约束条件时,激活一次触发器。当省略 for each row 选项时,before 和 after 触发器为语句触发器,而 instead of 触发器则为行触发器。
    when 子句说明触发约束条件。condition 为一个逻辑表达时,其中必须包含相关名称,而不能包含查询语句,也不能调用 pl/sql 函数。when 子句指定的触发约束条件只能用在 before 和 after 行触发器中,不能用在 instead of 行触发器和其他类型的触发器中。

每张表最多可建立 12 种类型的触发器:

4、触发器触发次序
1、执行 before 语句级触发器;
2、对与受语句影响的每一行:
   ·执行 before 行级触发器
   ·执行 DML 语句
   ·执行 after 行级触发器
3、执行 after 语句级触发器

5、创建 DML 触发器
    触发器名可以和表或过程有相同的名字,但在一个模式中触发器名不能相同。

6、触发器的限制
·create trigger 语句文本的字符长度不能超过 32 KB;
·触发器体内的 select 语句只能为 select ... into ... 结构,或者为定义游标所使用的 select 语句。
·触发器不能使用数据库事务控制语句 commit;rollback;savepoint语句
·当触发器所调用的过程或函数也不能使用数据库事务控制语句。

7、:NEW , :OLD 修饰符
当触发器被触发时,要使用被插入、更新或删除的记录中的列值,有时要使用操作前、操作后的值的时候,可以通过以下方式来实现
:NEW 修饰符访问操作完成后列的值
:OLD 修饰符访问操作完成前列的值

二、示例
例1:

进行更新操作,语句及显示结果如下:

例2:
(1)行级触发器: 每更新 employees 表中的一条记录, 都会导致触发器执行
     create or replace trigger employees_trigger
     after
     update on employees
     for each row
     begin
            dbms_output.put_line('修改了一条记录!');
     end;
     -- 显示结果如下

(2)语句级触发器: 一个 update / delete / insert 语句只使触发器执行一次
     create or replace trigger employees_trigger
     after
     update on employees
     begin
            dbms_output.put_line('修改了一条记录!');
     end;
     -- 显示结果如下:

例3:使用 :new, :old 修饰符

更新语句及显示结果如下:

注:如显示语句有误,显示具体错误信息的语句为:show error;

0 0