TRY..CATCH Error_Line().... line

时间:2017-10-02 15:36:18

标签: tsql error-handling

我正在查看MS提供的这个示例,因为我正在尝试学习Try...Catch。我理解语法和输出(大部分),但我有一个问题:

输出会将Error_Line显示为“4”。这很好,但如果我删除GOBEGIN TRY之间的换行符,则会将Error_Line显示为“3”。我只是想了解这里的逻辑。

我想象的是,SQL Server通过在GO之后立即开始批处理来计算行数,即使该行为空白但我不确定。任何人都可以澄清吗?如果这个理论是正确的,那么如果用这样的换行符编写脚本会不会使查找错误变得困难?

-- Verify that the stored procedure does not already exist.  
IF OBJECT_ID ( 'usp_GetErrorInfo', 'P' ) IS NOT NULL   
    DROP PROCEDURE usp_GetErrorInfo;  
GO  

-- Create procedure to retrieve error information.  
CREATE PROCEDURE usp_GetErrorInfo  
AS  
SELECT  
    ERROR_NUMBER() AS ErrorNumber  
    ,ERROR_SEVERITY() AS ErrorSeverity  
    ,ERROR_STATE() AS ErrorState  
    ,ERROR_PROCEDURE() AS ErrorProcedure  
    ,ERROR_LINE() AS ErrorLine  
    ,ERROR_MESSAGE() AS ErrorMessage;  
GO  
                                        --Line 1
BEGIN TRY                               --Line 2
    -- Generate divide-by-zero error.   --Line 3
    SELECT 1/0;                         --Line 4
END TRY  
BEGIN CATCH  
    -- Execute error retrieval routine.  
    EXECUTE usp_GetErrorInfo;  
END CATCH; 

1 个答案:

答案 0 :(得分:0)

您无法真正依赖ERROR_LINE(),尤其是在内部存储过程中抛出错误或者执行了动态T-SQL语句时。

但你真的需要确切的错误线吗?

  1. 在实际生产代码中,导致错误的行的修复可能不像在您的示例中那么明显;
  2. 最好使用相应的输入参数调试存储过程或函数以重现错误
  3. 通过这种方式,解决问题会更容易。为了调试SQL例程:

    1. 只是编写脚本
    2. 删除dropcreate内容
    3. 在输入参数前面添加声明,并使用导致错误的值
    4. 对其进行初始化

      基本上,您可能会发现有用的两件事,而不是确切的错误行(可以很容易地获得正确的输入参数并执行例程):

      • 哪个路由导致错误(例如,您可以向用户usp_GetErrorInfo SP添加其他参数,这也会产生SP名称
      • 导致错误的输入参数(这可以使用分隔表来记录CATCH子句中的错误 - 您只需在表中插入输入参数和有关错误的信息)

      有了这些信息,很容易重现并解决问题(在很多情况下)。