第八章 触发器
触发器的基本概述
在SQLServer2005中,存储过程和触发器都是SQL语句和流程控制语句的集合,就本质而言,触发器也是一种存储过程,它是一种在基本表被修改时自动执行的内嵌过程,主要通过事件进行触发而被执行,而存储过程可以通过存储过程名字而被直接调用,当对某一张表进行如UPDATE,INSERT,DELETE这些操作时,SQLServer就会自动执行触发器所定义的SQL语句.从而确保对数据的处理符合由这些SQL语句所定义的规则.触发器的主要作用是其能实现由主键和外键所不能保证的复杂的参照完整性和数据的一致性.
优点:
由于在触发器中可以包含复杂的处理逻辑,因此,应该将触发器用来保持低级的数据的完整性,而不是返回大量的查询结果.使用触发器主要可以实现以下操作:
1.强制比CHECK约束更复杂的数据的完整性
在数据库中实现数据的完整性的约束,可以使用CHECK约束或触发器来实现.但是在CHECK约束中不允许引用其他表中的列来完成检查工作,而触发器可以引用其他表中的列来完成数据的完整性的约束.
2.使用自定义的错误提示信息
用户有时需要在数据的完整性遭到破坏或其他情况下,使用预先自定义好的错误提示信息或动态自定义的错误提示信息,通过使用触发器用户可以捕获破坏数据的完整性的操作,并返回自定义的错误提示信息.
3.实现数据库中多张表的级联修改
用户可以通过触发器对数据库中的相关表进行级联修改
4.比较数据库修改前后数据的状态
触发器提供了访问有INSERT,UPDATE,DELETE语句引起的数据前后状态变化的能力.因此用户就可以在触发器中引用由于修改所影响的记录行.
5.维护规范化数据
用户可以使用触发器来保证非规范数据库中的低级数据的完整性,维护非规范化数据与表的级联是不同的,表的级联指的是不同表之间的主外键关系,维护表的级联可以通过设置表的主键与外键的关系来实现,而非规范数据通常是指在表中派生的,冗余的数据值,维护非规范化数据应该通过使用触发器来实现.
触发器的创建
语法:
CREATETRIGGER触发器名称
ON表名
FORINSERT或UPDATE或DELETE
AS
BEGIN
要执行的操作
END
示例:
CREATETABLEUSERS(
USERIDINTIDENTITYPRIMARYKEY,
USERNAMENVARCHAR(20)NOTNULL,
USERPWDNVARCHAR(20)NOTNULL
)
CREATETABLEUSERTYPE(
TYPEIDINTIDENTITYPRIMARYKEY,
TYPENAMENVARCHAR(20)NOTNULL,
USERIDINTNOTNULL
)
--INSERT触发器
CREATETRIGGERADDUSERTYPE
ONUSERS
FORINSERT
AS
BEGIN
DECLARE@USERIDINT
SET@USERID=@@IDENTITY
INSERTINTOUSERTYPEVALUES('家人',@USERID)
INSERTINTOUSERTYPEVALUES('同学',@USERID)
INSERTINTOUSERTYPEVALUES('同事',@USERID)
INSERTINTOUSERTYPEVALUES('朋友',@USERID)
END
INSERTINTOUSERSVALUES('zhanghaidang','wdpc');
可以看到USERTYPE表插入了四条记录
--DELETE触发器
CREATETRIGGERDELUSERTYPE
ONUSERS
FORDELETE
AS
BEGIN
IF@@ROWCOUNT=0
RETURN
ELSE
BEGIN
DECLARE@USERIDINT
--注意,这里是DELETED,后面多了一个D,下面专门介绍DELETED
--SELECT@USERID=USERIDFROMDELETED
--DELETEFROMUSERTYPEWHEREUSERID=@USERID
DELETEFROMUSERTYPEWHEREUSERIDin(SELECTUSERIDFROMDELETED)
END
END
DELETEFROMUSERSWHEREUSERID=4
触发器有2个专用表
一个是Inserted,其中的数据记录的是更新后的数据
一个是Deleted,其中的数据记录的是更新前的数据
当对某张表建立触发器后,分3种情况讨论
1.插入操作(Insert)
Inserted表有数据,Deleted表无数据
2.删除操作(Delete)
Inserted表无数据,Deleted表有数据
3.更新操作(Update)
Inserted表有数据(新数据),Deleted表有数据(旧数据)
简单来说:删除的数据保存在deleted表中插入的数据保存在inserted表中
--UPDATE触发器
CREATETABLEUSERRECORD(
RECORDIDINTIDENTITYPRIMARYKEY,
RECORDNAMENVARCHAR(20)NOTNULL,
RECORDPHONENVARCHAR(20)NOTNULL,
TYPEIDINT,
USERNAMENVARCHAR(20)NOTNULL
)
CREATETRIGGERUPDATEUSERS
ONUSERS
FORUPDATE
AS
BEGIN
DECLARE@OLDUSERNAMENVARCHAR(20),@NEWUSERNAMENVARCHAR(20)
SELECT@OLDUSERNAME=USERNAMEFROMDELETED
SELECT@NEWUSERNAME=USERNAMEFROMINSERTED
UPDATEUSERRECORDSETUSERNAME=@NEWUSERNAMEWHEREUSERNAME=@OLDUSERNAME
END
UPDATEUSERSSETUSERNAME='wujinghui'WHEREUSERID=4