2

我有一个包含 try-catch 块的存储过程。在 catch 块中,我调用 raiserror() 以在某些上下文中重新抛出错误。

我期待如果发生错误,将调用 raiserror() 并且执行将立即从存储过程返回到调用代码。但是,情况似乎并非如此。看起来存储过程的执行一直持续到它遇到 return 语句,然后 raiserror() 生效。

这是正确的吗? raiserror() 在调用 return 或到达存储过程的结尾之前不会生效?

我正在使用 SQL Server 2012。

编辑: 作为对存储过程详细信息请求的回复,以下是相关的代码片段:

DECLARE @ErrMsg VARCHAR(127) = 'Error in stored procedure ' + OBJECT_NAME(@@PROCID) + ': %s';

declare @UpdateDateRecordCount table (LastUpdated datetime, NumberRecords int);
begin try;
    insert into @UpdateDateRecordCount (LastUpdated, NumberRecords)
    exec sp_ExecuteSql 
        @UpdateCountQuery, 
        N'@LastUpdated datetime', 
        @LastUpdated = @LastUpdated;

    if @@rowcount <= 0
    begin;
        return 0;
    end; 
end try
begin catch;
    declare @InsertError varchar(128) = 'Error getting updated date record count: ' 
        + ERROR_MESSAGE();
    RAISERROR (@ErrMsg, 16, 1, @InsertError);
end catch;

-- Attempt to loop through the records in @UpdateDateRecordCount...

@UpdateCountQuery 参数将设置为:

N'select LastUpdated, count(*) from dbo.Part where LastUpdated > @LastUpdated group by LastUpdated;'
4

3 回答 3

4

据我了解,如果您希望停止执行,您需要在TRY块中引发错误,然后在CATCH块中再次引发错误,这将确保错误被​​“引发”给调用者。

或者您可以在块中的RETURN语句之后添加一个语句。这将退出过程并返回给调用者。RAISERRORCATCH

此外,正如 MSDN 所建议的,您应该尝试使用THROW语句,而不是RAISERROR因为它(RAISERROR)将被逐步淘汰。

于 2013-08-14T06:28:47.257 回答
3

这不是它在 T-SQL 中的工作方式。文档中没有任何内容TRY...CATCHRAISERROR指定任何将覆盖的特殊情况:

当 CATCH 块中的代码完成时,控制权立即传递给 END CATCH 语句之后的语句。由 CATCH 块捕获的错误不会返回给调用应用程序。如果必须将错误信息的任何部分返回给应用程序,则 CATCH 块中的代码必须使用诸如 SELECT 结果集或 RAISERROR 和 PRINT 语句之类的机制来执行此操作。

如果要退出存储过程,还需要一个RETURN语句。

于 2013-08-14T06:31:54.930 回答
0

这取决于您使用的严重性级别。以下链接中有更多信息:

http://technet.microsoft.com/en-us/library/ms178592.aspx

但是引用这篇文章:

RAISERROR 生成的错误与数据库引擎代码生成的错误相同。RAISERROR 指定的值由 ERROR_LINE、ERROR_MESSAGE、ERROR_NUMBER、ERROR_PROCEDURE、ERROR_SEVERITY、ERROR_STATE 和@@ERROR 系统函数报告。当 RAISERROR 在 TRY 块中以 11 或更高的严重性运行时,它会将控制权转移到关联的 CATCH 块。如果运行 RAISERROR,错误将返回给调用者...

因此,如果您的严重级别为 11 或更高,则控制将立即转移到 CATCH 块。

以下示例显示严重级别为 16:

RAISERROR ('Error raised in TRY block.', -- Message text.
16, -- Severity.
1 -- State.
);
于 2013-08-14T03:33:34.870 回答