@@ ERROR和/或TRY - CATCH

时间:2009-07-10 19:25:59

标签: sql-server sql-server-2005 tsql

Try-Catch会捕获@@ ERROR可以发现的所有错误吗?在下面的代码片段中,检查@@ ERROR是否值得? RETURN 1111会发生吗?

SET XACT_ABORT ON
BEGIN TRANSACTION

BEGIN TRY
    --do sql command here  <<<<<<<<<<<

    SELECT @Error=@@ERROR
    IF @Error!=0
    BEGIN
        IF XACT_STATE()!=0
        BEGIN
            ROLLBACK TRANSACTION
        END
        RETURN 1111
    END

END TRY
BEGIN CATCH

    IF XACT_STATE()!=0
    BEGIN
        ROLLBACK TRANSACTION
    END
    RETURN 2222

END CATCH

IF XACT_STATE()=1
BEGIN
    COMMIT
END

RETURN 0

6 个答案:

答案 0 :(得分:14)

以下文章是SQL Server MVP的Erland Sommarskog必读的:Implementing Error Handling with Stored Procedures

另请注意Your TRY block may fail, and your CATCH block may be bypassed

还有一件事:使用旧式错误处理和保存点的存储过程在与TRY ... CATCH块一起使用时可能无法正常工作。Avoid mixing old and new styles of error handling.

答案 1 :(得分:8)

TRY / CATCH陷阱更多。它非常棒,而且非常好。

DECLARE @foo int

SET @foo = 'bob' --batch aborting pre-SQL 2005
SELECT @@ERROR
GO
SELECT @@ERROR  --detects 245. But not much use, really if the batch was a stored proc
GO


DECLARE @foo int
BEGIN TRY
    SET @foo = 'bob'
    SELECT @@ERROR
END TRY
BEGIN CATCH
    SELECT ERROR_MESSAGE(), ERROR_NUMBER()
END CATCH
GO

在触发器中使用TRY / CATCH也有效。触发器回滚过去也是批量中止:如果触发器中也使用了TRY / CATCH,则不再使用。

如果BEGIN / ROLLBACK / COMMIT在内部,而不在构造外部,那么你的例子会更好

答案 2 :(得分:4)

尝试Catch不会捕获所有内容

这里有一些代码来演示

    BEGIN TRY
      BEGIN TRANSACTION TranA
     DECLARE  @cond INT;
     SET @cond =  'A';
    END TRY
    BEGIN CATCH
     PRINT 'a'
    END CATCH;
    COMMIT TRAN TranA

服务器:消息3930,级别16,状态1,行9 当前事务无法提交,也无法支持写入日志文件的操作。回滚交易。 服务器:消息3998,级别16,状态1,行1 在批处理结束时检测到不可提交的事务。该事务将被回滚。

答案 3 :(得分:0)

我不相信控制会到达RETURN语句 - 一旦你处于TRY块,任何引发的错误都会将控制转移到CATCH块。但是,有一些非常严重的错误可能导致批处理甚至连接本身中止(Erland Sommarskog已经写过SQL Server herehere中的错误主题 - 不幸的是,他没有没有更新它们以包括TRY ... CATCH)。我不确定你是否可以捕获那些错误,但是,@@ ERROR也不好。

答案 4 :(得分:0)

根据我的经验,根据联机丛书,TRY ... CATCH块将捕获所有会产生错误的事件(因此,将@@ ERROR设置为非零值)。我认为这不适用于任何情况。所以不,返回值永远不会设置为1111,并且包含@@错误检查是不值得的。

然而,错误处理可能非常关键,而且我会对DTC,链接服务器,通知或经纪服务以及我很少有经验的其他SQL功能等边缘情况进行对冲。如果可以,请测试更奇怪的情况,看看实际会发生什么。

答案 5 :(得分:0)

“Try..Catch”的重点在于您无需为每个语句检查@@ ERROR。

所以这不值得。