【问题标题】:Issues with T-SQL TRY CATCH?T-SQL TRY CATCH 的问题?
【发布时间】:2011-08-26 11:43:58
【问题描述】:

我们目前正在使用 SQL 2005,我正在将旧的 Foxpro 系统迁移到由 SQL Server 支持的新 Web 应用程序。我在 T-SQL 中使用 TRY CATCH 进行事务处理,它似乎工作得很好。工作中的其他一位程序员对此感到担忧,因为他说他听说过一些问题,即标语并不总是能捕捉到错误。我已经将 sproc 打死了,不能让它失败(错过一个捕获),我在网上搜索时发现的唯一问题是它不会返回错误号

【问题讨论】:

  • 引起很多人注意的是,如果出现编译错误,则不会输入 CATCH 子句,例如缺少列/表。

标签: sql-server tsql try-catch


【解决方案1】:

我从来没有遇到过 TRY...CATCH... 失败的情况。 Neiteher 可能有很多人读过这个问题。这,唉,只意味着如果有这样的SQL bug,那么我们还没有看到它。问题是,这是一个相当大的“如果”。信不信由你,微软确实付出了一些努力来使他们的核心软件产品变得相当可靠,而 TRY...CATCH... 并不是一个新概念。一个简单的例子:在 SQL 2005 中,我在解决当时的新表分区时遇到了一个可靠的、可证明的和可复制的错误——这个错误已经被补丁修复了。并且 TRY...CATCH... 比表分区更频繁地使用。

我想说举证责任落在你的同事身上。如果他“在某处听到”,那么他应该尝试用某种证据来支持它。互联网上到处都有一句老话“只是因为每个人都这么说,并不意味着他们是对的”。

【讨论】:

  • 我问了一个一般性的问题,如果有人在使用 TRY CATCH 时遇到任何问题 - 我没有要求任何人证明任何事情。
  • -1,T-SQL Try Catch 未处理 CLR 集成错误。但是,这个问题很有用,其他答案也很有用。
【解决方案2】:

TRY ... CATCH 没有捕捉到所有可能的错误,但未捕捉到的错误在 BOL Errors Unaffected by a TRY…CATCH Construct 中有详细记录

TRY...CATCH 构造不会捕获 以下条件:

  • 严重性为 10 或更低的警告或信息性消息。
  • 严重性为 20 或更高的错误会停止 SQL Server 数据库引擎任务处理 会议。如果发生错误 严重程度为 20 或更高,并且 数据库连接没有中断, TRY…CATCH 将处理错误。
  • 注意,例如客户端中断请求或中断 客户端连接。
  • 当系统管理员使用 KILL 结束会话时 声明。

以下类型的错误不是 当它们由 CATCH 块处理时 发生在同一执行级别 作为 TRY...CATCH 构造:

  • 编译错误,例如语法错误,阻止批处理 正在运行。
  • 语句级重新编译期间发生的错误,例如 对象名称解析错误 编译后发生,因为 延迟名称解析。

这些错误返回到关卡 运行批处理,存储过程, 或触发器。

【讨论】:

    【解决方案3】:

    在我的经验中,有一种情况是 TRY...CATCH 块没有捕捉到错误。与排序规则有关的错误: 无法解决 equal to 操作中“Latin1_General_CI_AS”和“Latin1_General_CI_AI”之间的排序规则冲突。 也许此错误对应于 BOL 中记录的错误类型之一。

    语句级重新编译过程中出现的错误,例如object 编译后出现的名称解析错误,因为 延迟名称解析。

    【讨论】:

      【解决方案4】:

      如果您将“错误”搜索词传递给CONTAINSTABLETRY ... CATCH 将无法捕获错误

      例如:

      DECLARE @WordList VARCHAR(800)
      SET @WordList = 'crap"s'
      CON
      
      TAINSTABLE(table, *, @WordList)
      

      CONTAINSTABLE 会给您一个“语法错误”,而任何周围的 TRY ... CATCH 都不会发现这一点。

      这特别令人讨厌,因为错误是由数据引起的,而不是由代码中的“真正”语法错误引起的。

      【讨论】:

        【解决方案5】:

        我正在使用 SQL Server 2008。我构建了一个包含 try/catch 的大型 sql 语句。我通过重命名表(在开发中)来测试它。该声明爆炸了,没有发现错误。 SQL Server 中的 Try/catch 很弱,但总比没有好。这是我的一段代码。由于我公司的限制,我不能再添加了。

            COMMIT TRAN T1;
        END TRY
        BEGIN CATCH
            -- Save the error.
            SET @ErrorNumber = ERROR_NUMBER();
            SET @ErrorMessage = ERROR_MESSAGE();
            SET @ErrorLine = ERROR_LINE();
            -- Put GSR.dbo.BlahBlahTable back the way it was.
            ROLLBACK TRAN T1;   
        END CATCH
        -- Output a possible error message. Knowing what line the error happened at really helps with debugging.
        SELECT @ErrorNumber as ErrorNumber,@ErrorMessage as ErrorMessage,@ErrorLine AS LineNumber;
        

        【讨论】:

          猜你喜欢
          • 2011-02-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-28
          • 2011-09-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多