触发器(Trigger)(九)

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

 2005新增功能:查看与修改DDL触发器

DDL触发器有两种,一种是作用在当前SQL Server服务器上的,一种是作用在当前数据库中的。这两种DDL触发器在Management Studio中所在的位置是不同的。

作用在当前SQL Server服务器上的DDL触发器所在位置是:【对象资源管理器】,选择所在SQL Server服务器,定位到【服务器对象】à【触发器】,在【摘要】对话框里就可以看到所有的作用在当前SQL Server服务器上的DDL触发器。

作用在当前数据库中的DDL触发器所在位置是:【对象资源管理器】,选择所在SQL Server服务器,【数据库】,所在数据库,定位到【可编程性】à【数据库触发器】,在摘要对话框里就可以看到所有的当前数据库中的DDL触发器。

右击触发器,在弹出的快捷菜单中选择【编写数据库触发器脚本为】àCREATE到】à【新查询编辑器对话框】,然后在新打开的【查询编辑器】对话框里可以看到该触发器的内容。

Management Studio如果要修改DDL触发器内容,就只能先删除该触发器,再重新建立一个DDL触发器。

虽然在Management Studio中没有直接提供修改DDL触发器的对话框,但在【查询编辑器】对话框里依然可以用SQL语句来进行修改。下面给出几个对DDL触发器操作常用的SQL代码,由于对DDL触发器的操作和对DML触发器的操作类似,因此不再详细说明用法。

创建DDL触发器

CREATE TRIGGER (Transact-SQL)

删除DDL触发器

DROP TRIGGER (Transact-SQL)

修改DDL触发器

ALTER TRIGGER (Transact-SQL)

重命名DDL触发器

sp_rename (Transact-SQL)

禁用DDL触发器

DISABLE TRIGGER (Transact-SQL)

启用DDL触发器

ENABLE TRIGGER (Transact-SQL)

删除DDL触发器

DROP TRIGGER (Transact-SQL)

 触发器的应用技巧

触发器的使用范围很广,使用的频率也很高,触发器的应用技巧也层出不穷,下面介绍一些在触发器里常用的技巧,希望可以做到抛砖引玉之功效。

  如何知道触发器修改了多少条记录

需要注意的是,一种操作类型(InsertUpdateDelete)虽然可以激活多个触发器,但是每个操作类型在一次操作时,对一个触发器只激活一次。例如,运行一个Update语句,有可能一次更新了十条记录,但是对于After Update这个触发器,只激活一次,而不是十次。但是在Inserted表和Deleted表里会有十条记录,这个时候,只要利用@@Rowcount这个系统变量就可以得知更新了多少条记录。例如:

CREATE TRIGGER 订单明细删除_test

   ON  订单明细

   AFTER DELETE

AS

BEGIN

         print '您此次删除了' + Cast(@@rowcount as varchar) + '条记录'

END

GO

Delete FROM 订单明细 where 折扣=0.25

GO

Delete FROM 订单明细 where 订单ID='123456789'

GO

这里先是建立了一个名为订单明细删除_test”的触发器,作用就是显示删除了多少条记录。之后执行两个SQL语句,一个是删除折扣为0.25的记录,一个是删除订单ID号为123456789的记录,这条记录是不存在的。运行结果如图11.20所示:

20 显示删除的记录数

在图20可以看出,用系统变量@@rowcount可以获得删除记录的条数。另外,在图中还可以看出,虽然第二个SQL语句删除的记录数为零,但是触发器还是被激活了。因此可以知道,触发器只与激活它的类型有关,与具体操作的记录数无关。

  如何知道插入记录的自动编号是多少

在第11.7节,触发器的嵌套里,【类别】数据表设计了一个触发器,当在【类别】数据表里插入一件记录的时候,将会在【操作记录表】里也插入一条记录,用来记录具体的插入操作的,其实这个触发器还可以写得更好,不但可以记录插入操作所用的SQL语句,还可以记录下当时插入记录时候,数据库为这个记录自动生成编号是多少,为以后的操作提供更大的便利。修改该触发器的代码如下:

ALTER TRIGGER 类别_Insert

   ON  类别

   AFTER INSERT

AS

BEGIN

         Declare

         @类别名称 nvarchar(15),

     @说明 nvarchar(max)

         set @类别名称 = (Select 类别名称 from inserted)

         set @说明 = (Select 说明 from inserted)

         INSERT INTO 操作记录表 (操作表名,操作语句,操作内容)

     VALUES ('类别表','插入记录',

                   '插入了ID号为'+cast(@@IDENTITY as varchar)+'的记录:类别名称:'

                            +@类别名称+',说明:'+@说明)

END

GO

从上面的代码可以看出,用@@IDENTITY可以获得刚插入记录的标识值,在本例中是它的主键值。插入记录后,在【操作记录表】里可以详细查看到插入的记录的编号以及它的内容。

 如何知道某个字段是否被修改

Update触发器和Insert触发器里,可以用“Update(字段名)”来判断某个字段是不是被更改,返回的是一个布尔值。例如定单生成后,只能修改折扣的触发器:

CREATE TRIGGER 只允许修改折扣

   ON   订单明细

   Instead Of UPDATE

AS

BEGIN

         SET NOCOUNT ON;

         if update(折扣)

                   begin

                            declare

                            @订单ID int,

                            @产品ID int,

                            @折扣 real

                            set @订单ID = (select 订单ID from inserted)

                            set @产品ID = (select 产品ID from inserted)

                            set @折扣 = (select 折扣 from inserted)

                            update 订单明细 set 折扣=@折扣

                                     where 订单ID=@订单ID and 产品ID=@产品ID

                   end

         else

         begin

                   print '只能更改折扣字段'

         end

END

GO

update 订单明细 set 折扣=0.2

         where 订单ID=10288 and 产品ID=54

Go

update 订单明细 set 订单ID=10288

         where 订单ID=10288 and 产品ID=54

Go

上面的代码,先建立了一个触发器,只有修改了折扣字段的Update语句才会被执行。然后写了两个UpdateSQL语句,一个是修改了折扣字段的,一个是没有修改折扣字段的。运行后的结果如图11.21所示。第一个SQL语句被正确执行,第二个SQL语句没有被执行。

21 Update判断字段是否被修改

 如何返回错误信息

虽然上面介绍触发器时,用过很多次Print来输出自定义的信息,但是实际上,只有在用【查询编辑器】中运行SQL语句才能看得到这些自定义的信息,而其他的前端应用程序都不会显示出这些自定义的信息,包括用Management Studio也一样。

读者可以自行测试一下,在Management Studio里打开【订单明细】数据表,因为上面建了一个【只允许修改折扣】的触发器,所以只要在不是折扣的字段里修改数据后,再将鼠标聚焦到其他记录上时,被修改的数据马上就会回滚到修改前的状态,在这个过程中,几乎是看不到什么提示的。如果想要在这个过程中看到提示的话,就要将触发器修改一下,加上“Raiserror”语句,具体修改代码如下:

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

go

ALTER TRIGGER 只允许修改折扣

   ON  订单明细

   Instead Of UPDATE

AS

BEGIN

         SET NOCOUNT ON;

         if update(折扣)

                   begin

                            declare

                            @订单ID int,

                            @产品ID int,

                            @折扣 real

                            set @订单ID = (select 订单ID from inserted)

                            set @产品ID = (select 产品ID from inserted)

                            set @折扣 = (select 折扣 from inserted)

                            update 订单明细set 折扣=@折扣

                                     where 订单ID=@订单ID and 产品ID=@产品ID

                   end

         else

                   begin

                            print '只能更改折扣字段'

                            Raiserror('除了折扣字段之外的其他字段信息不能修改',16,5)

                   end

END

修改完触发器之后,再去修改其他非折扣字段的内容时,就会弹出错误提示,如图11.22所示,Raiserror的用法可以查看SQL Server 2005的帮助。

22 显示错误信息

  小结

触发器是与数据库和数据表相结合的特殊的存储过程,当数据表有InsertUpdateDelete操作或数据库有CreateAlterDrop操作的时候,可以激活触发器,并运行其中的T-SQL语句。

SQL Server 2005中触发器分为DML触发器和DDL触发器两种。其中DML触发器又分为After触发器和Instead Of触发器两种。After触发器是先修改记录后激活的触发器;Instead Of触发器是取代触发器。DDL触发器根据作用范围可以分为作用在数据库的触发器和作用在服务器的触发器两种。After触发器只能用于数据表中,而Instead Of触发器即可以用在数据表中,也可以用在视图中。

使用CREATE TRIGGER语句可以创建触发器,使用ALTER TRIGGER语句可以修改触发器,使用Drop Trigger语句可以删除触发器。触发器允许嵌套和递归,嵌套最多可以是32层。

在下个章节里将会介绍索引的使用方法。

 

触发器,trigger

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

触发器的PPT文档Trigger PPT document

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

(trigger)触发器的定义和作用

(trigger)触发器的定义和作用 博客分类: Oracle SQLCC++C#F#  第一:触发器(trigger) 触发器(trigger)是指隐含执行的存储过程pr...

oracle trigger(触发器)字段触发

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

MySQL触发器Trigger实例篇

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

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

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

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

unity3d 理解刚体(Rigidbody)和碰撞体(Collider)以及触发器(Is Trigger),边学边更新 分类: Unity3D2014-04-01 16:50 2776...

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

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

mysql之触发器trigger 详解

mysql之触发器trigger 触发器(trigger):监视某种情况,并触发某种操作。 触发器创建语法四要素:1.监视地点(table) 2.监视事件(insert/update/dele...
  • wdk1011
  • wdk1011
  • 2017年07月29日 15:49
  • 111

mysql触发器(Trigger)简明总结和使用实例

一,什么触发器 1,个人理解 触发器,从字面来理解,一触即发的一个器,简称触发器(哈哈,个人理解),举个例子吧,好比天黑了,你开灯了,你看到东西了。你放炮仗,点燃了,一会就炸了。 2,官方定义 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:触发器(Trigger)(九)
举报原因:
原因补充:

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