我正在更改一些代码以利用 SQL Server 2005 中的 TRY ... CATCH。您找到了哪些成功的策略来使用它?
我正在考虑创建一个存储过程,它调用提供错误详细信息的系统函数,回滚任何打开的事务并引发错误。有没有更好的办法?
我正在更改一些代码以利用 SQL Server 2005 中的 TRY ... CATCH。您找到了哪些成功的策略来使用它?
我正在考虑创建一个存储过程,它调用提供错误详细信息的系统函数,回滚任何打开的事务并引发错误。有没有更好的办法?
这是我正在使用的模板示例:
create procedure [usp_my_procedure_name]
as
begin
set nocount on;
declare @trancount int;
set @trancount = @@trancount;
begin try
if @trancount = 0
begin transaction
else
save transaction usp_my_procedure_name;
-- Do the actual work here
lbexit:
if @trancount = 0
commit;
end try
begin catch
declare @error int, @message varchar(4000), @xstate int;
select @error = ERROR_NUMBER()
, @message = ERROR_MESSAGE()
, @xstate = XACT_STATE();
if @xstate = -1
rollback;
if @xstate = 1 and @trancount = 0
rollback
if @xstate = 1 and @trancount > 0
rollback transaction usp_my_procedure_name;
raiserror ('usp_my_procedure_name: %d: %s', 11, 1, @error, @message) ;
return;
end catch
end
这个模板处理嵌套事务,每个过程只回滚自己的工作(如果可能的话)并让调用者决定是否回滚调用者的工作。重要的是要检查XACT_STATE,因为有可能发生交易失败。MSDN 也有关于这个主题的相当长的文本。
还有各种利害攸关的问题可能会改变您在 TRY/CATCH 和事务管理方面可以和应该做的事情:您是否使用分布式事务?你有链接服务器吗?您的某些维护工作是否需要恢复命名保存点功能?您需要调用者访问原始异常代码吗?您是否想保留异常严重性,也许是为了您的自动监控和警报通知?重点是一些模板和实践在某些情况下有效,有些在其他情况下有效。到目前为止,我发布的模板对我的大多数情况都证明是好的。
我完全按照您描述的方式使用 TRY...CATCH,RAISERROR
在 CATCH 块的末尾使用将错误传递回调用者。这也允许您处理存储过程中的某些错误代码。