触发器(Trigger)(五)

转载 2007年09月20日 09:00:00

  建立触发器的SQL语句

回顾一下,在Management Studio新建一个触发器的时候,它在查询分析对话框给预设了一些SQL代码,这些代码其实上就是建立触发器的语法提示。现在来看一下完整的触发器语法代码:

CREATE TRIGGER <Schema_Name, sysname, Schema_Name>.<Trigger_Name, sysname, Trigger_Name>

   ON  <Schema_Name, sysname, Schema_Name>.<Table_Name, sysname, Table_Name>

   AFTER <Data_Modification_Statements, , INSERT,DELETE,UPDATE>

AS

BEGIN

         -- SET NOCOUNT ON added to prevent extra result sets from

         -- interfering with SELECT statements.

         SET NOCOUNT ON;

    -- Insert statements for trigger here

END

GO

用中文改了一下,以上代码就一目了然了:

CREATE TRIGGER 触发器名

   ON  数据表名或视图名

   AFTER INSERTDELETEUPDATE

AS

BEGIN

         --这里是要运行的SQL语句

END

GO

现在再对上面的代码进行进一步的说明:

l  CREATE TRIGGER 触发器名:这一句声明SQL语句是用来建立一个触发器。其中触发器名在所在的数据库里必须是唯一的。由于触发器是建立中数据表或视图中的,所以有很多人都以为只要是在不同的数据表中,触发器的名称就可以相同,其实触发器的全名(Server.Database.Owner.TriggerName)是必须唯一的,这与触发器在哪个数据表或视图无关。

l  ON 数据表名或视图名:这是指定触发器所在的数据表或视图,但是请注意,只有Instead Of触发器才能建立在视图上。并且,有设置为With Check Option的视图也不允许建立Instead Of触发器。

l  AFTER INSERT DELETE UPDATE:这是指定触发器的类型,是After Insert触发器,还是After Delete触发器,或者是After Update触发器。其中After可以用For来代取,它们的意思都是一样的,代表只有在数据表的操作都已正确完成后才会激活的触发器。INSERTDELETEUPDATE至少要指定一个,当然也可以指定多个,若指定多个时,必须用逗号来分开。其顺序可以任意摆放。

l  With EncryptionWith Encryption是用来加密触发器的,放在“On 数据表名或视图名的后面,“For”的前面。如果使用了这句话,该触发器将会被加密,任何人都看不到触发器的内容了。

例一:以下是一个包含提醒电子邮件的触发器例子,如果订单表里记录有改动的的话(无论增加订单还是修改、删除订单),则给物流人员张三发送电子邮件:

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

                   print '折扣不能大于0.6'

                   Rollback Transaction

         end

END

GO

在示例二中运用了两个方法,一个是前面说过的,在Inserted表里查询某个字段,还有一个是用Rollback Transaction来回滚操作。如果用下面的SQL语句来进行Insert操作的话,插入记录将会不成功。

INSERT INTO 订单明细(订单ID,产品ID,单价,数量,折扣)  

VALUES (11077,1,18,1,0.7)

运行结果如图7所示:

7 插入记录不符合触发器里的约束,则回滚操作

设置After触发器的激活顺序

对于同一个操作,如InsertUpdateDelete来说,可以建立多个After Insert触发器,在11.5.1节中,已经建立了一个名为产品_Insert”的触发器,现在再建立一个After Insert触发器,作用也是输出一句有好提示,提示内容为:再一次告诉你,你又添加了一种产品

CREATE TRIGGER 产品_Insert1

   ON  产品

   AFTER INSERT

AS

BEGIN

         print '再一次告诉你,你又添加了一种产品'

END

GO

重新运行一下插入产品的SQL语句:

INSERT INTO 产品(产品名称)

VALUES ('大苹果')

如图8所示,运行一个Insert语句,在【消息】可以看到一共输出了两句话,说明激活两个不同的触发器。

8 一个语句激活两个触发器

当同一个操作定义的触发器越来越多的时候,触发器被激活的次序就会变得越来越重要了。在SQL Server 2005里,用存储过程【sp_settriggerorder】可以为每一个操作各指定一个最先执行的After触发器和最后执行的After触发器。sp_settriggerorder语法如下:

sp_settriggerorder [ @triggername = ] '[ triggerschema. ] triggername'

        , [ @order = ] 'value'

        , [ @stmttype = ] 'statement_type'

        [ , [ @namespace = ] { 'DATABASE' | 'SERVER' | NULL } ]

翻译成中文就是

sp_settriggerorder 触发器名,

        激活次序,

        激活触发器的动作

解释如下:

触发器名,要用单引号括起来,因为它是一个字符串。

激活次序可以为FirstLastNoneFirst是指第一个要激活的触发器;Last是指它最后一个要激活的触发器;None是不指激活序,由程序任意触发。

激活触发器的动作可以是:InsertUpdateDelete

上面的例子里,先激活的是【产品_Insert】触发器,后激活的是【产品_Insert1】触发器。如果把【产品_Insert1】触发器设为First触发器,把【产品_Insert】触发器设为Last触发器,那么结果将会完全不一样。设置语句如下:

Exec sp_settriggerorder

         '产品_Insert1','First','Insert'

go

Exec sp_settriggerorder

         '产品_Insert',’Last’,'Insert'

Go

重新运行一下插入产品的SQL语句:

INSERT INTO 产品(产品名称)

VALUES ('大苹果')

运行结果如图9,与图8比较一下,是不是激活次序已经发生变化了?

9 按次序激活的激活器

在设置After触发器激活顺序时,还有几点是需要注意的:

每个操作最多只能设一个First触发器和一个Last触发器。

如果要取消已经设好的First触发器或Last触发器,只要把它们设为None触发器即可。

如果用Alter命令修改过触发器内容后,该触发器会自动变成None触发器。所以用Alter命令也可以用来取消已经设好的First触发器或Last触发器。

只有After触发器可以设置激活次序,Instead Of触发器不可以设置激活次序。

激活触发器的动作必须和触发器内部的激活动作一致。举例说明:After Insert触发器,只能为Insert操作设置激活次序,不能为Delete操作设置激活次序。以下的设置是错误的:

Exec sp_settriggerorder

         '产品_Insert1','First',’Update’

go 

相关文章推荐

触发器,trigger

  • 2012年11月11日 15:08
  • 479KB
  • 下载

触发器的PPT文档Trigger PPT document

  • 2009年06月23日 23:41
  • 2.12MB
  • 下载

MySQL触发器Trigger实例篇

MySQL触发器Trigger实例篇 发表于668 天前 ⁄ IT技术 ⁄ 暂无评论 以前关注的数据存储过程不太懂其中奥妙,最近遇到跨数据库,同时对多个表进行CURD(Create...
  • hireboy
  • hireboy
  • 2014年01月10日 11:45
  • 25907

Oracle12c中多宿主环境(CDB&PDB)的数据库触发器(Database Trigger)

oracle12c引入了多宿主选项(multitenant),即出现了CDB和PDB的概念和应用,这也会对其他方方面面的特性和应用带来不小的影响和改变,本文通过实例演示,说明了在引入多宿主选项后,触发...
  • LHDZ_BJ
  • LHDZ_BJ
  • 2016年03月01日 16:56
  • 669

oracle trigger(触发器)字段触发

说到oracle的触发器,一直以来都以为只能以表触发,今天有需求某个字段的值改变后触发一系列动作,原来想这个表改变再触发,后来想了一下,触发器本来很耗性能,如果这个表的每个字段更改都触发,这样做就造成...
  • diyyong
  • diyyong
  • 2014年01月21日 15:28
  • 9275

(05) 触发器(Trigger)的维护困境

触发器(trigger)在维护中的斑斑劣迹,我碰到的那是数不胜数.         首先不是说trigger不好,数据库都提供这个技术,自然有它的好处.  其中之一, 处理某些业务时特别简便.    ...

unity3d 理解刚体(Rigidbody)和碰撞体(Collider)以及触发器(Is Trigger),边学边更新

做实验的时候发现了一个很诡异的事情,就是发生碰撞的主体一定是要带刚体的,即只有带刚体的碰撞体去撞其他碰撞体时,双方才会收到碰撞事件,以下是我做的实验: 一、控制A(刚体加碰撞体)撞击 静止的B(碰撞...
  • ybhjx
  • ybhjx
  • 2015年12月23日 20:12
  • 771

Unity 理解刚体(Rigidbody)和碰撞体(Collider)和触发器(Is Trigger)以及刚体休眠(Rigidbody Sleeping)

前言:      今天看到看到了 Rigidbody Sleeping这个知识点,解决了我疑惑很久的一个物理学的问题。本来笔者遇到问题会想办法去解决的,但是那是想了蛮久也没想通为什么两个物体碰撞...
  • U3D_YSJ
  • U3D_YSJ
  • 2015年08月27日 00:05
  • 1631

触发器Trigger介绍

触发器简介         触发器是数据库的一种,编码方式类似于存储过程,当有DML语句对表进行操作的时候,可以引起触发器的执行,从而实现对表的数据一致性维护;         通过触发器...

cocos2d-x CocoStudio中场景触发器(Trigger)的使用和扩展

场景编辑器中的触发器是一种通过事件触发机制,在特定的事件被触发的时候自动执行自己预先定义的动作或者功能。 编辑器中带有一些默认的事件、条件和动作,当然也可以扩展自定义的事件、条件和动作。 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:触发器(Trigger)(五)
举报原因:
原因补充:

(最多只允许输入30个字)