SQL Server 中的错误处理(一)

Sql server 2000 中的错误处理

Sql server 2000中所提供的是一种非结构化的错误处理,其主要方法是使用@@error 来取得之前最近的一条处理的返回值。0表示操作成功,非0值则表示操作失败,不同的非0值表示不同的错误。

@@error 使用不方便之处在于你必须在怀疑会出错的语句之后,立即将@@error 赋予能够长时间保存值的自定义变量,否则该值将随着下一条语句的执行而产生变化,无法反映你所关注语句的真实执行情况。返回上一语句所影响的行数的@@rowcount亦是如此。

于是我们想,如果执行某操作后需要同时返回@@error以及@rowcount,是否可以运用下列语句?

<sql operation>

SET @err = @@error

SET @rc = @@rowcount

答案是否定的,问题在于第二句 “SET @rc = @@rowcount;”  返回的实为 “SET @err = @@error” 的执行结果(为0 — 该语句未影响任何一行) 而并非我们所希望得到的 <sql operation> 的属性。所以我们看出,单句赋值的SET是不能达到预期结果的。

不过在Sql server 2000中,我们还有一个work around:

<sql operation>

SELECT @err = @@error, @rc = @@rowcount

— Error handling code here

这样一来,语句段的错误处理我们可以解决了,接下来我们来看看存储过程。我们不妨把存储过程看成一个方法,都有参数有返回值。如果我们在一个方法中需要传出两个输出,那么我们应该怎么做?只能把其中一个作为out参数。存储过程也是如此:

CREATE PROC dbo.usp_XXXX

        @parameter VARCHAR(50),

        @rows INT OUTPUT

AS

DECLARE @err AS INT

<Sql operations>

SELECT @err = @@error, @rows = @@rowcount

RETURN @err

GO

虽然有一些不方便,不过还是能够处理。那么我们再来看看一些不能处理的情况,在Sql server 2000中,你并不能捕获到所有的错误。有一些错误会导致Sql语句执行直接中止,根本无法进入到之后基于判断@@error的错误处理:

1. 除零错误

SELECT 1/0;  — 出错后直接中断

PRINT ‘I’m here’;  — 该句不会执行

2. 转型错误

SELECT 1 + ‘A’  — 出错后直接中断

PRINT ‘I’m here’;  — 该句不会执行

3. 解析编译错误

SELECT * FROM dbo.nonexistingtable;  — 出错后直接中断

PRINT ‘I’m here’;  — 该句不会执行

除了上述无法处理的错误之外,即便你能得到@@error,它也只是一个INT值,记录错误编号,除此之外,不包含任何其他信息。

附:Sql server 2000中常用的错误处理模板,以存储过程为例

CREATE PROC dbo.usp_XXXX

        @parameter VARCHAR(50),

        @rows INT OUTPUT

AS

DECLARE @originalTrancount INT

SET @originalTrancount = @@TRANCOUNT

IF @originalTrancount = 0

BEGIN

        BEGIN TRAN

END

<Operation in TRAN>

SELECT @err = @@error, @rows == @@rowcount

Quit:

IF @originalTrancount = 0

BEGIN

        IF @err = 0

                COMMIT TRAN

        ELSE

                ROLLBACK TRAN

END

RETURN @err

This entry was written by Longzhang Fu , posted on Tuesday February 02 2010at 09:02 pm , filed under MS SQL Server and tagged , . Bookmark the permalink . Post a comment below or leave a trackback: Trackback URL.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>