为什么要使用触发器
触发器的主要作用就是其能够实现由主键和外所不保证的复杂的参照完整性和数据的一致性。除此之外触发器还有其它许多不同的功能
触发器定义
触发器实际上是一种特殊的存储的过程。触发器的主要功能是监视用户对数据的修改。如果针对一个数据表建了触发器,则 当数据表被修改(插入、更新或者删除)时,SQL Server便使触发器自动执行,以便对数据的修改采用一些适当的措施,从而保证数据的完整性和安全性。
触发器分类
After 触发器在触发操作(Insert、Update 或Delete)后和处理完任何约束后激发。可通过指定 After 或 for 关键字来请求 After 触发器。因为 For 关键字与 After 的效果相同,所以具有 For 关键字的触发器也归类为 After 触发器。
Instead Of 触发器代替触发动作进行激发,并在处理约束之前激发。
注意:对于每个触发操作(Update、Delete和Insert),每个表或视图只能有一个 Instead Of 触发器。而一个表对于每个触发操作可以有多个 After触发器。
Instead Of 触发器
INSTEAD OF触发器指定执行触发器而不是执行触发 的SQL 语句,从而替代触发语句的操作。
在表或视图上,每个 INSERT、UPDATE 或 DELETE 语句最多可以定义一个 INSTEAD OF 触发器。然而,可以在每个具有 INSTEAD OF 触发器的视图上定义视图。
Instead Of 触发器举例
Instead Of 触发器的主要优点是可以使不能更新的视图支持更新。包含多个基表的视图必须使用 Instead Of 触发器来支持引用表中数据的插入、更新和删除操作。Instead Of触发器的另一个优点是使您得以编写这样的逻辑代码:可以拒绝批处理中的某些部分同时允许批处理的其它部分成功。
Instead Of 触发器可以进行以下操作:
- 忽略批处理中的某些部分。
- 不处理批处理中的某些部分并记录有问题的行。
- 如果遇到错误情况则采取备用操作。
将此逻辑作为 Instead Of 触发器的一部分进行编码,可避免所有访问数据的应用程序必须重新执行该逻辑。在下列 Transact-SQL 语句序列中Instead Of触发器更新视图中的两个基表。另外,显示两种处理错误的方法:
忽略对 People 表的重复插入,并且插入的信息将记录在 PeopleRepeat 表中。
表Teacher的重复插入转变为 Update 语句,该语句将当前信息检索至 Teacher,而不会产生重复键侵犯。用Transact-SQL 语句创建两个基表、一个视图、一个记录错误表和视图上的 INSTEAD OF 触发器。下面的这些表将个人数据和业务数据分开并且是视图的基表:下面的视图使用某个人的两个表中的所有相关数据立报表:
Instead Of 触发器举例代码如下
--身份证表
Create Table People
(
PeopleID Int Primary Key,--身份证号
PeopleName Varchar(20) not null,--姓名
PeopleSex Char(2) Default(‘男‘),--性别
Constraint Check_Sex Check(PeopleSex in (‘男‘,‘女‘)),
)
--教师表
Create Table Teacher
(
TeacherID int Primary Key,--教师编号
PeopleID int References People(PeopleID),--身份证号
Salary Money,--工资
)
--记录重复身份证号
Create Table PeopleRepeat
(
PeopleID Int,--身份证号
PeopleName Varchar(20) not null,--姓名
PeopleSex Char(2) Default(‘男‘),--性别
OperateName Char(50),--操作员
OperateTime DateTime,--操作时间
)
--创建视图
Alter View View_Teacher As
Select P.PeopleID,PeopleName,PeopleSex,TeacherID,Salary
From People P Inner Join Teacher T
On P.PeopleID = T.PeopleID
--Instead Of 触发器在单独视图的多个基表中插入行。
--将对插入具有重复社会安全号的行的尝试记录在 PersonDuplicates 表中。
--将Teacher 中的重复行更改为更新语句。
If Exists (Select Name From Sysobjects
Where name = Ltrim(‘Trig_Insert_ViewTeacher‘) And type = ‘TR‘)
Drop Trigger Trig_Insert_ViewTeacher
Go
Create Trigger Trig_Insert_ViewTeacher ON View_Teacher
Instead Of Insert
As
Begin
Set Nocount On
-- 检查PeopleID是否重复,不重复则插入记录
If (Not Exists (Select P.PeopleID
From People P, Inserted I
Where P.PeopleID = I.PeopleID))
Insert Into People
Select PeopleID,PeopleName,PeopleSex
FROM inserted
Else
-- 记录重复插入的信息(错误处理方法一:忽略对 People 表的重复插入,并且插入的信息将记录在 PeopleRepeat 表中。)
Insert into PeopleRepeat
Select PeopleID,PeopleName,PeopleSex,Suser_Sname(),Getdate()
From Inserted
--检查是否存在TeacherID,如果不存在则插入记录
If (Not Exists (Select T.TeacherID
From Teacher T, inserted I
Where T.TeacherID = I.TeacherID))
Insert Into Teacher
Select TeacherID,PeopleID,Salary
From inserted
else
--如果重复了,则改为Upate,则不会出现重复插入的错误 即前面所讲的遇 到错误备用操作
--(错误处理方法二:表Teacher的重复插入转变为 Update 语句,该语句将当前信息检索至 Teacher,而不会产生重复键侵犯。)
Update Teacher
Set TeacherID = I.TeacherID,
Salary = I.Salary
From Teacher T, Inserted I
Where T.PeopleID = I.PeopleID
End
Go
Insert Into View_Teacher
Values(0001,‘小敏‘,‘女‘,2,5000)
Select * From People
Select * From Teacher
Select * From PeopleRepeat
Select * From View_Teacher
总结要点
- Instead Of 触发器并不(Insert,Update,Delete)操作,这些触发器在执行任何约束前执行,因此可执行预处理以补充约束操作
- Instead Of 触发器的主要优点是可以使不能更新的视图支持更新
- 在含有用 DELETE 或 UPDATE 操作定义的外键的表上,不能定义 INSTEAD OF DELETE 和 INSTEAD OF UPDATE 触发器