为什么我的SP不会给我一个有用的错误消息?

时间:2017-03-23 17:15:21

标签: sql-server stored-procedures

我有一个SQL Server存储过程,它返回了我常见的错误

"db_ErrorCode Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0."

我在谷歌搜索之后发现的是,它真的说在交易提交之前发生了错误。

有一个

BEGIN TRY            

BEGIN TRANSACTION     

在SP的开头,

COMMIT TRANSACTION            

      END TRY            

   BEGIN CATCH            

  ROLLBACK TRANSACTION            

  SELECT @ErrorNumber = ERROR_NUMBER(),            
   @ErrorLine = ERROR_LINE(),            
   @ErrorMessage = ERROR_MESSAGE()            

  RAISERROR (@Flag, 18, 120);            

      END CATCH               

END        

问题是这些行之间有大约1100行代码,如果有问题,整个SP需要回滚,所以我们不能在其间放置try / catch语句。为什么我的最终Catch块没有返回实际错误,而不是给我无用的事务计数错误?

1 个答案:

答案 0 :(得分:1)

我无法回答为什么Sql Server会在没有看到整行1100行代码的情况下提供错误信息。但是,如果您想知道如何查明错误,我可以给您一些提示。 首先在任何大型存储过程中,我总是将@Debug变量作为输入变量。将它作为最后一个变量,并将其默认值设置为0(不在调试模式下)。如果它有一个默认值,那么将它添加为最后一个变量不应该破坏现有的代码调用。

当您想要调试时,您可以添加测试或结果,以显示已完成的步骤或各种操作的结果。将这些步骤包含在if语句中,如

IF @DEBUG=1 
BEGIN
<add your tests here>
END

您可以在proc中的每个重要步骤之后添加此代码,或者可以在proc中稍后使用其中包含多个步骤的一个或两者。我倾向于通过检查来查看通过proc的步骤中将要发生的事情的状态以及显示最终结果应该是什么的那些状态。

该代码仅在您处于调试模式时执行。您可能放入的东西可能是在proc的那一点打印或选择变量,打印您所在步骤的名称,运行通常作为插入的基础的选择或者之后的结果操作等。

您可以做的另一件事是创建一个表变量来存储完成的步骤。回滚后表变量保持在范围内,因此您可以执行选择并查看在回滚之前已完成的步骤。