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块是否设置不正确?
答案 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构造不会捕获以下条件:
- 严重性为10或10的警告或信息性消息 低。
- 严重性为20或更高的错误,可以阻止SQL Server 会话的数据库引擎任务处理。如果发生错误 严重性为20或更高且数据库连接不是 中断,TRY ...... CATCH将处理错误。
- 注意事项,例如客户端中断请求或客户端损坏 连接。
- 系统管理员使用该会话结束会话时 KILL声明。
醇>当CATCH块不处理以下类型的错误 它们与TRY ... CATCH结构处于相同的执行级别:
- 编译阻止批处理的错误,例如语法错误 运行
- 语句级重新编译期间发生的错误,例如 编译后发生的对象名称解析错误,因为 延迟名称解析。
醇>
答案 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