代码之家  ›  专栏  ›  技术社区  ›  KM.

@@错误和/或尝试-捕获

  •  14
  • KM.  · 技术社区  · 15 年前

    将尝试捕获@@error可以捕获的所有错误?在下面的代码片段中,是否值得检查@@error?返回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 回复  |  直到 10 年前
        1
  •  13
  •   A-K    15 年前

    以下文章是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.

        2
  •  8
  •   gbn    15 年前

    尝试/捕捉更多陷阱。它非常好,令人惊奇。

    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位于构造的内部而不是外部,则示例会更好。

        3
  •  5
  •   SQLMenace    15 年前

    尝试捕获不会捕获所有内容

    下面是一些代码来证明这一点

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

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

        4
  •  0
  •   Ken Keenan    15 年前

    我相信控件永远不会到达RETURN语句——一旦您在一个try块中,任何引发的错误都会将控件转移到catch块。但是,有一些非常严重的错误会导致批处理或甚至连接本身中止(Erland Sommarskog已经写了有关SQL Server中错误的主题 here here --不幸的是,他还没有更新它们来包含“尝试…捕获”)。我不确定你是否能捕捉到这种错误,但是,@@错误也不好。

        5
  •  0
  •   Philip Kelley    15 年前

    根据我的经验,根据联机丛书,Try…Catch块将捕获所有会生成错误的事件(因此,将@@Error设置为非零值)。我想在任何情况下这都不适用。所以不,返回值永远不会设置为1111,并且不值得包括@@error check。

    但是,错误处理可能非常关键,我会对一些边缘情况(如DTC、链接服务器、通知或经纪服务以及其他我几乎没有经验的SQL功能)进行对冲。如果可以的话,测试一下你更奇怪的情况,看看会发生什么。

        6
  •  0
  •   dance2die    15 年前

    “try..catch”的关键是不必为每个语句检查@@error。

    所以这是不值得的。