SQL Server 2008中SQL应用系列--目录索引
在SQL Server 2000中,我们一般使用RaiseError(http://msdn.microsoft.com/zh-cn/library/ms177497.aspx)来抛出错误交给应用程序来处理。看MSDN示例(http://msdn.microsoft.com/zh-cn/library/aa238452%28v=sql.80%29.aspx),自从SQL Server 2005集成Try…Catch功能以后,我们使用时更加灵活,到了SQL Server 2012,更推出了强大的THROW,处理错误显得更为精简。本文对此作一个小小的展示。
首先,我们假定两个基本表如下:
我们从一个最简单的例子入手:
例一:
先不看结果,我想问一下,该语句执行完毕后,Score表会插入几条记录?估计可能有人说是2条,有人说0条,也可能有人说4条。
实际上,我希望是0条,但结果是4条!
我对这个结果也有点惊讶,我希望它出错回滚,于是修改:
例二:
我先提示一下大家,这个语句中的@@ERROR值是547,那么此时,Score表中有几条记录?
答案是2条!
可能有人开始摇头了,那么问题的关键在哪儿呢?对,就是这个“XACT_ABORT ”开关,查MSDN(http://msdn.microsoft.com/zh-cn/library/ms188792.aspx),
官方解释:它用于指定当 Transact-SQL 语句出现运行时错误时,SQL Server 是否自动回滚到当前事务。当 SET XACT_ABORT 为 ON 时,如果执行 Transact-SQL 语句产生运行时错误,则整个事务将终止并回滚。当 SET XACT_ABORT 为 OFF 时,有时只回滚产生错误的 Transact-SQL 语句,而事务将继续进行处理。 如果错误很严重,那么即使 SET XACT_ABORT 为 OFF,也可能回滚整个事务。 OFF 是默认设置。编译错误(如语法错误)不受 SET XACT_ABORT 的影响。对于大多数 OLE DB 访问接口(包括 SQL Server),必须将隐式或显示事务中的数据修改语句中的 XACT_ABORT 设置为 ON。 唯一不需要该选项的情况是在提供程序支持嵌套事务时。
这里,红色的一句话是关键,那么“有时”究竟是指什么时候呢?查资料知:(http://msdn.microsoft.com/zh-cn/library/ms164086.aspx)
大致分为以下四个级别:
当等级SEVERITY为0-10时,为“信息性消息”,最轻。
当等级为11-16时,为“用户可以纠正的数据库引擎错误”。如除数为零,等级为16
当等级为17-19时,为“需要DBA注意的错误”。如内存不足、数据库引擎已到极限等。
当等级为20-25时,为“致命错误或系统问题”。如硬件或软件损坏、完整性问题、媒体故障等。
用户也可以自定义错误级别和类型。
根据以上解释,我们最保险的方式是:Set XACT_ABORT ON。
当然,使用Try…Catch在Set XACT_ABORT OFF时也能按照我们的意愿回滚。
例三:
这个返回结果比较另类,它其实是一条拼凑起来的记录。
记录并没有新增,因为Catch到错误而事务回滚了。
使用RaiseError也可以把出错的信息抛给应用程序来处理。
例四:
或者直接使用Throw也能达到RaiseError同样的效果,而且这是微软推崇的方式:其官方解释为“
THROW 语句支持 SET XACT_ABORT,但 RAISERROR 不支持。 新应用程序应该改用 THROW,而不使用 RAISERROR。”其实,可能是微软在忽悠,因为,其实RaiseError也支持Set XACT_ABORT。
例五:
不过,说实话,Throw好像很简练。
说到这里,我有一个疑问:例四和例五的查询结果相同:
虽然因为回滚而没有插入数据,但是两个“(1 row(s) affected) ”还是让我吃了一惊,
哪位高手能告诉我一下,这影响的两行SQL Server究竟是怎么处理的?先谢过了。
既然,错误已经被捕获,那么有两种处理方式,一是直接在数据库中记录到表中。比如:我们可以建立一个数据库DBErrorLogs,
在出错时直接插入相应信息到该表中即可。另外一种思路是交给应用程序来处理,比如下例中,我们用C#捕获错误,并用log4net记录回数据库中。C#中有相应的SQLException类,封装了相应的Error的等级、编号、出错信息等,真心方便。
文后附有C#源码。执行效果:
小结:
1、SQL Server处理错误时有一个重要的开关XACT_ABORT,没事的时候,记得把它打开。
2、SQL Server提供的错误信息很丰富,请区分等级采取相应的对策,当然,还可以自己增加更为实用贴切的自定义错误类型。
下载源码
邀月注:本文版权由邀月和CSDN共同所有,转载请注明出处。
助人等于自助! 3w@live.cn
分享到:
相关推荐
十分好用的sql server profiler 事件跟踪器
SQL SERVER 2005/2008/2008R2 自动关联表名字段名工具,SQL SERVER 2008R2测试可用
本人目前在做Java开发 在网上下载了好几个jdbc驱动,问题很多 现在对jdbc驱动进行总结: sqlserver2005/sqlserver2008 jdbc驱动 希望对有这方面需求的人提供帮助。
sql server 2005/2008 自动联想表名字段名工具,超实用小工具。
Xampp1.7 链SQLServer2005/SQLServer2008,配置与测试; 扩展库 sqlserver driver for php
连接SQL SERVER 2005/2008失败——解决方案
这个压缩包中包括了oracle sqlserver2005/2008 mysql驱动包以及url和驱动名,三个常用数据库的驱动以及url和驱动的名称,下载后只要在自己的jdbc类中复制进去,修改数据库的名称以及密码就可以使用了!!
blog博客发布系统 jsp+servlet+sqlserver2005/2008
灵活方便的自动附加数据库工具,配置Config.ini文件即可自动附加MS SQL Server 2000/2005/2008
SQLServer2000/2005/2008+MySQL5.0的数据库驱动包
主要用于弥补sqlserver2005/2000生成脚本无法连带生成表内数据的短板,一键生成脚本,解决了编写大量繁琐的执行语句的问题。
SQLSERVER数据库中使用发布与订阅方式进行数据同步,使用所有的SQLSERVER数据库,从SQLSERVER2000到SQLSERVER2005/SQLSERVER2008/SQLSERVER2008R2
sqlserver 2000/2008 jar包
sql server 2005/2000 jdbc2.0驱动 对于Java数据库编程很是用. sql server 2005 添加jdbc4.jar
列出指定SQL Server 服务器上数据库列表,选择要处理的数个数据库,执行批量日志清理与数据库压缩
在SQLServer2008上面成功附件SQLServer2005的方法
不管是SQL SERVER 2005还是SQL 2008 都没有提供字符串的聚合函数,但是 SQL 2005以后的版本支持CLR扩展系统的函数,所以就使用VS2010写了一个. 以后可以这样写了 select Age,dbo.joinstr(UserName,',',0) Name From ...
Microsoft SQL Server 2005 Backward Compatibility Components (Microsoft SQL Server 2005 向后兼容组件) SQL Server Backward Compatibility 包中包含 最新版本的 Data Transformation Services 2000 运行时 ...
修改SQL Server 2005,2008用户数据库的默认路径和备份路径
NULL 博文链接:https://12345678.iteye.com/blog/1038363