触发器(trigger)

触发器是表上的程序,主要提供数据添加、修改与删除后的程序处理方法,可以用来检查数据及进行数据更新,也可以分担一些前端应用程序撰写的逻辑规则。
触发器英文名为trigger,也就是板机的意思,与枪支的操作原理类似,只有扣动板机,子弹才会飞出。将该词用在SQL SERVER环境中,表示当表发生了insert 、update、delete操作之后,才会执行的t-SQL程序,这样的程序就叫触发器。

应用场景: 触发器可以查询其他表,而且可以包含复杂的SQL语句。它们主要用于强制复杂的业务规则或要求。
触发器的主要应用场合概括起来讲有以下几种:
    1.当向一张表中添加或删除记录时,需要在相关表中进行同步操作。比如,当为应用系统添加一个系统用户时,需要同时向权限表中添加该用户的缺省权限,此时就编写系统用户表的触发器在添加记录动作时触发。
    2.当表上某列数据的值与其他表中的数据有联系时。比如,当某客户进行欠款消费,可以在生成订单时通过设计触发器判断该客户的累计欠款是否超出了最大限度。
    3.当需要对某张表进行跟踪时。比如,当人事表中有人离职时,第一时间通知或更改相关表的值。

DML触发器的分类:SQL Server 2005的DML触发器分为两类:
        * After触发器:这类触发器是在记录已经改变完之后(after),才会被激活执行,它主要是用于记录变更后的处理或检查,一旦发现错误,也可以用Rollback Transaction语句来回滚本次的操作。
        * Instead Of触发器:这类触发器一般是用来取代原本的操作,在记录变更之前发生的,它并不去执行原来SQL语句里的操作(Insert、Update、Delete),而去执行触发器本身所定义的操作。

应用示例:alter --例一:以下是一个包含提醒电子邮件的触发器例子,如果订单表里记录有改动的的话(无论增加订单还是修改、删除订单),则给物流人员张三发送电子邮件:
CREATE TRIGGER 订单_Insert
ON 订单
AFTER INSERT, UPDATE, DELETE
AS
   EXEC master..xp_sendmail '张三', '订单有更改,请查询确定'
GO

--例二:在订单明细表里,折扣字段不能大于0.6,如果插入记录时,折扣大于0.6的话,回滚操作。
CREATE TRIGGER 订单明细_Insert
   ON  订单明细
   AFTER INSERT
AS
BEGIN
         if (Select 折扣 from inserted)>0.6
         begin
              raiserror('折扣不能大于0.6',16,1)
               Rollback Transaction --回滚事务。
         end
END
GO

/**//**//**//*在示例二中运用了两个方法,一个是前面说过的,在Inserted表里查询某个字段,还有一个是用Rollback Transaction来回滚操作。如果用下面的SQL语句来进行Insert操作的话,插入记录将会不成功。*/
INSERT INTO 订单明细(订单ID,产品ID,单价,数量,折扣) 
VALUES (11077,1,18,1,0.7) 
折扣为0.7, 插入记录不符合触发器里的约束,回滚操作,插入记录不成功。after应用范围:只能使用在表上。

应用示例2:Instead Of /**//*前面说过的11.5.3节中的例二,用After触发器并不是一个最好的方法,如果用Instead Of触发器,在判断折扣大于0.6时,就中止了更新操作,避免在修改数据之后再回滚操作,减少服务器负担。现将原来的触发器改为Instead Of触发器:*/
CREATE TRIGGER 订单明细_Insert
   ON  订单明细
   Instead Of INSERT
AS
BEGIN
    SET NOCOUNT ON;
    declare @订单ID int, @产品ID int,@单价 money, @数量 smallint,@折扣 real
    set @订单ID = (select 订单ID from inserted)
    set @产品ID = (select 产品ID from inserted)
    set @单价 = (select 单价 from inserted)
    set @数量 = (select 数量 from inserted)
    set @折扣 = (select 折扣 from inserted)
       if (@折扣)>0.6
          raiserror('折扣不能大于0.6',16,1)
       else
          INSERT INTO 订单明细 (订单ID,产品ID,单价,数量,折扣)
            VALUES (@订单ID,@产品ID,@单价,@数量,@折扣)
         END
GOInstead Of触发器的使用范围
Instead Of触发器可以同时在数据表和视图中使用,通常在以下几种情况下,建议使用Instead Of触发器:
* 数据库里的数据禁止修改:例如电信部门的通话记录是不能修改的,一旦修改,则通话费用的计数将不正确。在这个时候,就可以用Instead Of触发器来跳过Update修改记录的SQL语句。
* 有可能要回滚修改的SQL语句:如11.5.3节中的例二,用After触发器并不是一个最好的方法,如果用Instead Of触发器,在判断折扣大于0.6时,就中止了更新操作,避免在修改数据之后再回滚操作,减少服务器负担。
* 在视图中使用触发器:因为After触发器不能在视图中使用,如果想在视图中使用触发器,就只能用Instead Of触发器。
* 用自己的方式去修改数据:如不满意SQL直接的修改数据的方式,可用Instead Of触发器来控制数据的修改方式和流程。

资料引用:http://book.csdn.net/bookfiles/414/10041414953.shtml

应用技巧:
1、如何查看旧的记录?无论何时Insert 或者Update 语句影响一个或者多行时,inserted 临时表都有记录行。无论何时Delete 或者Update 语句影响一个或者多行时,deleted 临时表都有记录行。对于一个Update 语句,deleted 临时表有旧行,inserted 临时表有新行。
2、如何知道触发器修改了多少条记录?只要利用@@Rowcount这个系统变量就可以得知更新了多少条记录
3、如何知道插入记录的自动编号是多少?用@@IDENTITY可以获得刚插入记录的标识值
4、如何知道某个字段是否被修改?if update(列名)...
5、如何返回错误信息?Raiserror('除了折扣字段之外的其他字段信息不能修改',16,5)
   
更多引用: http://book.csdn.net/bookfiles/414/

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhou__zhou/archive/2007/07/19/1699128.aspx

posted @ 2009-07-03 14:42  周骏  阅读(1577)  评论(0编辑  收藏  举报