触发器
触发器是一种特殊类型的存储过程,它不同前面介绍过的存储过程。触发器主要是通过事件进行触发而被执行的,而存储过程可以通过存储过程名称而被直接调用。触发器是一个功能强大的工具,它使每个站点可以在有数据修改时自动强制执行其业务规则。触发器可以用于SQL Server约束、默认值和规则的完整性检查。
当往某一个表格中插入记录、修改记录或者删除记录时,SQL Server就会自动执行触发器所定义的SQL语句,从而确保对数据的处理必须符合由这些SQL语句所定义的规则。在触发器中可以查询其他表格或者包括复杂的SQL语句。触发器和引起触发器执行的SQL语句被当作一次事务处理,如果这次事务未获得成功,SQL Server会自动返回该事务执行前的状态。和CHECK约束相比较,触发器可以强制实现更加复杂的数据完整性,而且可以参考其他表的字段。它的主要优点如下:
(1)触发器是自动的。当对表中的数据作了任何修改(比如手工输入或者应用程序采取的操作)之后立即被xx。
(2)触发器可以通过数据库中的相关表进行层叠更改。如,可以在titles表的title-id列上写入一个删除触发器,以使其他表中的各匹配行采取删除操作。该触发器用title-id列作为惟一键,在titleauthor、sales及roysched表中对各匹配行进行定位。
(3)触发器可以强制限制。这些限制比用CHECK约束所定义的更复杂。与CHECK约束不同的是,触发器可以引用其它表中的列。例如,触发器可以回滚试图对价格低于10美元的书(存储在title表中)应用折扣(存储在discounts表中)的更新。
一、创建触发器
在SQL Server中,可以使用企业管理器或者Transact-SQL语句来创建触发器。在创建触发器之前应该考虑以下几个问题:
(1)CREATE TRIGGER语句必须是批处理中的{dy}个语句。将该批处理中随后的其它所有语句解释为CREATE TRIGGER语句定义的一部分。
(2)创建触发器的权限默认分配给表的所有者,且不能将该权限转给其他用户。
(3)触发器为数据库的对象,其名称必须遵循标识符的命名规则。
(4)虽然触发器可以引用当前数据库以外的对象,但只能在当前数据库中创建触发器。
(5)虽然不能在临时表或系统表上创建触发器,但是触发器可以引用临时表。不应引用系统表,而应使用信息架构视图。有关更多信息,请参见信息架构视图。
(6)在含有用DELETE或UPDATE操作定义的外键的表中,不能定义INSTEAD OF和INSTEAD OF UPDATE触发器。
(7)虽然TRUNCATE TABLE语句类似于没有WHERE子名(用于删除行)的DELETE语句,但它并不会引发DELETE触发器,因为TRUNCATE TABLE语句没有记录。
(8)WRITETEXT语句不会引发INSERT或UPDATE触发器。
(9)当创建一个触发器时必须指定:名称;在其上定义触发器的表;触发器将何时激发;xx触发器的数据修改语句,有效选项为INSERT、UPDATE或DELETE,多个数据修改语句可xx同一个触发器,如,触发器可由INSERT或UPDATE语句xx;执行触发器操作的编程语句。
1.使用企业管理器创建触发器
在企业管理器中,展开指定的服务器和数据库项,然后展开其上创建触发器的表所在的数据库,右击该表,选择“所有任务--管理触发器”,在名称文本框中选择新建,输入触发器文本,单击“检查语法”,单击“应用--确定”即可。
2.使用CREATE TRIGGER命令创建触发器
使用CREATE TRIGGER命令可以创建触发器,其中需要指定定义触发器的基表、触发器执行的事件和触发器的所有指令。创建触发器的过程类似于创建存储过程,其语法形式如下:
CREATE TRIGGER trigger_name
ON {table | view} [WITH ENCRYPTION]
{
{{FOR | AFTER | INSTEAD OF}{[DELETE][,][INSERT][,][UPDATE]}
[WITH APPEND]
[NOT FOR REPLICATION]
AS
[{IF UPDATE(column)
[{AND | OR}UPDATE(column)]
[,..n]
| IF (COLUMNS_UPDATED(){bitwise_operator}updated_bitmask)
{comparison_operator}column_bitmask[,..n]
}]
sql_statement[,..n]
}
}
其中,各参数的说明如下:
-
trigger_name:用于指定触发器的名称。其名称在当前数据库中必须是{wy}的。
-
Table | View:用于指定在其上执行触发器的表或视图,有时称为触发器表或触发器视图。
-
WITH ENCRYPTION:用于加密syscomments表中包含CREATE TRIGGER语句文本的条目。使用此选项可以防止将触发器作为系统复制的一部分发布。
-
AFTER:用于指定触发器只有在触发SQL语句中指定的所有操作都已成功执行后才激发。所有的引用级联操作和约束检查也必须成功完成后,才能执行此触发器。如果仅指定FOR关键字,则AFTER是默认设置。注意该类型触发器仅能在表上创建,而不能在视图上定义该触发器。
-
INSTEAD OF:用于规定执行的是触发器而不是执行触发SQL语句,从而用触发器替代触发语句的操作。在表或视图上,每个INSERT、UPDATE或DELETE语句最多可以定义一个INSTEAD OF触发器。然而,可以在每个具有INSTEAD OF触发器的视图上定义视图。INSTEAD OF触发器不能在WITH CHECK OPTION的可更新视图上定义。如果向指定的WITH CHECK OPTION选项的可更新视图添加INSTEAD OF触发器,系统将产生一个错误。用户必须用ALTER VIEW删除该选项后才能定义INSTEAD OF触发器。
-
{[DELETE][,][INSERT][,][UPDATE]}:用于指定在表或视图上执行哪些数据修改语句时将xx触发器的关键字。必须至少指定一个选项。在触发器定义中允许使用以任何的顺序组合这些关键字。如果指定的选项多于一个,需要用逗号分隔。
-
WITH APPEND:用于指定应该添加现有类型的其他触发器。只有当兼容级别()是65或更低时,才需要使用该可选子名。如果兼容级别是70或更高,则不必使用该子名,。
-
NOT FOR REPLICATION:表示当复制进程更改触发器所涉及的表时,不应执行该触发器。
-
AS:触发器要执行的操作。
-
sql_statement:触发器的条件和操作。触发器条件指定其他准则,以确定DELETE、INSERT或UPDATE语句是否导致执行触发器操作。
-
IF UPDATE(column):用于测试在指定的列上进行的INSERT或UPDATE操作,不能用于DELETE操作。可以指定多列。因为在ON子句中指定了表名,所以在IF UPDATE子句中的列名前不要包含表名。若要测试在多个列上进行的INSERT或UPDATE操作,请在{dy}个操作后指定单独的UPDATE(column)子句。在INSERT操作中,IF UPDATE高尔夫球返回TRUE值,因为这些列插入了显式值或隐性值(NULL)。
-
IF (COLUMNS_UPDATED()):用于测试是否插入或更新了所涉及的列,仅用于INSERT或UPDATE触发器中。
-
bitwise_operator:用于比较运算的位逻辑运算符。
-
updated_bitmask:整型位掩码,表示实际更新或插入的列。如,表t1包含列C1,C2,C3,C4和C5。假定表t1上有UPDATE触发器,若要检查列C2、C3和C4是否都已更新,则指定值14(01110);若要检查是否只有列C2已更新,则指定值2(00010)。
-
comparison_operator:是比较运算符。使用等号(=)检查updated_bitmask中指定的所有列是否都实际进行了更新。使用大于号(>)检查updated_bitmask中指定的任一列或某些列是否已更新。
-
column_bitmask:是要检查列的整型位掩码,用于检查是否已更新或插入了这些列。
当创建触发器时,如果使用了相同名称的触发器,后建立的触发器将会覆盖前面创建的触发器。用户不能在系统表上创建用户自定义的触发器。
例:创建一个触发器,在titles表上创建一个插入、更新类型的触发器。
程序如下:
USE pubs
IF EXISTS(SELECT name FROM sysobjects WHERE name='reminder' AND type='TR')
DROP TRIGGER reminder
GO
CREATE TRIGGER reminder
ON titles
FOR INSERT,UPDATE
AS sql_statements
GO
注意:有两个表应知道,deleted表存储delete和update所影响的行的副本,inserted表存储insert和update所影响的行的副本。
二、查看、修改和删除触发器
1.查看触发器
如果要显示作用于表上的触发器究竟对表有哪些操作,必须查看触发器信息。在SQL Server中,有多种方法可以查看触发器信息,其中常用的有两种:
(1)使用企业管理器查看触发器信息。
(2)使用系统存储过程查看触发器。
系统存储过程sp_help、sp_helptext和sp_depends分别提供有关触发器的不同信息。其具体用途和语法形式如下。
-
sp_help:用于查看触发器的一般信息,包括名称、属性、类型和创建时间。
sp_help '触发器名称'
-
sp_helptext:用于查看触发器的正文信息。
sp_helptext '触发器名称'
-
sp_depends:用于查看指定触发器所引用的表或者指定的表涉及到的所有触发器。
sp_depends '触发器名称'
sp_depends '表名'