0

我正在更改一些代码以利用 SQL Server 2005 中的 TRY ... CATCH。您找到了哪些成功的策略来使用它?

我正在考虑创建一个存储过程,它调用提供错误详细信息的系统函数,回滚任何打开的事务并引发错误。有没有更好的办法?

4

2 回答 2

2

这是我正在使用的模板示例:

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 和事务管理方面可以和应该做的事情:您是否使用分布式事务?你有链接服务器吗?您的某些维护工作是否需要恢复命名保存点功能?您需要调用者访问原始异常代码吗?您是否想保留异常严重性,也许是为了您的自动监控和警报通知?重点是一些模板和实践在某些情况下有效,有些在其他情况下有效。到目前为止,我发布的模板对我的大多数情况都证明是好的。

于 2009-06-17T13:11:17.467 回答
1

我完全按照您描述的方式使用 TRY...CATCH,RAISERROR在 CATCH 块的末尾使用将错误传递回调用者。这也允许您处理存储过程中的某些错误代码。

于 2009-06-17T12:58:17.960 回答