一、什么是触发器
前面已经介绍过存储过程,触发器和存储过程比较类似,它由PL/SQL编写并存储在数据库中,它可以调用存储过程,但触发器本身的调用和存储过程调用却是不一样的。存储过程由用户、应用程序、触发器或其他过程调用。但触发器只能由数据库的特定事件来触发,所谓的特定事件主要包括如下几种类型的事件。
1)用户在指定的表或视图中做DML操作,主要包括如下几种:
■ INSERT操作,在特定的表或视图中增加数据。
■ UPDATE操作,对特定的表或视图修改数据。
■ DELETE操作,删除特定表或视图的数据。
2)用户做DDL操作,主要包括如下几种:
■ CREATE操作,创建对象。
■ ALTER操作,修改对象。
■ DROP操作,删除对象。
3)数据库事件,主要包括如下几种:
■ LOGON/LOGOFF,用户的登录或注销。
■ STARTUP/SHUTDOWN,数据库的打开或关闭。
■ ERRORS,特定的错误消息等。
在以上事件中的一种或多种发生时就能使触发器运行。
二、触发器的作用
可以根据不同的事件进行触发器调用,它有着更加精细的控制能力,这种特性可以帮助开发人员完成很多普通PL/SQL语句完成不了的功能。下面介绍触发器的主要作用。
■自动生成自增长字段。例如,为了不让数据重复,一般需要设置一个主键,该主键的内容不需要用户来控制,由Oracle系统在后台控制,而且该主键的值必须唯一。在表中插入一条新的数据之前,需首先得到该主键的最大值,然后连同要插入的数据一起插入表中,从而避免数据的重复。
■ 执行更复杂的业务逻辑。普通的操作方式只能完成固定的数据变动,而使用触发器则在完成的基础功能上做额外的操作,以达到完成特殊业务的目的。
■ 防止无意义的数据操作。利用触发器可以把符合某些条件的数据加以限制,使其不能变动。
■ 提供审计。利用触发器可以跟踪对数据库的操作。也可以在指定的表或视图记录改变时,利用触发器把数据变动日志记录下来。
■ 允许或限制修改某些表。利用触发器可以限制表的变动。
■ 实现完整性规则。当一个表中的数据有变动时可以利用触发器修改这些变动数据在其他表中的关联数据(正常情况下可以利用外键进行限制)。
■ 保证数据的同步复制。
注意:建议开发人员只在必要时使用触发器,因为触发器可能造成比较复杂的相关依赖性,这种情况在大型的数据库中可能会带来麻烦。例如,某个触发器的触发很可能造成多个触发器的连锁触发,一旦这种连锁触发超过32个就会出现异常。
三、触发器类型
触发器可分为5种类型,具体内容如下:
■数据操纵语言(DML)触发器。此种类型的触发器定义到表上,当对表执行INSERT、UPDATE、DELETE操作时可以激发该类型的触发器。利用该类触发器可以复制、检查、替换某种符合指定条件的数据。按照触发级别可以分为两种方式,第一种为行级触发器,此种类型表示每条记录修改时都会激发该触发器;第二种为语句级触发器,此种类型表示当SQL语句执行时会激发该触发器,它和修改多少条记录没有关系。如果以数据的更改事件为准,则分为BEFORE和AFTER两种类型。
■ 数据定义语言(DDL)触发器。当定义CREATE、ALTER、DROP模式对象时会触发相关的触发器,在Oracle中可以简单地理解为一个用户就有一个和它同名的模式,利用它可以使得某些表不能被修改或删除。
■ 复合触发器。此种类型的触发器是Oracle 11g的新特性,它相当于在一个触发器中包含了4种类型的触发器,其中包含了BEFORE类型的语句级、BEFORE类型的行级、AFTER类型的语句级以及AFTER类型的行级触发器。这种把所有触发器都放到一个代码块中的做法使得变量的传递变得更加方便。
■ INSTEAD OF触发器。此种类型的触发器通常作用在视图上。对具有多个源表的视图做DML操作转换成对多个源表进行操作。
■ 用户和系统事件触发器。作用在数据库上由数据库事件激发的触发器,如登录和注销事件的触发器。利用它可以记录数据库的登录情况。
本小节简单介绍了触发器的类型,也有些机构把DML和DDL类型的触发器直接分为行触发器、语句触发器、BEFORE触发器、AFTER触发器。
四、触发器的语法
了解触发器的语法是使用它的第一步,它就像一个公式,能让我们迅速地创建出自己的触发器。
1)DML触发器的主要语法如下:
01 CREATE [ OR REPLACE ] TRIGGER [schema.] trigger
02 { BEFORE | AFTER | INSTEAD OF }
03 { DELETE | INSERT | UPDATE
04 [ OF column [, column ]... ]
05 }
06 [ OR { DELETE | INSERT | UPDATE
07 [ OF column [, column]... ]
08 }
09 ]...
10 {ON [ schema. ]table | [ schema. ] view }
11 [ FOR EACH ROW ]
12 [ FOLLOWS [ schema. ] trigger [, [ schema. ] trigger ]... ]
13 [ ENABLE | DISABLE ]
14 [ WHEN (condition) ]
15 trigger_body
【语法说明】
■ OR REPLACE:新建的触发器可以覆盖原有的同名触发器。
■ TRIGGER:创建触发器的关键字。
■ schema:触发器所属模式(可简单看成用户名),如果不加该项则表示该触发器属于自己。
■ BEFORE:触发器类型为前触发。
■ AFTER:触发器类型为后触发。
■ INSTEAD OF:表示触发器类型为替换类型。
■ DELETE | INSERT | UPDATE:表示触发的事件。
■ [ OF column [, column ]:触发条件具体到的某列。
■ 第6~9行表示可以追加多个条件。
■ ON [ schema. ]table | [ schema. ] view:该触发器作用的表或视图,INSTEAD OF类型可以作用在视图上。
■ FOR EACH ROW:表示行级触发器,省略该关键字则为语句级触发器。
■ FOLLOWS [ schema. ] trigger:触发器的执行顺序。
■ ENABLE | DISABLE:设置触发器是否可用。
■ WHEN (condition):触发该触发器的条件。
■ trigger_body:表示触发器的函数体。
2)DDL和数据库事件触发器语法如下:
01 CREATE [ OR REPLACE ] TRIGGER [schema.] trigger
02 { BEFORE | AFTER }
03 { ddl_event [OR ddl_event]...
04 | database_event [OR database_event]...
05 }
06 ON { [schema.] SCHEMA
07 | DATABASE
08 }
09 [ FOLLOWS [ schema. ] trigger [, [ schema. ] trigger ]... ]
10 [ ENABLE | DISABLE ]
11 [ WHEN (condition) ]
12 trigger_body
【语法说明】
■ OR REPLACE:新建的触发器可以覆盖原有的同名触发器。
■ TRIGGER:创建触发器的关键字。
■ schema:触发器所属模式,如果不加该项则表示该触发器属于自己。
■ BEFORE:触发器类型为前触发。
■ AFTER:触发器类型为后触发。
■ ddl_event [OR ddl_event]:DDL事件,用OR连接。
■ database_event[OR database_event]:数据库事件,用OR连接。
■ [schema.] SCHEMA | DATABASE:触发器可作用在模式上或数据库上。
■ FOLLOWS [ schema. ] trigger:触发器的执行顺序。
■ ENABLE | DISABLE:设置触发器是否可用。
■ WHEN (condition):触发该触发器的条件。
■ trigger_body:表示触发器的函数体。
下表列出了一部分DDL事件,这些事件都可以激发触发器。