【问题标题】:T-SQL Clear ErrorsT-SQL 清除错误
【发布时间】:2013-11-26 20:43:29
【问题描述】:

我正在尝试清理一个巨大的遗留 T-SQL 存储过程。我们从 BizTalk 中调用它。 BizTalk 具有在出错时重试发送端口(例如每 5 分钟 3 次)的功能。

例如,存储过程检测到丢失的数据并执行以下操作:

   if @CompanyID is null        raiserror( '@CompanyID is missing', 18, 1 );

“Begin Catch”逻辑会处理某些错误(即将它们记录到错误表中),然后执行“Return 0”。我相信之前的程序员认为这会阻止 BizTalk 再次调用它。但现在我有一个踪迹,我可以证明 BizTalk 每隔 y 分钟就调用它 x 次重试(由 BizTalk SendPort 定义)。

我目前的想法是,如果@@Error 和@@ErrorMessage 不为null,BizTalk 仍然认为它有错误,并会重试。

关于如何彻底清除错误有什么想法吗?我希望做一个小的快速修复,没有时间进行重大重写。

【问题讨论】:

    标签: sql-server-2008 stored-procedures error-handling biztalk biztalk-2010


    【解决方案1】:

    这可能不适用,但如果您提高错误级别,这可能会通过记录更严重的错误来解决问题。通常,我认为 1 到 19 与更多信息相关,20 之后被认为是致命错误,并且也会在 SQL 日志中记录错误。这可能会强制程序停止,即使处理程序仍然认为它是打开的。您可以随时对此进行测试,看看它是否适合您的需求,如果不适合则将其改回。您也可以尝试更合适的 BEGIN END 阻塞,以及不返回捕获值的通用返回值,例如:

    IF @CompanyID is NULL
      BEGIN
         Raiserror('@CompanyID is missing', 20, 1);
         return;
      END
    

    更多关于错误捕捉的信息:http://msdn.microsoft.com/en-us/library/ms178592.aspx

    【讨论】:

    • 您的代码是有道理的,但我认为大约有 10 个或更多 Raiserrors 语句,并且他们试图使用通用处理程序将错误写入数据库表。我的研究实际上开始了,因为一些错误对于表中的列大小来说太大了,我们得到了一个误导性的截断错误消息,而不是底层的 Raiserrror 消息。我现在没有分配时间来纠正所有问题,需要修补它。
    • 哦,还有一点。 BizTalk 有点愚蠢,在你的代码中,如果他看到错误,他会尝试重试存储过程。这对于超时、死锁等非常有用,但对于基于错误数据的用户错误,允许 BizTalk 使用相同的错误数据重新运行存储的过程是非常糟糕的,因为结果显然是相同的。因此,需要处理错误,并像存储过程成功一样返回,这样 BizTalk 就不会打扰重试。
    • 您应该能够在 SQL Management Studio 中按“CTRL + H”(取决于版本)并将“缺失,18”批量替换为“缺失,20”并引发错误级别状态强制更高的数字。这本身可能会迫使操作停止。
    • 我想清楚,但我想我不是。如果我抛出更高级别的错误,BizTalk 将重试存储过程。 BizTalk 配置为每 5 分钟重试 3 次。这对于死锁和超时非常有用。但是当出现用户数据错误时,我想处理错误并优雅地返回。会只是“回归”吗?新信息:我仍然在我的 BizTalk 事件日志中看到截断错误,即使我正在跟踪几乎每一行代码,我也看不到截断的位置,所以这就是我现在正在查看的内容。跨度>
    • 如果你想继续,你不应该使用 raiserror。 return 相当于我在 SQL 实现方面的经验。如果您正在尝试开始尝试,开始捕获块,如果停止印刷机处理它不是关键任务,您可以忽略它来处理您遇到的问题。您甚至可以执行 begin catch print '@ID was blank' end catch,它会打印出信息,但不会像错误一样处理它。您可能希望这样做,因为它会继续。
    【解决方案2】:

    如果错误处理是基于 SQL 的,那么听起来您可能希望完全替换 RAISERROR,而是在此时记录您的错误并简单地返回。

    另外,@@Error 永远不会为空。它将在执行的每条语句中返回一个“新”值。如果前面的语句执行成功,它将返回 0,否则将返回错误号....在您的情况下为 18。如果您的逻辑关闭 @@Error,那么您需要确保它在相关语句执行后立即检查(或保存到变量中)。

    更多信息如下。

    http://technet.microsoft.com/en-us/library/ms190193(v=sql.100).aspx

    【讨论】:

    • 就像我说的,目前还不能完全重写。 (参见上面的@djangojazz 的 cmets)。我不依赖@@Error,但恐怕 BizTalk 可能是。但是,catch 中有许多 SQL 语句,它们成功了,因为我读到它应该重置它。
    【解决方案3】:

    我认为这篇文章基本上回答了我的问题(这也是我的一篇文章,以放大与 catch 块内的错误处理有关的澄清):

    T-SQL is error handling totally turned off in a "BEGIN CATCH" block?

    try catch 中的某些语句不会崩溃。他们可以设置错误并且代码不断失败。

    在这种特定情况下,catch 块有一个插入到表中,并且在存储过程中扩展了一列,但在错误表中没有扩展。大约 4 个月前,我们在其他表中扩展了该列,但直到本周我们才发现错误处理程序存在这个隐蔽的隐藏问题。

    我认为 StackOverflow 的另一篇文章最终将有助于回答为什么 BizTalk 将其视为错误的问题。我认为“返回0”会做到这一点。但由于我们遇到了截断问题,因此该错误被发送到 BizTalk。

    在现实世界中,我们很少遇到此错误代码,而且当我们这样做时,导致错误的特定列不会太大。当 QA 人员开始某个测试场景并输入一些无效的航班号以及违规列的特别长的值时,就会出现此错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-18
      • 2012-06-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多