为什么程序没有进入catch块

时间:2013-04-05 04:17:57

标签: sql-server sql-server-2008

我有一个存储过程,它从Entity表中选择我们数据库中不存在的条目。

在下面的代码中,如果我执行存储过程,它不会进入catch块,而对于try块中的每个错误,它应该自动转到catch块。

我无法理解原因

Create PROCEDURE AddUpdateEntity
   (@Name VARCHAR(20),
    @Age SMALLINT)
AS
  BEGIN TRY
     SELECT NAME, Age FROM Entity WHERE NAME = @name AND Age = @Age
  END TRY
  BEGIN CATCH
     SELECT ERROR_NUMBER() StatusCode, ERROR_MESSAGE() [Message]
  END CATCH
GO

/* Command to execute the SP */
EXEC AddUpdateEntity 'Sandeep',20

此execute语句显示错误“Invalid Entity Object”但未调用catch块。

存储过程已崩溃并显示消息

  

Msg 208,Level 16,State 1,Procedure AddUpdateEntity,Line 10
  Nom d'objet'实体'非valide。

2 个答案:

答案 0 :(得分:9)

根据MSDN(请点击链接http://msdn.microsoft.com/en-us/library/ms175976.aspx

  

错误不受TRY ... CATCH构造

的影响      

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

     
      
  • 严重性为10或更低的警告或信息性消息。

  •   
  • 严重性为20或更高的错误,用于停止会话的SQL Server数据库引擎任务处理。如果发生严重性为20或更高且数据库连接未中断的错误,则TRY ... CATCH将处理错误。

  •   
  • 注意事项,例如客户端中断请求或客户端连接中断。

  •   
  • 系统管理员使用KILL语句结束会话时。

  •   
     

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

     
      
  • 编译阻止批量运行的错误,例如语法错误。

  •   
  • 语句级重新编译期间发生的错误,例如由于延迟名称解析而在编译后发生的对象名称解析错误。

  •   
     

这些错误将返回到运行批处理,存储过程或触发器的级别。

     

如果在TRY块内的较低执行级别(例如,执行sp_executesql或用户定义的存储过程时)的编译或语句级重新编译期间发生错误,则错误发生在低于TRY的级别... CATCH构造并将由关联的CATCH块处理。

希望以上描述能解决您的问题。

答案 1 :(得分:1)

它永远不会进入CATCH块,因为没有从查询返回任何行。不返回任何行的SQL查询不是错误;这是预期的行为。

正如其他人所指出的,您看到的错误似乎是编译时错误,因为Entity表不存在。

您可以尝试使用带有sp_executesql的动态sql强制SP仅在运行时检查表是否存在。

BEGIN TRY
    DECLARE @sqlStr NVARCHAR(4000),
            @sqlParams NVARCHAR(400);
    SET @sqlStr = N'SELECT Name, Age FROM Entity WHERE Name=@Name AND Age=@Age';
    SET @sqlParams = '@Name VARCHAR(20), @Age SMALLINT';
    sp_executesql @sqlStr, @sqlParams, @Name = @Name, @Age = @Age
END TRY
BEGIN CATCH
    SELECT ERROR_NUMBER() StatusCode, ERROR_MESSAGE() [Message]
END CATCH