在SQL Server 2005数据库中进行错误捕捉
作者:Blithe 发布时间:2008-12-02 14:39:00
在SQL Server数据库中,如果执行Transact-SQL时出现了错误,我们可以使用两种捕捉错误的方法解决此问题,一种是在客户端代码(如c#、delphi等)中使用类似try...catch的语句进行捕捉;另外一种就是在Transact-SQL中利用Transact-SQL本身提供的错误捕捉机制进行捕捉。如果是因为Transact-SQL语句的执行而产生的错误,如键值冲突,使用第一种和第二种方法都可以捕捉,但是如果是逻辑错误,使用客户端代码进行捕捉就不太方便了。因此,本文针对如何使用Transact-SQL进行错误捕捉进行了深入的探讨。
一、非致命错误(non-fatal error)的捕捉
通过执行Transact-SQL而产生的错误可分为两种:致命错误(fatal error)和非致命错误(non-fatal error)。在Transact-SQL中只可以捕捉非致命错误(如键值冲突),而无法捕捉致命错误(如语法错误)。在Transact-SQL中可以通过系统变量@@ERROR判断最近执行的一条语句是否成功执行。如果发生了错误,@@Error的值大于0,否则值为0。下面举一个例子说明@@ERROR的使用。
假设有一个表table1,在这个表中有两个字段f1,f2。其中f1是主键。
INSERT INTO table1 VALUES(1, 'aa')
INSERT INTO table1 VALUES(1, 'bb') --这条语句将产生一个错误
IF @@ERROR > 0
PRINT '键值冲突'
当执行第二条语句时发生键值冲突错误,@@ERROR被赋为错误号2627,因此输出结果显示'键值冲突'。使用@@ERROR系统变量时需要注意,@@ERROR只记录最近一次执行的Transact-SQL语句所发生的错误,如果最近一次执行的Transact-SQL没有发生错误,@@ERROR的值为0。因此,只能在被捕捉的那条Transact-SQL语句后使用@@ERROR。
在SQL Server中,不仅可以捕捉系统提供的错误,还可以自定义错误。有两种方法可以定义错误信息。
1. 使用sp_addmessage系统存储过程添加错误信息,然后使用RAISERROR抛出错误
sp_addmessage将错误号,错误级别、错误描述等信息添加到系统表中,然后使用RAISERROR根据相应的错误号抛出错误信息。用户自定义的信息应该从50001开始。
EXEC sp_addmessage @msgnum = 50001, @severity = 16,
@msgtext = 'sql encounter an error(%s).',
@lang = 'us_english'
EXEC sp_addmessage @msgnum = 50001, @severity = 16,
@msgtext = 'sql遇到了一个错误(%1!).'
如果使用的SQL Server版本是非英语版本,在添加本地错误信息时必须首先添加英文的错误信息。错误描述可以象c语言中的printf的格式字符串一样使用参数,如%s、%d。但要注意的是在英文版的错误信息中要使用%s、%d等形式,而在本地化的错误信息中要使用%1!、%2!等形式,在每个%?(1 <= ? <= n)后需要加一个!,而且%?的数目必须和英文版的错误信息的参数一致。
在未插入本地化错误信息时,RAISERROR将使用英文版的错误信息。当插入本地化错误信息时,RAISERROR使用本地化的错误信息。
RAISERROR(50001, 16, 1, '测试')
输出的结果:
服务器: 消息 50001,级别 16,状态 1,行 1
sql遇到了一个错误(测试).
其中'测试'字符串通过%1传入本地化的错误描述字符串中。
2.直接使用RAISERROR将错误抛出
使用第一种方法虽然使Transact-SQL语句看上去更整洁(这种方法类似于在编程语言中使用常量定义错误信息,然后在不同的地方通过错误编号引用这些错误信息。),但是这样做却使错误信息和数据库的耦合度增加,因为如果将这些带有RAISERROR的Transact-SQL放到别的SQL Server数据库上执行,由于在其它的数据库中还未添加错误信息,因此会产生RAISERROR调用错误,除非使用sp_addmessage将所需的错误信息再加入到其它的数据库中。
基于上述原因,RAISERROR不仅可以根据错误代码抛出错误信息,也可以直接通过错误描述格式字符串抛出错误信息。
RAISERROR('sql遇到了一个错误(%s)', 16, 1, '测试')
猜你喜欢
- 除了使用xlrd库或者xlwt库进行对excel表格的操作读与写,而且pandas库同样支持excel的操作;且pandas操作更加简介方便
- 常用方法#记住引入numpy时要是用别名np,则所有的numpy字样都要替换 #查询数值类型>>>type(float)d
- “你如何为成千上万的用户和页面提供CSS?” 这是Nicole Sullivan在她的在丹佛的Web Directions North 大会
- 根据题意理解:本质就是写分页查询:每页条数:10条;当前页码:4页;//第一种:select * from (select ROW
- 两个Date类型字段:START_DATE,END_DATE,计算这两个日期的时间差(分别以天,小时,分钟,秒,毫秒):天:ROUND(TO
- Python模块,简单说就是一个.py文件,其中可以包含我们需要的任意Python代码。迄今为止,我们所编写的所有程序都包含在单独的.py文
- 1.基数排序基数排序的基本思想是先将数字按照个位数上数字的大小进行排序,排序之后再将已经排过序的数字再按照十位数上数字的大小进行排序,依次推
- 本文为大家分享了vuejs事件中心管理组件间的通信,供大家参考,具体内容如下事件中心这个可以是一个空的全局的Vue实例,其他的组件利用这个实
- 升级并不容易,但是有一些特性值得花时间了解。下面本文将介绍一些避免升级问题的技巧。升级一个关键业务SQL Server实例并不容易;它要求有
- 我就废话不多说了,直接上代码吧!from os import listdirimport osfrom time import timeim
- 很长时间以来,一直想将自己的一些零碎的想法总结下,给自己一个完整的思维,也算是做个存档。一家之言,绝不敢说对别人会有什么帮助,对外人的层面上
- 本文实例为大家分享了python实现knn算法的具体代码,供大家参考,具体内容如下knn算法描述对需要分类的点依次执行以下操作:1.计算已知
- 由于一些原因,视频录制要告一段落了。再写一篇关于cntk的文章分享出来吧。我也很想将这个事情进行下去。以后如果条件允许还会接着做。cntk2
- Vue - 实现穿梭框功能,效果图如下所示:css.transfer{ display: flex;
- 今天启动SQLServer2000时报1053错误 错误如下所示: 发生错误 1053-(服务没有及时响应或控制请求。),此时正在 MSSQ
- 1.MySQL官网下载压缩版文件,放至安装路径下载zip安装包MySQL :: Download MySQL Community Serve
- var gb1 = 10; this.gb2 = 20; function gb3() {}; (function() { var ro =
- Real Numbers实数实数是具有小数部分的数字, 当然, 实数不是专门用来表示小数的, 也可以用DECIMAL来存储那些无法用INTE
- 昨天有位同事说,他的网页查询过程中发现普通索引和唯一索引的效率是有差别的,普通索引比唯一索引快,今天在我的虚拟机中布置了环境,测试抓图如下:
- 本文实例讲述了flask框架jinja2模板与模板继承。分享给大家供大家参考,具体如下:jinja2模板from werkzeug.cont