不,上面的脚本不会失败,并且完全按照您的预期工作:
Begin Try
Declare @SQL NVarchar(Max)='Exec [MyLinkedServer].master.dbo.sp_executesql N''Drop Table [tempdb].dbo.[T1]''';
Print @SQL;
Exec master.dbo.sp_executesql @SQL;
End Try
Begin Catch
print 'in catch'
Print Error_Message()
End Catch
Exec [MyLinkedServer].master.dbo.sp_executesql N'Drop Table [tempdb].dbo.[T1]'
in catch
Could not find server 'MyLinkedServer' in sys.servers. Verify that the correct server name was specified. If necessary, execute the stored procedure sp_addlinkedserver to add the server to sys.servers.
看到那个'in catch'消息了吗?是 catch 块被执行的证明。
但是你是对的,有一个众所周知的问题是编译错误不能在它们发生的范围内被捕获。这绝对是意料之中的,就像在代码编译失败时要求 C# 程序中的 catch 块运行......这个问题在 SQL 2005 和更高版本的错误处理中得到了很好的解释。您必须创建一个外部作用域来捕获内部作用域中发生的编译错误。这正是您在发布的示例中所做的!