其它AFTER器操作

After 器的激活

于同一个操作,如InsertUpdate Delete,可以建立多个After Insert 器,如以下DEMO,已建立了一个名―orders_Insert‖的触器,出一句友好提示“又添加了一种品”;之后再建立一个After Insert 器,作用也出一句友好提示,提示内再一次告你,你又添加了一种

--12个触

CREATETRIGGER orders_Insert

ON orders

AFTERINSERT

AS

BEGIN

print'又添加了一种'

END

GO

CREATETRIGGER orders_Insert1

ON orders

AFTERINSERT

AS

BEGIN

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

END

GO

--2、插入一条数据

insertinto Orders

values('a02','2011-09-04','cisco','USA','7000')

--返回:

从上可以看出,一条insert into 句,触2 个触

当同一个操作定的触器越来越多的候,触器被激活的次序就会得越来越重要了。在SQLServer 2008 里,用存储过程【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 是不指激活序,由程序任意触

激活触器的作可以是:InsertUpdate Delete

上面的例子里,先激活的是【orders_Insert】触器,后激活的是【orders_Insert1

器。如果把【orders_Insert1】触设为First 器,把【orders_Insert】触设为Last 器,那么果将会完全不一句如下:

Exec sp_settriggerorder

'orders_Insert1','First','Insert'

go

Exec sp_settriggerorder

'orders_Insert','Last','Insert'

Go

--插入一条新的数据

insertinto Orders

values('a03','2011-09-04','MII','USA','7000')

器返回果:

After 器激活有几点是需要注意的:

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

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

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

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

激活触器的作必和触器内部的激活作一致。明:After Insert 器,只能Insert操作置激活次序,不能Delete 操作置激活次序。以下的置是错误的:

Execsp_settriggerorder

'orders_Insert1','First',Update

go

 

器的嵌套

当一个触,能触活另一个触器,种情况就是触器的嵌套。在SQL Server 2008 里,触器能嵌套到32

如果不想行嵌套的,可以通【允器激活其他触器】的服器配选项来控制。但不管此置是什么,都可以嵌套Instead Of 器。置触器嵌套的选项更改方法

1)打开ManagementStudio,在【源管理】中,右器名,并选择属性】选项

2单击【高点。

3)在【杂项】里置【允器激活其他触器】True False

--1建一个测试表,用于记录操作记录

DEMO_DB数据里建一个操作记录表,用来记录所有数据表的操作,无哪个数据表行了插入、更新或除,都可以把操作内容和操作时间记录到操作记录表里。下面是建立操作记录表的SQL 句:

CREATETABLE Operation

(

seq_numint IDENTITY(1,1) NOT NULL, --

op_tablevarchar(50) NOT NULL, --操作表名

op_Sentencevarchar(2000) NOT NULL, --操作

op_Contentvarchar(2000) NOT NULL, --操作

op_timedatetime NOT NULL --操作时间

CONSTRAINTDF_Operation_time DEFAULT (getdate()), --建一个默认约

CONSTRAINTPK_Operation PRIMARY KEYCLUSTERED --针对seq_num列做一个主键约

( seq_num ASC )

WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]

)

ON [PRIMARY]

GO

{ 使用 IGNORE_DUP_KEY选项理重复

建或修改唯一索引或,您可以将IGNORE_DUP_KEY选项设ON OFF。当索引建后,此选项指定操作多行的INSERT 句中所出的重复键值错误的响方式。

IGNORE_DUP_KEY OFF(默认设置),如果有一行或多行含有重复键值SQLServer 数据引擎 将拒绝语句操作的所有行。当ON ,只有包含重复键值的行被拒后,才能添加非重复键值

例如,如果一个句向某个具有唯一索引的表中插入20 行,而其中 10 行含有重复键值情况下全部20 行都将被拒。但是,如果索引选项IGNORE_DUP_KEY ON只有10 个重复键值会被拒,其他10 个非重复键值将插入到表中。}

--2建一个After Insert 器,触器的作用是入一条句:数据又有记录变动

句如下:

CREATETRIGGER Operation_Insert

ON Operation

AFTERINSERT

AS

BEGIN

print'数据又有记录变动'

END

GO

--3建一个测试type,用于插入数据,触操作

createtable type

(type_name nvarchar(15),type_descrnvarchar(max))

--4建立一个After Insert

当在type 表里插入一条记录候,器向操作记录表里插入一条记录,而在操作记录表里插入记录时,将会触操作记录表里的【Operation_Insert】触器。

CREATETRIGGER type_Insert

ONtype

AFTERINSERT

AS

BEGIN

Declare

@type_namenvarchar(15), --义变@type_name

@type_descrnvarchar(max) --义变@type_descr

set @type_name= (Selecttype_name from inserted)

--@type_name值为inserted表中type_name

set @type_descr= (Select type_descr from inserted)

--@type_descr值为inserted表中type_descr

INSERTINTO Operation(op_table,op_Sentence,op_Content)

–-,将操作内容插入到操作记录

VALUES('type','insert','type_name'+@type_name+',type_descr'+@type_descr)

END

GO

--4、在type 表中插入一条记录

insertinto type

values('book','cisco_bsci')

返回:

数据又有记录变动

(1 行受影响)

(1 行受影响)

在【消息】对话框可以看到数据又有记录变动这说明,触[Operation_Insert]

被嵌套激活了

--5看表operation 内容

select* from type

select* from Operation

返回果:

--6、如果把【允器激活其他触器】的选项设为False,再看看运行果:

insertinto type

values('book','cisco_ts')

返回:

(1 行受影响)

(1 行受影响)

可以看到并未触嵌套触[Operation_Insert]

select* from type

select* from Operation

返回 :

器的递归

器的递归是指,一个触器从其内部又一次激活器。例如一个Insert 器的内部有一条本数据表插入记录SQL 句,那么个插入句就有可能再一次激个触器本身。当然,递归的触器内部会有判断句,要一定的情况下才会行那个SQL 句,否,就会成死循了。

上面的例子的是直接递归的触器,有一种是递归的触器,明:当A 表插入一条记录时,激活了A 表的Insert 器,A表的Insert 器里有一个SQL句是B Insert 操作的,而在 B 表的Insert器里也有一句A Insert 操作的。这样就是触器的递归

一般情况来SQL Server 器是不允许递归的,如果要打开触递归的功能,是将【允器激活其他触器】设为True

设计Instead Of

InsteadOf 器与After 器的工作流程是不一的。After 器是在SQL

Server器接到SQL 求之后,先建立临时Inserted 表和Deleted表,然后实际更改数据,最后才激活触器的。而InsteadOf 器看起来就简单多了,在SQLServer 器接到SQL 求后,先建立临时Inserted 表和Deleted表,然后就触Instead Of 器,至于那个SQL 句是插入数据、更新数据除数据,就一概不管了,把Instead Of 器,由它去完成之后的操作

 

Instead Of 器的使用范

InsteadOf 器可以同在数据表和视图中使用,通常在以下几种情况下,建使Instead Of 器:

数据里的数据禁止修改:例如信部的通话记录是不能修改的,一旦修改,话费用的数将不正确。在候,就可以用Instead Of 器来跳Update 修改记录SQL 句。

有可能要回修改的SQL句:例在订单表里,折扣字段不能大于0.6,如果插入记录时,折扣大于0.6 ,回操作。如果用Instead Of 器,在判断折扣大0.6 ,就中止了更新操作,避免在修改数据之后再回操作,减少服担。

视图中使用触器:因After 器不能在视图中使用,如果想在视图中使用触器,就只能用InsteadOf 器。

用自己的方式去修改数据:如不SQL直接的修改数据的方式,可用Instead Of器来控制数据的修改方式和流程。

Instead of

1)、法:

CREATETRIGGER 器名

ON 数据表名或视图

InsteadOf INSERTDELETEUPDATE

AS

BEGIN

--里是要运行的SQL

END

GO

从上面可以看得出,InsteadOf 器与After 器的法几乎一致,只是简单地把After Instead Of

DEMO使用InsteadOf 器,在判断表orders 价格大于10000,就中止了更新操作,避免在修改数据之后再回操作,减少服担。将原来的触器改InsteadOf 器:

--1、使用AFTER 建触器:

CREATETRIGGER orders_Insert

ON orders

AFTERINSERT

AS

BEGIN

if (Select ratefrom inserted)>8000

begin

print'rate Not more than 8000'

RollbackTransaction

end

END

GO

--插入一条句,其中rate>10000看返回

insertinto Orders

values('a06','2011-09-17','cisco','usa','8500')

--返回:

rateNot more than 8000

消息3609级别16,状1,第1

在触器中束。批理已中止。

--2、使用Instead Of 建触器:

CREATETRIGGER orders_Insert

ON orders

InsteadOf INSERT

AS

BEGIN

SETNOCOUNT ON;

declare

@docnochar(20),

@docdatedatetime,

@custnvarchar(200),

@carrencychar(3),

@ratenumeric(5)

set @docno = (selectdocno from inserted)

set @docdate = (selectdocdate from inserted)

set @cust = (selectcust from inserted)

set @carrency = (selectcarrency from inserted)

set @rate = (selectrate from inserted)

if (@rate)>1000

print'rate Not more than 1000'

end

--插入一条句,其中rate>1000看返回

insertinto Orders

values('a07','2011-09-18','cisco','usa','5000')

--返回:

rateNot more than 1000

(1 行受影响)

 

管理DML

 

  1. DML

 

使用Management Studio

打开ManagementStudio →数据 → 表 → 触

看的触器名,Management Studio 动弹出一个

查询编辑器】对话框,对话框里示的是器的内容

 

使用系储过看触

SP_HELP

SP_HELPTEXT

DEMO:

sp_helporders_insert1

go

sp_helptextorders_insert1

go

返回:

修改触

 

法:

ALTERTRIGGER 器名

ON 数据表名或视图

AFTERINSERTDELETEUPDATE

AS

BEGIN

--里是要运行的SQL

END

GO

重命名触器:

sp_rename'旧触器名','新触器名'

D除触器:

除:

droptrigger '器名'

禁用:

Altertable 数据表名

DisableEnable trigger 器名或ALL

Disable可以禁用触器,用Enable 可以启用触器;如果要禁用或启用所有触器,―ALL‖来代替触器名