【网学网提醒】:本文主要为网学会员提供触发器学习资料,希望对需要触发器学习资料网友有所帮助,学习一下!
触发器
触发器是SQLServer提供给程序员和数据库分析员确保数据完整性的一种方法。这些方法对于那些经常被大量的不同应用程序访问的数据库相当有用,因为它们使数据库增强了应用规则,而应用规则是依赖于应用软件的。
1.SQLServer触发器的概念
SQLServer有效地管理信息的能力来源于它在系统中控制数据的能力。存储过程的建立,使用户能够在服务器上执行逻辑,通过规则和默认值去帮助数据库更进一步地管理信息。SQLServer在信息被写入数据库之前确认规则和默认值。这对于信息是一种“预过滤器”并且能基于数据项控制数据库活动的作用阻止数,据项的活动。触发器是在数据更新后执行的“后置过滤器”,并且SOLServer已经确认了这些规则、默认值等。触发器是SQLServer执行的特殊类型的存储过程,它发生在对于一个给定表的插入、修改或删除操作执行后。由于触发器是在操作有效执行后才被运行,在修改中它们代表“最后动作”假如触发器导致的一个请求失败的话,Server。SOL将拒绝信息更新,并且对那些倾向于事务处理的应用程序返回一个错误消息。触发器最普遍的应用是实施数据库中的商务规则,当然在维持引用完整性方面,外键要比触发器更快,但触发器能够维持那些外键所不能处理的复杂关系。触发器不会明显影响服务器的性能。它们经常被用于增强那些在其他的表和行上进行很多级联操作的应用程序的功能。
2创建触发器
创建触发器的用户必须是该数据库的拥有者,当添加一个触发器到列、行或表的时候,就会改变怎样使表能够被访问,怎样使其他对象能够与之关联等。因此,实际上正在改变数据库的模式。当然这种类型的操作为数据库拥有者所保留,以便防止有人无意中修改了系统的布局格式。创建触发器相当于说明一个存储过程,并且它有相似的语法。⑴创建触发器的语法:CREATETRIGGERtrigger_nameONtable[WITHENCRYPTION]{
{FOR{[DELETE][,][INSERT][,][UPDATE]}[WITHAPPEND][NOTFORREPLICATION]ASSql_statement[…n]}│{FOR{[INSERT][,][UPDATE]}[WITHAPPEND]
[NOTFORREPLICATION]AS{IFUPDATE(column)[{AND│OR}UPDATE(column)][…n]│IF(COLUMNS_UPDATED()bitwise_operator)updated_bitmask){comparison_operator}column_bitmask[…n]}sql_statement[…n]
}}
上述语句中的trigger_name为所定义的触发器名称;关键字INSERT,UPDATE,DELETE定义了触发器的作用域,后者决定了启动触发器的操作;Sql_statement为包含在触发器中的任何合法的SQL语句。⑵用SQLEnterpriseManager来创建触发器在Windows开始菜单中执行“程序|MicrosoftSQLServer7.0|EnterpriseManager”命令,进
入EnterpriseManager界面。在EnterpriseManager中展开SQLServerGroup,再展开Database项,选择要创建触发器的数据库(如PROJECT),再选中要创建触发器的表(如J),按右键,在弹出的菜单上选择AllTasks命令,再选ManageTriggers命令,如图33所示,弹出一个“Triggerproperties…”窗口,如图34所示,在该窗口中输入触发器代码。
3.Inserted和deleted表
当触发器被执行时,SQLServer创建一个或两个临时表(Inserted或者deleted
表)。当一个记录插入到表中时,相应的插入触发器创建一个inserted表,该表镜像该触发器相连接的表的列结构。例如,当用户在J表中插入一行时,J表的触发器使用J表的列结构创建inserted表。对于插入到J表的每一行,相应地在inserted表中也包括该行。deleted表也镜象触发器相连接的表的列结构。当执行一条DELETE语句时从表中删除的每一行都包含在删除触发器内的deleted表中。
图16.33
选择ManageTriggers
图16.34
Triggers
Properties窗口
被UPDATE语句触发的触发器创建两个表inserted和deleted表,这两个表和它们相连接的表有相同的列结构。deleted和inserted表分别包含相连接表中数据的“前后”快照。例如,假设用户执行下面的语句:UPDATEJSETJNO=’J10’WHEREJNO=’S8’当该语句被执行时,表中的更新触发器被触发。J在触发器的inserted和deleted表中,该语句所改变的每一数据行都在这两个表中包含一行。deleted表中行的数据值是执行UPDATE语句之前的J表中行的数据值;inserted表中则是执行UPDATE语句后的J表中行的数据值。
4.Update()函数
触发器降低了SQLServer事务的性能并且在事务执行时保持锁处于打开状态。如果用户的触发器逻辑只有当某些特定列改变时才需要运行,用户就应该检测这种情况的出现。update()函数可以帮助用户进行检测。Update()函数只在插入和更新触发器中可用,它确定用户传递给它的列是否已经被引起触发器激活的insert或update语句所作用。例如在表J上定义更新触发器,使其阻止JNO列被执行,触发器定义如下:CREATETRIGGERTRJ_UpdONJFORUPDATEASIFupdate(JNO)ROLLBACKTRANSACTION
RETURN
5.触发器检查
用户可以使用触发器检查事务。例如,创建一个名为TRJ的触发器,如图35所示。该触发器的功能是:将删除的工程项目数据转移到存档工程表JBACK中(假设已建立了与工程表J结构相同的存档表JBACK),,我们可以如下定义触发器:CREATETRIGGERTRJONJFORDELETEASINSERTJBACKSELECTJNO,JNAME,JCITY,BALANCEFROMdeleted又如:创建一个名为TRSPJ_UPDATE_PRICE的触发器,使其具有如下功能:在
修改供应表(SPJ)的单价时,要求修改后的单价一定要比原来的单价低。,我们可以如下定义触发器:CREATETRIGGERTRSPJ_UPDATE_PRICEONSPJFORUPDATE
ASIF(SELECTCOUNT(*)FROMdeleted,insertedWHEREdeleted.price>=inserted.price)=0ROLLBACKTRANSACTION
图16.35
触发器TRJ代码
6、insteadof和after触发器的区别主要包括定义和应用范围条件,操作执行时机;AFTER触发器(也叫“FOR”触发器)会在触发insert、update或是delect动作之后执行。例如,一个Employees表上的AFTER触发器会在在Employee表上执行一条update语句后激活。因此,AFTER触发器只有在已插入一行或是多行和所有约束已被处理且通过后才触发。INSTEADOF触发器和AFTER触发器有本质上的不同,因为INSTEADOF触发器代替触发动作进行激发。就拿同样的例子来说,如果在Emplyees表上有一个INSTEADOFUPDATE触发器和在这个表上执行一条UPDATE语句,结果是这条UPDATE语句并不会改变Employee表中的任何一行。相反,这条UPDATE语句只有是为了踢离INSTEADOFUPDATE触发器,这个触发器可能会,也可能不会改变Employees表中的数据。因此,怎么决定在合适的时间和位置放置INSTEADOF触发器呢?有几个关键的因素在做决定是值得考虑的。AFTER触发器多用在动作必须在表中数据发生改变之后才执行后情情况。比如,AFTER触发器可以用于将对数据作任何变动的日志记录在一个相对独立的审计表中。INTEADOF触发器也能做同样的工作。但是INSTEADOF触发器在这个情况下的效率比较低,因为更新动作只能在将它发生的动作准确地记录在审计表之后才允许执行。一般来说,只要不影响数据的修改,AFTER触发器比INSTEAD
OF触发器更有效率。在对数据进行计算或是对数据的修改作为一个整体提交或是作为一个整体回退的情况下,AFTER触发器也是一个很好的选择。例如,存在这样一条规则:对在Products表的产品价格的变动超过30%的必须回退。AFTER触发器能很漂亮地完成这个工作,它利用已插入同已删除的表中的产品价格作比较,然后在有必要的时回滚事务。这些都是AFTER触发器的理想条件,但有时INSTEADOF会更好些。INSTEADOF触发器有一个很大的特点——就是它允许你在某个表或视图上用多个复杂的查询操作来代替单一的查询。跟AFTER触发器只能对表起作用不同,INSTEADOF触发器可以同时对表和视图起作用。