65.9K
CodeProject 正在变化。 阅读更多。
Home

SQL Server 2005 错误处理概述

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.77/5 (32投票s)

2009年8月1日

CPOL

5分钟阅读

viewsIcon

219483

使用@@Error和Try-Catch对SQL Server 2005中的错误和异常处理进行概述

目录

引言

在开发任何应用程序时,最常见的事情之一就是我们需要处理异常和错误。同样,我们在设计数据库(如存储过程内部)时也需要处理错误和异常。在 SQL Server 2005 中,有一些出色的功能可用于处理错误。

何时需要在 SQL Server 中处理错误

通常,开发人员会尝试从代码本身处理所有类型的异常。但有时我们需要从数据库站点本身处理。有些情况,例如,我们期望在执行存储过程时会返回一些行,但不幸的是,SP 没有返回任何行。以下几点可能是我们可以使用错误处理的一些可能场景:

  • 在执行某些 DML 语句(如 INSERTDELETEUPDATE)时,我们可以处理错误以检查正确的输出。
  • 如果事务失败,则需要回滚 - 这可以通过错误处理来完成。
  • 在 SQL Server 中使用游标时。

错误处理机制

SQL Server 2005 中最常见的两种错误处理机制是:

  • @@ERROR
  • TRY-CATCH 块

让我们来看看如何实现 @@Error Try-Catch 块来处理 SQL Server 2005 中的错误。

使用 @@ERROR

我们可以将 @@ERROR 视为 SQL Server 中最基本的错误处理机制之一。@@Error 是 SQL Server 中的一个 全局变量。当某个语句发生错误时,此变量会自动填充错误消息。但我们必须在实际发生错误后的下一行立即跟踪它,否则它将重置为 0。

通用语法

@@ERROR 的通用语法如下:

Select @@ERROR

返回类型

int

它返回错误编号。

示例

我有一个名为 StudentDetails 的表,包含列 Roll (int)Name (varchar)Address (varchar)。现在我故意尝试在 Roll 字段中插入一个 char

insert into StudentDetails (roll,[Name],Address)
 values ('a','Abhijit','India')

这将引发以下错误:

Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'a' to data type int.

查看消息和编号,它是 245。现在,我在该语句之后立即执行 @@Error 语句并查看输出:

Select  @@Error 

输出是:

Error1.JPG

因此,@@Error 返回与 insert 命令返回的错误相同的错误。正如我已经说过的,@@Error 返回最后执行的 Transact-SQL 语句的错误号,所以如果我们执行任何 @@Error 语句,我们将得到输出 0。

何时应使用 @@Error 

有些场景我们 应该使用 @@ERROR

  • InsertDeleteUpdateSelect Into 语句一起使用。
  • 在 SQL Server 中使用游标时(打开、获取游标)。
  • 执行任何存储过程时。

使用 Try...Catch 块

此功能从 SQL Server 2005 及更高版本开始可用。它通常用于需要捕获或处理多个 SQL 语句或 SQL 语句块的错误的情况。TRY...CATCH 块是现代编程语言中异常处理的标准方法。使用和语法可能与普通编程语言相同。就像编程语言中的异常处理一样,我们也可以在 SQL Server 中使用嵌套的 Try-Catch 块。

Try 块将捕获错误并将其抛出到 Catch 块中。然后 Catch 块处理该场景。

GeneralBlock.JPG

通用语法

以下是 Try-Catch 块的通用语法:

-- SQL Statement
-- SQL Statement
BEGIN TRY
   -- SQL Statement or Block
END TRY
BEGIN CATCH
   -- SQL Statement or Block
END CATCH
-- SQL Statement

TRY 块中出现任何错误时,执行将跳转到 CATCH 块。

示例

正如我之前已经讨论过的 studentDetails 表,我现在将在此表中插入一条记录,其中 Roll='a'

BEGIN TRY
     INSERT INTO StudentDetails(Roll, [Name])
     VALUES('a', 'Abhijit')
END TRY
BEGIN CATCH
   SELECT 'There was an error while  Inserting records in DB '
END CATCH

由于 Roll int 类型,但我试图插入 char 类型的数据,这将违反类型转换规则,从而引发错误。因此,执行指针将跳转到 Catch 块。以下是输出:

There was an error while  Inserting records in DB

现在,为了获取错误详细信息,SQL Server 提供了以下 系统函数,我们可以在 Catch-block 中使用它们来检索错误详细信息。请查看下表:

函数名 描述
ERROR_MESSAGE() 返回错误消息的完整描述。
ERROR_NUMBER() 返回错误的编号。
ERROR_SEVERITY() 返回严重性级别编号。
ERROR_STATE() 返回错误状态号。
ERROR_PROCEDURE() 返回发生错误的存储过程的名称。
ERROR_LINE() 返回导致错误的行号。

这是一个使用系统函数的简单示例:

BEGIN TRY
   INSERT INTO StudentDetails(Roll, [Name])
    VALUES('a', 'Abhijit')
END TRY
BEGIN CATCH
   SELECT  ' Error Message: '  + ERROR_MESSAGE() as ErrorDescription
END CATCH

我在这里执行了相同的代码块,但没有显示自定义消息,而是通过调用 ERROR_MESSAGE() 系统函数来显示内部错误消息。以下是输出:

SystemFunction.JPG

嵌套 TRY-CATCH 块 

与其他编程语言一样,我们可以在 SQL Server 2005 中使用 嵌套的 Try catch 块

BEGIN TRY
  print 'At Outer Try Block'
   BEGIN TRY
      print 'At Inner Try Block'
   END TRY
   BEGIN CATCH
      print 'At Inner catch Block'
   END CATCH
END TRY
BEGIN CATCH
   print 'At Outer catch block'
END CATCH

如果我们执行此操作,输出将如下所示:

At Outer Try Block
At Inner Try Block

现在,内部 catch 块抛出错误。

BEGIN TRY
  print 'At Outer Try Block'
   BEGIN TRY
      print 'At Inner Try Block'
      INSERT INTO StudentDetails(Roll, [Name])   _
		VALUES('a', 'Abhijit')  -- Throwing Exception
   END TRY
   BEGIN CATCH
      print 'At Inner catch Block'
   END CATCH
END TRY
BEGIN CATCH
   print 'At Outer catch block'
END CATCH

这会产生以下输出:

At Outer Try Block
At Inner Try Block
At Inner catch Block

用于事务回滚的 Try-Catch 块 

在这里,我将解释一个使用 TRY-CATCH 块的真实场景。常见场景之一是使用 Transaction。在 Transaction 中,我们可以有多个操作。如果所有操作都成功执行,则数据库将提交,否则我们需要 ROLLBACK

/*
  I want to delete a Particular Records from Both Student
  Details and Library. Database will only commit, iff both 
  delete statement execute successfully, If fails it will Roll
  back. Intentionally  I have passed a wrong roll ( Which causes)
  the exception and transaction will rollback.
*/
BEGIN TRY
   -- Start A Transaction
   BEGIN TRANSACTION   

   -- Delete Student From StudenDetails Table
   DELETE FROM StudentDetails WHERE Roll = '1'
   Print 'Delete Record from Student Details Table'
   -- Delete The Same Student Records From Library Table also
   DELETE FROM Library  WHERE Roll = 'a'
   Print 'Delete Record from Library Table'
   -- Commit if Both Success
   COMMIT
   -- Update Log Details
   Insert into LogDetails(ID,Details) values ('1','Transaction Successful');
END TRY
BEGIN CATCH
 Print 'Transaction Failed - Will Rollback'
  -- Any Error Occurred during Transaction. Rollback
  IF @@TRANCOUNT > 0
    ROLLBACK  -- Roll back
END CATCH

以下是输出:

Delete Record from Student Details Table
Transaction Failed - Will Rollback

关注点

我已经用实际示例非常轻松地编写和解释了所有内容。希望这对您有所帮助。

请提供您的反馈和建议。

后续学习

这是 SQL Server 2005 错误处理的优秀链接供将来参考:

历史

  • 首次发布:2009 年 8 月 1 日
© . All rights reserved.