谈谈基于SQL Server 的Exception Handling[上篇]
对于所有的开发人员来说,Exception Handling是我们每天都要面对的事情。对于基于Source Code的Exception Handling,我想大家已经司空见惯了,但是对于Database级别的Exception Handling,就没有那么常见了。在这篇文章中,我将会介绍我对于基于Database编程中Exception Handling的一些粗浅的认识:在编写Stored Procedure时,如何抛出一个可预知的Exception,ADO.NET如何处理从Database抛出的Exception,如何保存基于Database Exception的Error Message,如何在Database和.NET Application之间进行消息的传递[注:这里的Database主要指SQL Server]。 @@ERROR 一、??? @@ERROR@@ERROR是我们经常使用的系统函数,其返回类型为INT,用以表示上一个语句的执行是否遇到错误,0便是语句正常执行,非0则以为着某个错误的产生。比如下面的一个例子:我在SQL Server Management Studio中执行下面一段简单的SQL: 会得到如下的执行结果:
由于可以通过@@ERROR得到Error的类型,可以帮助我们在编写Stored Procedure的过程中,借助这个@@ERROR进行一些流程的控制。比如我们知道Error Number为547代表违反外键约束,我们就可以通过@@ERROR的结果是否等于547来进行异常的处理:
? ? 通过我们上面一个截图我们发现,在 SQL Server Management Studio中执行任何一个语句的时候,如果遇到一个预定义的Error,会打印出相关的Error Message。这些Error Message到底是如何存储的呢?Error message和Error Numbder又是如何进行关联的呢?? 实际上,SQL Server通过一个名为sys.messages的系统表来存储关于Error的一些信息[关于sys.messages,在后续的章节中还会提及]。下面是sys.messages的结构:message_id不仅仅代表message的唯一标识,对于一个预定义的Error,其Error number就是这个message_id。由于Localization的需要,我们需要为不同的语言定义不同的Message,这些Message共享一个message_id,具体采用何种语言通过luange_id来标识。Severity代表Error的严重程度,我将在后续部分专门介绍。is_event_logged是一个Indicator,表明出现该Error是否需要在Event log中进行日志记录,text当然就是message文本了。
@error5SELECT,sys.messages.*FROM?sys.messages?WHERE?message_id?
下面是执行的结果:
@@ERROR实际上代表的是在编写SQL或者Stored procedure中对异常的识别,大多数我们通过@@ERROR来判断一段SQL语句是否成功执行,保证没有遇到不可预知的异常。对于一些可以预知的异常在SQL中又该如何处理呢? 我发现很多程序员喜欢使用Output参数来处理这些预知的异常。比如:我们需要编写一个添加User的Stored procedure,user name具有唯一性,添加一个和database中同名的user显然是不合法的,在很多情况下通过一个Output参数来返回操作最终执行的情况,比如: CREATEProcedure?P_USERS_I
![]() 很显然通过flag output参数可以得到User的创建操作最终执行的结果:-1代表重名,0代表成功,大于0代表出现不可预知的异常。 说实话,我不太喜欢这样的异常处理方式,其实这并不是说这样的处理不好,大部分还是由于个人喜好决定。我觉得,既然添加一个同名的User本身代表一种Exception,从语义上讲,认为地抛出这样Exception的方式好像更加合理一点,所以我们喜欢通过调用RAISEERROR的方式将一个Error抛出。 二、?????? RAISEERRORRAISEEROR是一个系统函数,用于奖某个可以预知的Exception抛出,供Application捕捉并处理,下面是RAISERROR的声明:
Severity:一个代表严重程度的数字,其范围为0-25,其中0-18可以由任何用户指定,19-25只能由sysadmin指定。一般地,0-10为严重程度很低的错误,11-18来高级别的错误,19-25代表非常严重的错误,以致在执行完成之后会终止当前的Session。 State:一个0-127的整数,代表一个错误状态,对于在多个地方抛出Message一致的的情况,将State在不同的地方设置在不同的值,在Debug的时候可以很快知道是哪里出错了,所以State具有很现实的意义。 Argument:向我们调用String.Format(string,…)一样,我们可以在一个一个参数中使用{0:G}{1:D}这样的站位符和进行格式处理的字符,这些站位符由后面的参数来填充。在这里也一样,在message中你一可以添加站位符,这着站位符由Argument来填充,具体如何定义,可以参阅SQL Server 2005 Books Online. WITH option [,...n ]:代表一些额外的选项,LOG表示进行日志记录,NOWAIT表示立即将Message递交到客户端,SETERROR强制将当前真实的@@ERROR或者message_id返回到客户端。 明白了RAISERROR如何使用了后,我们可以修改我们的先前创建User的Stored Procedure: )
![]() [原创]谈谈基于SQL Server的Exception Handling - PART I [原创]谈谈基于SQL Server 的Exception Handling - PART II [原创]谈谈基于SQL Server 的Exception Handling - PART III? |
- asp.net实现生成缩略图及给原始图加水印的方法示例
- asp.net-mvc-4 – 将ninject dependecyResolver用于MVC和We
- asp.net-mvc – Asp.net MVC / Web Api路由:需要路由一点点
- asp.net – RegisterOnSubmitStatement在客户端验证之后
- asp.net – 我可以在卫星装配中组合本地资源吗?
- asp.net-core – ASP.Net核心RC1:System.ArgumentExceptio
- asp.net-membership – ASP.NET成员资格 – 登录控制 – Te
- 使用Asp.Net Core时,如何查看为Razor Page生成的代码?
- asp.net-mvc – 清理用户指定的URL以防止XSS(使用ASP.NET M
- asp.net – 使用xml类型在SQL Server 2005中存储XSLT?
- 当在ASP.NET中调用AppInitialize方法时?
- asp.net-mvc – 是否有一个ASP MVC与JSTL标签等效
- asp.net-core – 使用IdentityServer4生成访问令
- ASP.NET MVC中QueryString拼接更新
- asp.net-mvc-4 – Dapper多对多查询
- asp.net-mvc – ASP.Net MVC:控制器中的访问验证
- Asp.net C的PDF或其他“报告查看器”选项#
- stored-procedures – 使用经典的asp从oracle 11
- asp.net-mvc-3 – 基于域的ASP.net MVC 3输出缓存
- redis 介绍和常用命令