我有一个存储过程,它从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。
答案 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