【问题标题】:Why the procedure is not going into the catch block为什么程序没有进入 catch 块
【发布时间】:2013-03-27 09:23:12
【问题描述】:

我有一个存储过程,它正在从我们的数据库中不存在的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' 无效。

【问题讨论】:

  • 错误是否在您的 TRY 块之外?仅当错误发生在您的 SELECT 中时才会调用 catch 块
  • 由于table 本身不存在,因此代码不会编译。因此catch block 不会执行

标签: sql-server sql-server-2008


【解决方案1】:

根据 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 块处理。

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

【讨论】:

  • 这意味着 try and catch 只适用于严重性在 10 到 20 之间的错误?
【解决方案2】:

它永远不会进入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

【讨论】:

  • 其返回错误消息 208,级别 16,状态 1,过程 AddUpdateEntity,第 10 行 Nom d'objet 'Tmp' 无效。
  • @SandeepKumar 我不会说法语,但我认为这意味着您发布的代码中没有包含一个名为“Tmp”的对象。除非我知道完整的上下文,否则我将无法确定问题的根源。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-07
相关资源
最近更新 更多