2
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 Error_Message()
End Catch

当表 T1 在 MyLinkedServer 中不存在而不是被定向到 Catch 部分时,上述脚本将失败。我想念什么?

只是要清楚一点:原始过程使用参数在过程内部动态构造@SQL。

谢谢!

4

1 回答 1

1

不,上面的脚本不会失败,并且完全按照您的预期工作:

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 和更高版本的错误处理中得到了很好的解释。您必须创建一个外部作用域来捕获内部作用域中发生的编译错误。这正是您在发布的示例中所做的!

于 2013-08-22T10:23:14.850 回答