正常来说是这样的.有没有办法自动回滚自定义异常?
因为嵌套的存储过程比较多,如果每次执行一个存储过程以后判断返回值的话太shit了

解决方案 »

  1.   

    create proc p1 as
    set xact_abort on
    begin tran
    if xxxx
    begin
     raierror('xx',16,1)
     rollback tran 
     return
    end
    commit tran正常思路来写的话应该是这个过程,这个如果嵌套的话就麻烦了
    我现在能想到的解决方法是有几个
    1.在每个存储过程的raiserror后面return -1,然后每次执行以后判断,相当那个的做法.......
    2.用TRY CATCH捕捉,相对于上一个来说不用执行每个存储过程以后执行,但还是不够优雅
    3.邪道,刚才想到的,xact_abort对非自定义异常有效果,raiserror直接用一个出现数据库异常的存储
      过程代替.create proc ud_raiserror @errorstring varchar(200)
    as
    set xact abort on
    raiserror(@errorstring,16,1)
    insert into tt select 1tt这个表不存在,所以执行这个肯定会报数据库错误.这样做可能性能不太好.对于大型操作来说可以无视掉这些,但一些繁琐的操作可能不太适合.或者说能有一个占用资源非常小的数据库异常.
    不知道大家平时怎么处理这些问题 ??
      

  2.   

    没看懂呀 
    楼主什么意思?raiserror怎么回滚?就抛一错误呀
    还是怎么让set xact_abort on 开启后的 begin tran commit tran回滚?
    在raiserror后面加一句
    if @@error>0 
    rollback 
    不行吗
      

  3.   

    以下代码示例显示如何在 TRY 块中使用 RAISERROR 使执行跳至关联的 CATCH 块中。它还显示了如何使用 RAISERROR 返回有关调用 CATCH 块的错误的信息。 复制代码 
    BEGIN TRY
        -- RAISERROR with severity 11-19 will cause execution to 
        -- jump to the CATCH block
        RAISERROR ('Error raised in TRY block.', -- Message text.
                   16, -- Severity.
                   1 -- State.
                   );
    END TRY
    BEGIN CATCH
        DECLARE @ErrorMessage NVARCHAR(4000);
        DECLARE @ErrorSeverity INT;
        DECLARE @ErrorState INT;    SELECT @ErrorMessage = ERROR_MESSAGE(),
               @ErrorSeverity = ERROR_SEVERITY(),
               @ErrorState = ERROR_STATE();    -- Use RAISERROR inside the CATCH block to return 
        -- error information about the original error that 
        -- caused execution to jump to the CATCH block.
        RAISERROR (@ErrorMessage, -- Message text.
                   @ErrorSeverity, -- Severity.
                   @ErrorState -- State.
                   );
    END CATCH;
     
      

  4.   


    恩,是这个意思.
    用try catch实现类似set xact_abort on的对raiserror也适用的代码
    BEGIN TRY--代码
    --RAISERROREND TRY
    BEGIN CATCH
        WHILE @@TRANCOUNT<>0
             ROLLBACK TRAN
        DECLARE @ErrorMessage NVARCHAR(4000);
        DECLARE @ErrorSeverity INT;
        DECLARE @ErrorState INT;    SELECT 
            @ErrorMessage = ERROR_MESSAGE(),
            @ErrorSeverity = ERROR_SEVERITY(),
            @ErrorState = ERROR_STATE();
            
        RAISERROR (@ErrorMessage, -- Message text.
                   @ErrorSeverity, -- Severity.
                   @ErrorState -- State.
                   );
    END CATCH;有点不太好的地方是这个代码块太繁复了,set xact_abort on一个语句解决的需要用这么长一个代码块来解决
      

  5.   

    使用自定义存储过程报异常CREATE PROC ud_RAISERROR @errorstring nvarchar(4000) 
    AS
    RAISERROR(@errorstring,16,1)
    INSERT INTO T.T SELECT 1T.T这个表不存在