触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程。触发器主要是通过事件进行触发被自动调用执行的。而存储过程可以通过存储过程的名称被调用。
Ø 什么是触发器
触发器对表进行插入、更新、删除的时候会自动执行的特殊存储过程。触发器一般用在check约束更加复杂的约束上面。触发器和普通的存储过程的区别是:触发器是当对某一个表进行操作。诸如:update、insert、delete这些操作的时候,系统会自动调用执行该表上对应的触发器。SQL Server 2005中触发器可以分为两类:DML触发器和DDL触发器,其中DDL触发器它们会影响多种数据定义语言语句而激发,这些语句有create、alter、drop语句。 一般使用的是DML触发器
DML触发器分为:
1、 after触发器(之后触发)
a、 insert触发器
b、 update触发器
c、 delete触发器
2、for触发器等同于after触发器
3、instead of 触发器 (之前触发)
其中after触发器要求只有执行某一操作insert、update、delete之后触发器才被触发,且只能定义在表上。而instead of触发器表示并不执行其定义的操作(insert、update、delete)而仅是执行触发器本身。既可以在表上定义instead of触发器,也可以在视图上定义。
触发器有两个特殊的表:插入表——instered表和删除表——deleted表(如果是oracle数据库对应new表和old表)。这两张是逻辑表也是虚表。有系统在内存中创建者两张表,不会存储在数据库中。而且两张表的都是只读的,只能读取数据而不能修改数据。这两张表的结果总是与被改触发器应用的表的结构相同。当触发器完成工作后,这两张表就会被删除。Inserted表的数据是插入或是修改后的数据,而deleted表的数据是更新前的或是删除的数据。
对表的操作 | Inserted逻辑表 | Deleted逻辑表 |
增加记录(insert) | 存放增加的记录 | 无 |
删除记录(delete) | 无 | 存放被删除的记录 |
修改记录(update) | 存放更新后的记录 | 存放更新前的记录 |
Update数据的时候就是先删除表记录,然后增加一条记录。这样在inserted和deleted表就都有update后的数据记录了。注意的是:触发器本身就是一个调用事务的存储过程,所以在触发器里面可以对修改数据进行一些特殊的检查。如果不满足可以利用事务回滚,撤销操作。接下来举个例子
假设有两个表:tab_1、tab_2 ,再假设两个表里都有“人员性别”这个字段
tab_1的数据例如: 张三```男```1978`````2002
tab_2的数据例如: 张三```男```销售科```科长
我要改tab_1中张三的性别为“女”的话,那么tab_2的性别也该改为“女”。因为是同一个人。
如果不用触发器的话,我们就要改完tab_1,再去改tab_2,使性别都变成女,于是这里可以用到触发器了,否则一个修改成功,另一个修改失败了数据会不同步。
原理是:当tab_1中某人的性别发生变更后,数据库自动将tab_2的性别进行同步修改,如果出现失败,事务回滚——两个都不修改。
触发器也可以这样应用:
1、当删除tab_1中的某人信息时,触发器一并删除该人的tab_2中的数据;
2、在tab_1中新插入一个人员时,触发器在tab_2中一并新增一条该人的数据。
===================================================================================
基本的语法规则是:
create trigger 触发器名称(你自己命名的) on 表 for 用途(delete|update|insert)
as
delete|update|insert语句
----------------------------------------------------------------------
例如:
create trigger tri_A on tab_1 FOR DELETE
AS
delete tab_2 from deleted where tab_2.id = deleted.id;
意思是:在tab_1表上,建立触发器(tri_A),用于删除该表的数据时触发一个事务,什么事务呢?——删除tab_2中的该编号人员的记录。
FOR INSERT、FOR UPDATE分别是建立用于“插入记录”、“更新数据”的触发器,例子里的FOR DELETE是用于触发“删除记录”的。
这里还要看清楚,那个delete语句中的表,是from deleted,还有,where子句的tab_2.id = deleted.id,不是tab_2.id = tab_1.id,deleted.id是指你刚删除的那条记录的id(而update、insert,都用inserted.id)
触发器的外面都有一个事务开始和回滚/提交(成功时提交,失败时回滚),如果用户自己在触发器内部使用事务的回滚需要再重新开始一个事务,否则事务不完整。
===================================================================================
好处:相对于外部程序、存储过程,触发器可以更快更高效的维护数据
坏处:触发器要用的恰到好处,一个大型应用里,触发器是在需要时才用。多了会使代码结构不清晰,给以后的维护带来不便。