触发器概述
1.触发器的基本概念
数据库触发器是一种在基表做UPDATE、INSERT或DELETE操作时被修自动执行的内嵌过程,用来防止对数据进行的不正确或不一致的修改。
通过触发器可以把事务规则从应用程序代码移到数据库中从而确保事务规则被遵守,并能显著提高性能,保证安全,并实现过程完整性。
其中,触发器的类型有:
(1)DDL(Data Definition Language)数据定义语言触发器
(2)DML(Data Manipulation Language)数据操作语言触发器
2.使用触发器的优点
(1)强制比CHCEK约束更复杂的数据完整性
在CHECK约束中不允许引用其他表中的列来完成检查工作,而触发器则可以引用其他表中的列来完成数据完整性的约束,如进出货过程中的定购量是必须小于存货量的:
进出货.存货量>定购量;
(2)使用自定义的错误信息
用户有时需要在数据完整性遭到破坏或其他情况下,发出预先自定义好的错误信息或动态自定义的错误信息;
(3)实现数据库中多张表的级联修改
如多张表中存在同一个字段,在其中一种表中该字段被修改时,可以在其余表中定位该字段并进行修改;
(4)比较数据库修改前后的状态
访问由INSERT、UPDATE或DELETE语句引起的数据变化的前后状态,用户可在触发器中引用由于修改所影响的记录行;
(5)维护非规范化数据
非规范数据通常是指在表中的派生的、冗余的数据值,维护非规范化数据可通过触发器方式来实现。
触发器的创建
1.触发器的创建
触发器的创建语句如下
CREATE TRIGGER [owner.] trigger_name
ON [owner.]{table|view}
{FOR|AFTER|INSTEAD OF}
{[INSERT],[UPDATE],[DELETE]}
[WITH ENCRYPTION]
AS
IF UPDATE(column_name)
[{and|or}UPDATE(column_name)…]
sql_statesments
•AFTER触发器:在触发SQL语句中指定的所有操作(引用级联操作和约束检查)成功完成后,才执行此触发器;
•INSTEAD OF触发器:在操作进行之前执行此触发器,并且不再去执行原来的SQL操作,而是去运行触发器本身的SQL语句;
•UPDATE:指定对表内某些字段作增加或修改操作时,触发器才起作用;
•sql_statesments:定义触发器被执行之后,将执行的数据库操作;
2.Deleted表和Inserted表
SQLServer为每个触发器都创建了两个专用表:INSERTED表和DELETED表。这两个逻辑表,由系统来维护,用户不能对它们进行修改。它们存放在内存中而不是数据库中。这两个表的结构总是与被该触发器作用的表的结构相同。触发器执行完成后,与该触发器相关的这两个表也被删除。
(1)Deleted表:存放由于执行DELETE或UPDATE语句而要从表中删除的所有行。在执行DELETE或UPDATE操作时,被删除的行从激活触发器的表中被移动到DELETED表,这两个表不会有共同的行。
(2)Insert表:存放由于执行INSERT或UPDATE语句而要向表中插入的所有行。在执行INSERT或UPDATE操作时,新的行同时添加到激活触发器的表和INSERTD表中,INSERTD表的内容是激活触发器的表中新行的备份
3.UPDATE:
通过定义
IF UPDATE <COLUMN_NAME>
实现当特定列被更新时触发触发器
不论该更新影响表中的多少行
若用户需要实现多个特定列中的任意一列被更新时触发触发器,可以通过在触发器定义中使用多个IF UPDATE <COLUMN_NAME>语句来实现。
4.查看触发器信息
和存储过程一样,触发器在创建后,系统把触发器的名称保存在系统表sysobjects中,并把创建的源代码保存在系统表syscomments中,名称保存在系统表sysobjects中,并把创建的源代码保存在系统表syscomments中。
(1)使用系统存储过程
EXEC sp_helptext <triggername>
可以通过指定WITH ENCRYPTION来对触发器的定义文本信息进行加密,加密后的触发器无法用sp_helptext查看相关信息。
还可使用系统存储过程sp_helptrigger来查看某特定表上存在的触发器的某些信息
EXEC sp_helptrigger <tablename>
(2)使用系统表
例:用系统表sysobjects查看数据库pubs上的所有触发器的相关信息
USE pubs
SELECT name from sysobjects
WHERE type='TR'
go
触发器的使用、修改和删除
1.使用触发器强制数据完整性
约束和触发器都可以用来实施数据完整性,但两者各有优势。
在以下情境中,应考虑优先使用触发器:
•除非REFERENCES子句定义了级联引用操作,否则FOREIGN KEY约束只能以与另一列中的值完全匹配的值来验证列值;
•应用程序要求根据另一表中的列验证列值;
•应用程序要求使用自定义信息和较为复杂的错误处理。
2.使用触发器强制业务规则
触发器在强制数据完整性之外,还可强制实施对CHECK约束来说过于复杂的业务规则,包括对其他表中行的状态进行检查。
3.修改触发器
修改触发器的语句如下:
ALTER TRIGGER[owner.]trigge_name
ON [owner.]{table|view}
{FOR|AFTER|INSTEADOF}
{INSERT,UPDATE,DELETE}
[WITH ENCRYPTION]
AS
IF UPDATE(column_name)
[{and|or} UPDATE(column_name)…]
sql_statesments
4.删除触发器
删除触发器的语句如下:
DROP TRIGGER[owner.]trigge_name
5.禁止或启用触发器
当一个触发器被禁止后,它仍然存在于触发器表上,只是触发器的动作不再执行,直到该它被重新启用。启用/禁止命令如下:
ALTER TABLE table_name
{ENABLE| DISABLE} TRIGGER
{ALL|trigger_name[,…n]}

