sp_executesql里面试试&抓住

时间:2013-08-22 10:04:29

标签: sql-server try-catch dynamic-sql sp-executesql

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

当MyLinkedServer中不存在表T1时,上述脚本失败 而不是被导向Catch部分。 我错过了什么?

为了清楚起见:原始过程使用参数在过程中构建@SQL dynamicaly。

谢谢!

1 个答案:

答案 0 :(得分: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块运行... Error Handling in SQL 2005 and Later详细解释了这个问题。您必须创建外部作用域以捕获内部作用域中发生的编译错误。这正是您在发布的示例中所做的!