1

我有一个存储过程,它正在从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

此执行语句显示错误“无效的实体对象”但未调用 catch 块。

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

消息 208,级别 16,状态 1,过程 AddUpdateEntity,第 10 行
Nom d'objet 'Entity' 无效。

4

2 回答 2

9

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

不受 TRY…CATCH 构造影响的错误

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

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

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

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

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

以下类型的错误发生在与 TRY...CATCH 构造相同的执行级别时,不会由 CATCH 块处理:

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

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

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

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

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

于 2013-04-05T05:08:34.290 回答
1

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

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

您可以尝试使用动态 sqlsp_executesql来强制 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
于 2013-04-05T04:23:06.503 回答