基于SQL Server 的Exception Handling - PART I

2016-02-19 16:02 1 1 收藏

有一种朋友不在生活里,却在生命力;有一种陪伴不在身边,却在心间。图老师即在大家的生活中又在身边。这么贴心的服务你感受到了吗?话不多说下面就和大家分享基于SQL Server 的Exception Handling - PART I吧。

【 tulaoshi.com - 编程语言 】

  对于所有的开发人员来说,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

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  RAISEERROR

  TRY CATCH & Return

  Error message & sys.messages

  ADO.NET Exception Handling

  SqlException

  InfoMessage

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  一、  @@ERROR

  @@ERROR是我们经常使用的系统函数,其返回类型为INT,用以表示上一个语句的执行是否遇到错误,0便是语句正常执行,非0则以为着某个错误的产生。比如下面的一个例子:我在SQL Server Management Studio中执行下面一段简单的SQL:

DECLARE @result INT
SET @result = 10/0
PRINT @@ERROR
Go

  会得到如下的执行结果:

  由于除零导致错误的产生,使@@ERROR的值变成8134。实际上8134是一个Error Number,代表某个系统定义的Error,每个预定义的Error由一个唯一的Error Number来唯一标识。@@ERROR本质上就是返回上一个语句执行遇到的Error的ID号,所以这并不是一个随机的值,无论是10/0还是100/0,@@ERROR返回的结果都是一样的。

  由于可以通过@@ERROR得到Error的类型,可以帮助我们在编写Stored Procedure的过程中,借助这个@@ERROR进行一些流程的控制。比如我们知道Error Number为547代表违反外键约束,我们就可以通过@@ERROR的结果是否等于547来进行异常的处理:

UPDATE T_USERS_IN_ROLES SET [USER_ID] = 'dummy text'
IF @@ERROR = 547
PRINT 'The user is not existent'

  通过我们上面一个截图我们发现,在

  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文本了。

  我们可以通过下面的SQL来进行验证:

DECLARE @result INT
DECLARE @error INT
SET @result = 5/0
SET @error = @@ERROR
SELECT @error,sys.messages.* FROM sys.messages WHERE message_id = @error
Go

  下面是执行的结果:

  对于@@ERROR,有一点需要特别提醒的是:它仅仅代表前一个语句执行的Error Number,之后任何一段语句的执行都会改变@@ERROR的值,甚至是一个IF语句。我想通过下面一段SQL,你肯定会后一个深刻的认识:

  我们可以看到,一个简简单单的IF语句就将@@ERROR从8134变成了0。不过想想也很简单,IF语句本身也是一个执行语句,在执行过程中并没有遇到Error,所以@@ERROR应该返回0。这也是我在上面的Sample中通过SET @error = @@ERROR将@@ERROR进行预存的原因。

  @@ERROR实际上代表的是在编写SQL或者Stored procedure中对异常的识别,大多数我们通过@@ERROR来判断一段SQL语句是否成功执行,保证没有遇到不可预知的异常。对于一些可以预知的异常在SQL中又该如何处理呢?

  我发现很多程序员喜欢使用Output参数来处理这些预知的异常。比如:我们需要编写一个添加User的Stored procedure,user name具有唯一性,添加一个和database中同名的user显然是不合法的,在很多情况下通过一个Output参数来返回操作最终执行的情况,比如:

CREATE Procedure P_USERS_I
  (
    @user_id      varchar(50),
    @user_name  nvarchar(256),
    @flag        INT OUTPUT
  )
AS
IF(EXISTS(SELECT * FROM dbo.T_USERS WHERE LOWERED_USER_NAME = LOWER(@user_name) OR [USER_ID] = @user_id))
  BEGIN
    SET @flag = -1
    RETURN
  END  
INSERT INTO dbo.T_USERS
      ([USER_ID]
      ,[USER_NAME]
      ,LOWERED_USER_NAME)
   VALUES(@user_id, @user_name, LOWER(@user_name))  
SET @flag = @@ERROR

来源:https://www.tulaoshi.com/n/20160219/1610942.html

延伸阅读
SQL Server是购买Sybase公司1987年推出的Sybase SQL Server, 又称为大学版INGRES的第三代产品,所以他们实质是一样的。 Sybase公司是1984年成立的,属于后起之秀。他推出了支持企业范围的“客户/服务器体系结构”的数据库。Sybase把“客户/服务器数据库体系结构”作为开发产品的重要目标。他们吸取了INGRES的研制经验,以满足联机事务...
以下为SQL SERVER7.0以上版本的字段类型说明。SQL SERVER6.5的字段类型说明请参考SQL SERVER提供的说明。 bit:0或1的整型数字 int:从-2^31(-2,147,483,648)到2^31(2,147,483,647)的整型数字 smallint:从-2^15(-32,768)到2^15(32,767)的整型数字 tinyint:从0到255的整型数字 decimal:从-10^38到10^38-1的定精度与有效位数的数字 ...
标签: SQLServer
微软总是试图使它的软件安装尽可能地简单顺畅,SQL Server 2000的安装也不例外。你从安装光盘的x86 etup文件夹启动setupsql.exe、在安装对话框中填入一些细节后,几分钟内,安装将在没有用户介入的情况下继续执行。你甚至可以成功的安装SQL Server 2000而不用明白那些选择意味着什么——只需在大多数安装对话框中点击“下一步”。然而,我强烈建...
Java里有个很重要的特色是Exception ,也就是说答应程序产生例外状况。而在学Java 的时候,我们也只知道Exception 的写法,却未必真能了解不同种类的Exception 的区别。 首先,您应该知道的是Java 提供了两种Exception 的模式,一种是执行的时候所产生的Exception (Runtime Exception),另外一种则是受控制的Exception (Checked E...
SQL SERVER数据库用datetime类型的时候 如果插入NULL,没有问题 如果插入空串"",就会默认1900-01-01 00:00:00

经验教程

127

收藏

77
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部