您好,欢迎访问一九零五行业门户网

MSSQL之十 触发器和事务

在关系数据库中,表中的数据是与其他表的数据相关的。因此,当在一个表中操作数据的时候,你需要检验和确认它对相关表中数据的影响。而且你可能需要在另一个表中插入或更新数据之后再表中操纵数据。而且,你可能需要在另一个表中插入或更新数据之后在起始表
在关系数据库中,表中的数据是与其他表的数据相关的。因此,当在一个表中操作数据的时候,你需要检验和确认它对相关表中数据的影响。而且你可能需要在另一个表中插入或更新数据之后再表中操纵数据。而且,你可能需要在另一个表中插入或更新数据之后在起始表中操纵数据。你也需要确保如果当更新表中的数据的时候发生了错误,那么变化能够被回复。这有助于维护数据的完整性。
本章解释在sql server 2008中创建的不同类型的触发器。接着,他讨论如何实现触发器来增强数据完整性。进一步,它解释如何实现事务。
重点
?          实现触发器
?          实现事物
预习功课
?        触发器的概念
?        创建触发器的格式
?        事物的概念
?        创建事物的格式
实现触发器
有时,当在数据库对象上进行数据操作的时候,你可能也需要在另一个对象上完成另一个操作。例如,在公司中,员工使用在线休假批复系统以申请休假。当一个员工请休假的时候,休假的详情被保存到leavedetails表中。而且新记录被添加到leavesforapproval表。当主管登陆到系统的时候,所有未决的申请休假都从leavesforapproval表中抽取并且显示给他们。为了完成这个操作,sql server允许你实现触发器。
   触发器是一块代码,它由一系列响应某些动作激发的t-sql语句组成,例如插入或删除。触发器被用于确保数据完整性在完成数据操作之前或之后。触发器是一种特殊的存储过程,它在执行语言事件时自动生效。
那就先了解一下不同类型的触发器。
   在sql server中,有各种类型的触发器可以用来进行不同数据操纵操作的类型。sql server支持下面的触发器类型:
 1、数据修改语言(dml)触发器
2、 数据定义语言(ddl)触发器
dml触发器
  当关联的表被dml语句影响的时候,dml触发器被触发,例如insert,update或delete.。这些触发器有助于维护一致性、可靠性和表中的正确数据。他们能够完成复杂的动作并且是这些动作串联到其他相依赖的表。串联是在一个表中所做的变更反映在其他表中的过程。
  dml 触发器在数据库中发生数据操作语言 (dml) 事件时将启用。dml 事件包括在指定表或视图中修改数据的 insert 语句、update 语句或 delete 语句。dml 触发器可以查询其他表,还可以包含复杂的 transact-sql 语句。将触发器和触发它的语句作为可在触发器内回滚的单个事务对待。如果检测到错误(例如,磁盘空间不足),则整个事务即自动回滚。
dml触发器有下面的特性:
1、由sql server自动触发无论何时任何数据修改语句被提交的时候。
2、不能够被显示的调用或执行,想存储过程一样。
3、防止错误,未授权和数据中的不一致变更。
4、不能返回数据给用户。
5、可以被嵌套最高32层。当触发器完成一个激发其他触发器的动作的时候嵌套触发器发生。
 无论何时触发器被作为insert,delete或update语句的响应触发,sql server创建两个临时表,被称为魔表 。魔表被称为 已插入的和已删除的。魔表是概念表并且在结构上与定义触发器的表类似。
   已插入表包含在触发器中插入的所有的记录的副本。已删除表包含所有从触发器表中删除的所有记录。无论何时你在表中更新数据的时候,触发器使用已插入和已删除表。
依赖与完成的操作,dml触发器可以进一步被定义为:
1、插入触发器:无论何时试图在触发器表中插入一行的时候触发。当insert语句被执行的时候,新行被添加到触发器和已删除的表中。
2、删除触发器:无论何时试图从触发器表中删除一行的时候触发。当delete语句被执行的时候,来自触发器表中的特定行被删除并且被添加到删除表中。删除的和触发器表没有任何公共的行,像已插入的和触发器表的情况一样。通过使用触发器有三种实现引用完整性的方法。他们是:
a、串联方法:无论何时从主表中删除数据的时候,从依赖表中删除数据
b、 限制方法:如果相关记录在依赖表中出现,那么限制从主表中删除记录
c、无效方法:无论何时记录从主表中删除,在依赖表中的特定列中置值为无效
3、更新触发器:当update语句在触发器表中执行的时候,触发。它用于它操作的两个逻辑表,删除表包含原始行(行包含更新前的值)和存储新行的插入表(已修改的行)。在所有表更新过之后,已删除和已插入表被生成并且触发器被触发。
?       dml触发器创建
当创建一个触发器时必须指定如下选项
(1)名称;
(2)在其上定义触发器的表;
(3)触发器将何时激发;
(4)激活触发器的数据修改语句,有效选项为 insert、update 或 delete,多个数据修改语句可激活同一个触发器;
(5)执行触发操作的编程语句。
使用create trigger命令创建dml触发器的语法形式如下:
 create trigger[schema_name.]trigger_name
 on {table|view}
 [with [encryption] execute as clause][,...n]]
  {for|after|instead of} {[insert][,] [update] [,]  [delete]}
  [with append]
 [not for replication]
 as
  {sql_statement [;][...n]|external name }
  ::=assembly_name.class_name.method_name
使用sql server管理平台创建触发器的过程如下:
在sqlserver管理平台中,展开指定的服务器和数据库项,然后展开表,选择并展开要在其上创建触发器的表,如图9-1所示,右击触发器选项,从弹出的快捷菜单中选择“新建触发器”选项,则会出现触发器创建窗口,如图9-2所示。最后,单击“执行”按钮,即可成功创建触发器。
【例10-1】 示例说明inserted,deleted表的作用。执行结果如右图。
程序清单如下:
create table sc
 (sno  char(10),
  cno  char(2),
  score  real)
go
create trigger tr1
on sc
for insert, update, delete
as
print ‘inserted表:’
select * from inserted
print ‘deleted表:’
select * from deleted
go
【例10-2】 创建一个触发器,在 s 表上创建一个插入、更新类型的触发器。
程序清单如下:
create trigger tr_s
on s
for insert,update
as
begin
declare @bh varchar(6)
select @bh =inserted.sno from inserted /*获取插入或更新操作时的新值(学号)
end
dml触发器的应用
1. 使用insert触发器
insert触发器通常被用来更新时间标记字段,或者验证被触发器监控的字段中数据满足要求的标准,以确保数据的完整性。
例10-3建立一个触发器,当向sc表中添加数据时,如果添加的数据与s表中的数据不匹配(没有对应的学号),则将此数据删除。
程序清单如下:
create trigger sc_ins on sc
for insert
as
begin
declare @bh char(5)
select @bh=inserted.sno from inserted
if not exists(select sno from s where s.sno=@bh)
delete sc where sno=@bh
end
使用insert触发器
例10-4创建一个触发器,当插入或更新成绩列时,该触发器检查插入的数据是否处于设定的范围内。
程序清单如下:
create trigger sc_insupd
on sc
for insert,update
as
declare @cj int,
select @cj=inserted.score from inserted
if (@cj 100)
begin
   raiserror ('成绩的取值必须在0到100之间', 16, 1)
   rollback transaction
end
使用update触发器
当在一个有update触发器的表中修改记录时,表中原来的记录被移动到删除表中,修改过的记录插入到了插入表中,触发器可以参考删除表和插入表以及被修改的表,以确定如何完成数据库操作。
例10-5 创建一个修改触发器,该触发器防止用户修改表s的入学成绩。
程序清单如下:
create trigger tri_s_upd
on s
for update
as
if update(escore)
begin
raiserror(‘不能修改入学成绩’,16,10)
rollback transaction
end
go
. 使用delete触发器
delete触发器通常用于两种情况,第一种情况是为了防止那些确实需要删除但会引起数据一致性问题的记录的删除,第二种情况是执行可删除主记录的子记录的级联删除操作。
例10-6 建立一个与s表结构一样的表s1,当删除表s中的记录时,自动将删除掉的记录存放到s1表中。
程序清单如下:
create triggertr_del on s /*建立触发器
for delete      /*对表删除操作
as insert s1select * from deleted /*将删除掉的数据送入表s1中*/
go
ddl触发器
   ddl 触发器是 sqlserver 2008 的新增功能。当服务器或数据库中发生数据定义语言 (ddl) 事件时将调用这些触发器。
ddl 触发器会为响应多种数据定义语言 (ddl) 语句而激发。这些语句主要是以 create、alter 和 drop 开头的语句。ddl 触发器可用于管理任务,例如审核和控制数据库操作。
ddl 触发器一般用于以下目的:
(1)防止对数据库架构进行某些更改;
(2)希望数据库中发生某种情况以响应数据库架构中的更改;
(3)要记录数据库架构中的更改或事件。
仅在运行触发 ddl 触发器的 ddl 语句后,ddl 触发器才会激发。ddl 触发器无法作为 instrad of 触发器使用
创建ddl触发器
使用createtrigger命令创建ddl触发器的语法形式如下:
 create trigger trigger_name
 on {all server|database}[with [ ,...n ]]
  {for|after} {event_type|event_group}[,...n]
  as {sql_statement[;] [...n]|external name[;]}
其中:
 ::=[encryption]execute as clause]
  ::=assembly_name.class_name.method_name
ddl触发器的应用
在响应当前数据库或服务器中处理的 transact-sql 事件时,可以激发 ddl 触发器。触发器的作用域取决于事件。
例10-7 使用 ddl 触发器来防止数据库中的任一表被修改或删除。
 程序清单如下:
 create trigger safety
 on database
 for drop_table,alter_table
 as
  print 'you must disable triggersafety to drop or alter tables!'
 rollback
ddl查看、修改和删除触发器
   查看触发器
如果要显示作用于表上的触发器究竟对表有哪些操作,必须查看触发器信息。在sql server中,有多种方法可以查看触发器信息,其中最常用的有如下两种:
(1)使用sqlserver管理平台查看触发器信息;
(2)使用系统存储过程查看触发器。
?       使用sql server管理平台查看触发器信息。
在sqlserver管理平台中,展开服务器和数据库,选择并展开表,然后展开触发器选项,右击需要查看的触发器名称,如图9-4所示,从弹出的快捷菜单中,选择“编写触发器脚本为→create到→新查询编辑器窗口”,则可以看到触发器的源代码。
?       使用系统存储过程查看触发器。
系统存储过程sp_help、sp_helptext和sp_depends分别提供有关触发器的不同信息。其具体用途和语法形式如下。
sp_help:用于查看触发器的一般信息,如触发器的名称、属性、类型和创建时间。
sp_help ‘触发器名称’
sp_helptext:用于查看触发器的正文信息。
sp_helptext ‘触发器名称’
sp_depends:用于查看指定触发器所引用的表或者指定的表涉及到的所有触发器。
sp_depends ‘触发器名称’
sp_depends ‘表名’
修改触发器
通过sqlserver管理平台、存储过程,可以修改触发器的正文和名称。
?       使用sql server管理平台修改触发器正文。
在管理平台中,展开指定的表,右击要修改的触发器,从弹出的快捷菜单中选择“修改”选项,则会出现触发器修改窗口,如图9-5所示。在文本框中修改触发器的sql语句,单击“语法检查”按钮,可以检查语法是否正确,单击“执行”按钮,可以成功修改此触发器
修改dml触发器的语法形式如下:
 alter trigger schema_name.trigger_name
  on (table|view)
 [with [,...n]]
  (for|after|instead of)
  {[delete][,][insert][,][update]}
 [not for replication]
  as {sql_statement[;][...n]|external name[;]}
 ::=[encryption][&lexecute as clause >]
  ::=assembly_name.class_name.method_name
修改ddl触发器的语法形式如下:
  alter trigger trigger_name
  on {database|all server }[with [,...n]]
  {for|after}{event_type[,...n]|event_group}
 as {sql_statement[;]|exteranal name [;]}
  ::=[encryption][&lexecute as clause > ]
  ::=assembly_name.class_name.method_name
使用sp_rename命令修改触发器的名称。
       sp_rename命令的语法形式如下:
sp_rename oldname,newname
删除触发器
由于某种原因,需要从表中删除触发器或者需要使用新的触发器,这就必须首先删除旧的触发器。只有触发器所有者才有权删除触发器。删除已创建的触发器有三种方法:
 (1)使用系统命令drop trigger删除指定的触发器。其语法形式如下:
   drop trigger { trigger } [ ,...n ]
 (2)删除触发器所在的表。删除表时,sql server将会自动删除与该表相关的触发器。
 (3)在sql server管理平台中,展开指定的服务器和数据库,选择并展开指定的表,右击要删除的触发器,从弹出的快捷菜单中选择“删除”选项,即可删除该触发器。
实现事物
在sql server中,你可以实现事务来确保数据完整性。在多用户环境中,有可能同时多个事务访问同一资源。
创建事务
   事务可以被定义为一系列作为一个单一工作逻辑单元一起完成的操作。工作的一个单元必须拥有四个属性,称为acid(原子性、一致性、隔离性和持久性)。
1、           原子性:这说明要么所有数据修改被执行要么它们一个都不进行。
2、           一致性:这说明所有数据是一致的状态在事务成功完成之后。所有在关系数据库种的规则必须被应用到事务的修改中以维护完全的数据完整性。
3、           隔离性:这说明任何并发事务所做的修改必须与其他并发事务所做的修改相隔离。简而言之,事务要么在一种窗体访问数据,在其中,它是并发事务修改它之前的状态。事务没有看到中间状态的机会。
4、           持久性:这说明完成事务对数据产生的改变在系统种保持永久的影响。因此,任何由于事务完成在数据中的改变甚至在系统故障的情况下也存在。这是通过备份概念和恢复事务日志完成的。
数据库系统提供确保每个事务的物理完整性是很重要的。为了完成acid属性的需求,sqlserver提供了下面的特性:
a、          事务管理:确保所有事务的原子性和一致性。事务必须在它们启动之后成功完成,或sql server撤销自从事务启动之后的所有的数据修改。
b、          锁:保护事务的持久性和隔离性。(不讨论)
sql server 以下面的两种方式允许实现事务:
1、           自动提交事务  是sql server的默认事务管理模式。基于每个t-sql语句的完成,事务自动别提交或回滚。如果它成功完成,语句被提交;如果遇到错误,它被回滚。
2、           显示事务    是一个事务的开始和结束都显示定义的事务。显示事务在sql server以前的版本种被称为用户定义或用户特定事务。显示事务使用begin transaction 和committransaction语句指定。
开始一个事务
begin transaction 语句标识事务的开始。begin transaction语句的语法是:begintran[saction] [transaction_name | @tran_name_variable]
提交事务
commit transaction或commit work语句标识显示事务的结束。这个语句被用来结束一个在事务期间没有遇到错误的事务。commit transaction语句的语法是:
commit[tran[saction] [transaction_name | @tran_name_variable]]
回滚事务
  有时,因为一个问题有可能所有事务的语句不能成功执行。例如,在两个语句之间断电的情况,一个语句将执行,但另一个没有执行。这导致事务在一个无效的状态。在这样的情况下,为了维护一致性,你需要回复成功执行的语句。
rollbacktransaction 语句回滚一个显式或隐式的事务到事务的开始,或到事务内的保存点。
rollbacktransaction 语句的语法是:
rollback[tran[saction] [transaction_name |@tran_name_variable | savepoint_name |@savepoint_variable]]
注释:事务并发性式多个事务同时访问或改变共享数据的能力。事务并发在试图修改数据的事务阻止其他事务读取数据的时候受到影响
实践问题
1、什么是触发器
2、什么是触发器的不同类型
3、事务的用途是什么?
4、下面哪个属性不是事务拥有的?
   a、原子性  b、一致性   c、隔离性   d、分离性
小结
1、  触发器是一块代码,它由一系列t-sql语句组成,被激活以相应某些动作。
2、  sql server支持如下触发器:
   dml触发器
   ddl触发器
3、  你可以修改和删除触发器
4、  事务被用于一起执行一系列语句可作为工作的一个逻辑单元
5、每个事务包括acid属性。
6、sql server支持如下事务
自动提交事务
现实事务
其它类似信息

推荐信息