SQL Server TRY ... CATCH没有捕获错误

时间:2015-10-14 16:20:32

标签: sql-server tsql try-catch

BEGIN TRY
    EXEC N'EXEC sp_testlinkedserver N''[MyLinkedServer]'';';
END TRY
BEGIN CATCH
    SELECT 'LinkedServerDown' AS Result
    RETURN
END CATCH
SELECT TOP(1) FirstName FROM [MyLinkedServer].TestDatabase.dbo.Customer

我在SQL Server中使用TRY ... CATCH的第一次体验到目前为止并没有让我印象深刻。

我已停止链接服务器上的SQL服务,以尝试测试我们的链接服务器已关闭,无法访问等情况。

此代码不会捕获任何错误,而是抛出“登录超时已过期”和“发生网络相关或特定于实例的错误...”错误,并停止执行其余代码。

我的SQL TRY ... CATCH块是否设置不正确?

3 个答案:

答案 0 :(得分:3)

根据MSDN,sp_testlinkedserver做的是

  

测试与链接服务器的连接。如果测试不成功   该程序因失败而引发异常。

因此,当您编译代码(SP)时,sp_testlinkedserver会检查连接。但是你可以推迟使用动态SQL来捕获它。

喜欢这个 -

BEGIN TRY
    EXEC sp_executesql N'EXEC sp_testlinkedserver [192.168.51.81];';
END TRY
BEGIN CATCH
    SELECT 'LinkedServerDown' AS Result
END CATCH

答案 1 :(得分:0)

来自MSDN

  

不受TRY ... CATCH构造影响的错误

     

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

     
      
  1. 严重性为10或10的警告或信息性消息   低。
  2.   
  3. 严重性为20或更高的错误,可以阻止SQL Server   会话的数据库引擎任务处理。如果发生错误   严重性为20或更高且数据库连接不是   中断,TRY ...... CATCH将处理错误。
  4.   
  5. 注意事项,例如客户端中断请求或客户端损坏   连接。
  6.   
  7. 系统管理员使用该会话结束会话时   KILL声明。
  8.         

    当CATCH块不处理以下类型的错误   它们与TRY ... CATCH结构处于相同的执行级别:

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

答案 2 :(得分:0)

您需要创建您的最终testlinkedserver存储过程。这还将捕获登录超时错误。

exec dbo.USP_testlinkedserver 'myServerNameHere'

定义如下:

CREATE PROCEDURE USP_testlinkedserver 
    @ServerName sysname
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @statement NVARCHAR(MAX), @errorMessage NVARCHAR(MAX)

    SET @statement = N'SELECT * FROM OPENQUERY('+QUOTENAME(@ServerName,'[')+', ''SELECT 1'')'

BEGIN TRY
    -- run the query
    EXEC sp_executesql @stmt = @statement;
END TRY
BEGIN CATCH
    -- show custom message
    SET @errorMessage=QUOTENAME(@ServerName,'[') + ' linked server is not available. ' + ERROR_MESSAGE()
    Raiserror(@errorMessage,16,1)
END CATCH;

END