触发器- - JavaEye技术网站

触发器是一种特殊的存储过程,在使用触发器之前可以与存储过程进行比较,触发器主要是通过事件进行触发而被执行的,而存储过程可以通过存储过程名称而被直接调用。

触发器主要优点如下:

触发器是自动的:当对表中的数据作了任何修改之后立即被xx,触发器与数据库中的表紧密相关,比如当对表执行INSERT、UPDATE或DELETE操作时,触发器就会自动执行。

触发器可以对数据库中的表进行嵌套的触发,一个触发器执行启动另一个触发器的操作,这样的嵌套可以达到32层。

触发器可以强制限制,可以防止恶意或错误的 INSERT、UPDATE 以及 DELETE 操作,并强制执行比CHECK约束定义的限制更为复杂的其他限制,虽CHECK约束已经在表定义的时候建立好了,但触发器可以实现很多其它的约束限制,在约束所支持的功能无法满足应用程序的功能要求时,触发器的优点就会体现。

在SQL Server中,已经包括两大类触发器:DML 触发器和 DDL 触发器。 DDL触发器为SQL Server 2005中新增的。

当数据库中发生数据操作语言 (DML) 事件时将调用 DML 触发器。DML 事件包括在指定表或视图中修改数据的 INSERT 语句、UPDATE 语句或 DELETE 语句。DML 触发器可以查询其他表,还可以包含复杂的 Transact-SQL 语句。将触发器和触发它的语句作为可在触发器内回滚的单个事务对待。如果检测到错误,则整个事务即自动回滚。

DDL 触发器是一种特殊的触发器,它在响应数据定义语言 (DDL) 语句时触发。它们可以用于在数据库中执行管理任务,例如,审核以及规范数据库操作。像常规触发器一样,DDL 触发器将激发存储过程以响应事件。但与 DML 触发器不同的是,它们不会为响应针对表或视图的 UPDATE、INSERT 或 DELETE 语句而激发。相反,它们会为响应多种数据定义语言 (DDL) 语句而激发。这些语句主要是以 CREATE、ALTER 和 DROP 开头的语句。DDL 触发器可用于管理任务,例如审核和控制数据库操作。

insert? 触发器

--当person表 新增 一条person记录时 
--将 该记录的主键personName 保存在changeTable表中
USE TestDB
IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'personInsert' AND type = 'TR')
   DROP TRIGGER personInsert
GO
CREATE TRIGGER personInsert
ON person
FOR INSERT
AS

   INSERT INTO TestDB.dbo.changeTable
  (changeTableName, changeType, changeTablePK, changeTablePKValue)
  SELECT 'person','INSERT','personName',personName FROM INSERTED
GO

?delete 触发器

--当person表 删除 一条person记录时 
--将 该记录的主键personName 保存在changeTable表中

USE TestDB
IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'personDelete' AND type = 'TR')
   DROP TRIGGER personDelete
GO
CREATE TRIGGER personUpdate
ON person
FOR DELETE
AS

   INSERT INTO TestDB.dbo.changeTable
  (changeTableName, changeType, changeTablePK, changeTablePKValue)
  SELECT 'person','DELETE','personName',personName FROM DELETED
GO


?update 触发器

--当person表 修改 一条person记录时 
--将 该记录的主键personName 保存在changeTable表中

USE TestDB
IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'personUpdate' AND type = 'TR')
   DROP TRIGGER personUpdate
GO
CREATE TRIGGER personUpdate
ON person
FOR UPDATE
AS

   INSERT INTO TestDB.dbo.changeTable
  (changeTableName, changeType, changeTablePK, changeTablePKValue)
  SELECT 'person','UPDATE','personName',personName FROM INSERTED
GO

?oracle中触发器的写法

触发器代码类似存储过程,以PL/SQL脚本编写。下面是一个触发器的示例:

新建员工工资表salary

create table SALARY
(
  EMPLOYEE_ID NUMBER, --员工ID
 MONTH       VARCHAR2(6), --工资月份
 AMOUNT      NUMBER --工资金额
)

创建与salary关联的触发器salary_trg_rai

1   Create or replace trigger salary_trg_rai

2   After insert on salary

3   For each row

4     declare

5   Begin

6     Dbms_output.put_line(‘员工ID:’ || :new.employee_id);

7     Dbms_output.put_line(‘工资月份:’ || :new.month);

8     Dbms_output.put_line(‘工资:’ || :new.amount);

9     Dbms_output.put_line(‘触发器已被执行’);

10   End;

打开一个SQL Window窗口(使用PL/SQL Developer工具),或在sqlplus中输入:

Insert into salary(employee_id, month, amount) values(1, ‘200606’, 10000);

执行后可以在sqlplus中,或在SQL Window窗口的Output中见到

员工ID:1

工资月份:200606

工资:10000

触发器已执行

?在代码的{dy}行,定义了数据库对象的类型是trigger,定义触发器的名称是salary_trg_rai
第二行说明了这是一个after触发器,在DML操作实施之后执行。紧接着的insert说明了这是一个针对insert操作的触发器,每个对该表进行的insert操作都会执行这个触发器。

第三行说明了这是一个针对行级的触发器,当插入的记录有n条时,在每一条插入操作时都会执行该触发器,总共执行n次。

Declare后面跟的是本地变量定义部分,如果没有本地变量定义,此部分可以为空

Begin和end括起来的代码,是触发器的执行部分,一般会对插入记录进行一致性检查,在本例中打印了插入的记录和“触发器已执行”。

其中:new对象表示了插入的记录,可以通过:new.column_name来引用记录的每个字段值

oracle中的语法

CREATE OR REPLACE TRIGGER trigger_name

<before | after | instead of> <insert | update | delete> ON table_name

[FOR EACH ROW]

WHEN (condition)

DECLARE

BEGIN

       --触发器代码

END;

?

Trigger_name是触发器的名称。<before | after | instead of>可以选择before或者afterinstead ofBefore表示在DML语句实施前执行触发器,而after表示在在dml语句实施之后执行触发器,instead of触发器用在对视图的更新上。<insert | update | delete>可以选择一个或多个DML语句,如果选择多个,则用or分开,如:insert or updateTable_name是触发器关联的表名。

[FOR EACH ROW]为可选项,如果注明了FOR EACH ROW,则说明了该触发器是一个行级的触发器,DML语句处理每条记录都会执行触发器;否则是一个语句级的触发器,每个DML语句触发一次。

WHEN后跟的condition是触发器的响应条件,只对行级触发器有效,当操作的记录满足condition时,触发器才被执行,否则不执行。Condition中可以通过new对象和old对象(注意区别于前面的:new:old,在代码中引用需要加上冒号)来引用操作的记录。

?

触发器代码可以包括三种类型:未涉及数据库事务代码,涉及关联表(上文语法中的table_name)数据库事务代码,涉及除关联表之外数据库事务代码。其中{dy}种类型代码只对数据进行简单运算和判断,没有DML语句,这种类型代码可以在所有的触发器中执行。第二种类型代码涉及到对关联表的数据操作,比如查询关联表的总记录数或者往关联表中插入一条记录,该类型代码只能在语句级触发器中使用,如果在行级触发器中使用,将会报ORA-04091错误。第三种类型代码涉及到除关联表之外的数据库事务,这种代码可以在所有触发器中使用。

从触发器的功能上来看,可以分成3类:

l???????? 重写列(xx于before触发器)

l???????? 采取行动(任何触发器)

l???????? 拒绝事务(任何触发器)

“重写列”用于对表字段的校验,当插入值为空或者插入值不符合要求,则触发器用缺省值或另外的值代替,在多数情况下与字段的default属性相同。这种功能只能在行级before触发器中执行。“采取行动”针对当前事务的特点,对相关表进行操作,比如根据当前表插入的记录更新其他表,银行中的总帐和分户帐间的总分关系就可以通过这种触发器功能来维护。“拒绝事务”用在对数据的合法性检验上,当更新的数据不满足表或系统的一致性要求,则通过抛出异常的方式拒绝事务,在其上层的代码可以捕获这个异常并进行相应操作。

郑重声明:资讯 【触发器- - JavaEye技术网站】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——