3.9 触发器

触发器是一种特殊的存储过程,它在创建后就存储在数据库中。触发器的特殊性在于它是建立在某个具体的表之上的,而且是自动激发执行的,如果用户在这个表上执行了某个DML操作(UPDATE、INSERT、DELETE),触发器就被激发执行。

触发器常用于自动完成一些数据库的维护工作。例如,触发器可以具有以下功能:

·可以对表自动进行复杂的安全性、完整性检查。

·可以在对表进行DML操作之前或之后进行其他处理。

·进行审计,可以对表上的操作进行跟踪。

·实现不同节点间数据库的同步更新。

3.9.1 触发器的使用

触发器是依附于某个具体的表的特殊存储过程,它在某个DML操作的激发下自动执行。在创建触发器时应该仔细考虑如它的相关信息。具体地说,应该考虑以下几个方面的问题:

1)触发器应该建立在哪个表之上。

2)触发器应该对什么样的DML操作进行响应。

3)触发器在指定的DML操作之前激发还是在之后激发。

4)对每次DML响应一次,还是对受DML操作影响的每一行数据都响应一次。

在确定了触发器的实现细节后,现在就可以创建触发器了。创建触发器的语法格式为:


CREATE[OR REPLACE]TRIGGER触发器

BEFORE|AFTER|INSTEAD OF

DELETE|INSERT|UPDATE[OF列名]

ON表名

[FOR EACH ROW[WHEN条件]]

BEGIN

PL/SQL语句;

END;


用户如果要在自己的模式中创建触发器,需要具有CREATE TRIGGER系统权限。如果希望能够在其他用户的模式中创建触发器,需要具有CREATE ANY TRIGGER系统权限。

在创建触发器的语法结构中,用方括号限定的部分是可选的,可以根据需要选用。创建触发器的命令是CREATE TRIGGER,根据指定的名字创建一个触发器。OR REPLACE子句的作用是如果已经存在同名的触发器,则删除它,并重新创建。

触发器可以是前激发的(BEFORE),也可以是后激发的(AFTER)。如果是前激发的,则触发器在DML语句执行之前激发。如果是后激发的,则触发器在DML语句执行之后激发。用BEFORE关键字创建的触发器是前激发的,用AFTER关键字创建的触发器是后激发的,这两个关键字只能使用其一。INSTEAD OF子句仅用于视图上的触发器。

触发器可以被任何DML命令激发,包括INSERT、DELETE和UPDATE。如果希望其中的一种、两种或三种命令能够激发该触发器,则可以指定它们之间的任意组合,两种不同命令之间用空格分开。如果指定了UPDATE命令,还可以进一步指定当表中的哪个列受到UPDATE命令的影响时激发该触发器。

当在指定的表上执行指定的DML命令时,将会激发触发器,触发器将对这样的操作进行必要的响应。触发器可能对每次单独的DML操作响应一次,也可能对每次DML操作所影响的每一行数据响应一次。如果对每次单独的DML操作响应一次,触发器执行的次数与受影响的行数无关,这样的触发器叫做语句级触发器。如果对受影响的每一行数据都响应一次,那么触发器执行的次数等于受影响的行数,这样的触发器叫做行触发器。

FOR EACH ROW子句的作用是指定创建的触发器为行触发器。如果没有这样的子句,则创建的触发器为语句级触发器。

由关键字BEGIN和END限定的部分是触发器的代码,也就是触发器被激发时所执行的代码。代码的编写方法与普通PL/SQL块的编写方法相同。在触发器中可以定义变量,也可以进行异常处理,如果发生异常,就执行相应的异常处理程序。

例如,下面创建的触发器是为了监视用户对表EMP中的数据所进行的删除操作。如果有这样的访问,则打印相应的信息。


CREATE OR REPLACE TRIGGER del_trg

BEFORE DELETE

ON emp

BEGIN

dbms_output.put_line('您正在对表emp进行删除操作');

END;


如果在表emp上进行DELETE操作,则激发这个触发器,例如:


SQL>DELETE FROM emp;

您正在对表emp进行删除操作

已删除14行。


从触发器的执行情况可以看出,无论用户通过DELETE命令删除0行、1行或者多行数据,这个触发器只对每次DELETE操作激发一次,所以这是一个典型的语句级触发器。

如果一个触发器不再使用,那么可以删除它。删除触发器的语法为:


DROP TRIGGER 触发器


例如,要删除刚才创建的触发器del_trg,使用的语句为:


SQL>DROP TRIGGER del_trg


触发器的创建者和数据库管理员可以使触发器失效。触发器失效后将暂时不起作用,直到再次使它有效。使触发器失效的命令格式为:


ALTER TRIGGER触发器DISABLE


触发器失效后只是暂时不起作用,它仍然存在于数据库中,使用命令可以使它再次起作用。使触发器再次有效的命令格式为:


ALTER TRIGGER触发器ENABLE


例如,下面的两条命令先使触发器del_trg失效,然后使其再次有效:


SQL>ALTER TRIGGER del_trg DISABLE

SQL>ALTER TRIGGER del_trg ENABLE