开发者社区> 问答> 正文

为什么当xact_abort打开时,Sql Server在raiserror之后仍继续执行?

我只是对TSQL中的某些东西感到惊讶。我以为如果打开xact_abort,调用类似

raiserror('Something bad happened', 16, 1);

将停止执行存储过程(或任何批处理)。

但是我的ADO.NET错误消息恰恰相反。我在异常消息中同时收到了raiserror错误消息,以及在此之后发生的下一件事。

这是我的解决方法(无论如何,这是我的习惯),但似乎没有必要:

if @somethingBadHappened
    begin;
        raiserror('Something bad happened', 16, 1);
        return;
    end;

展开
收起
心有灵_夕 2019-12-28 22:30:36 665 0
1 条回答
写回答
取消 提交回答
  • 如果使用try / catch块,严重性为11-19的raiserror错误号将导致执行跳转到catch块。

    任何高于16的严重性都是系统错误。为了演示以下代码,我们设置了一个try / catch块并执行了一个我们认为会失败的存储过程:

    假设我们有一个表[dbo]。[错误]用来保存错误假设我们有一个存储过程[dbo]。[AssumeThisFails],当我们执行它时将失败

    -- first lets build a temporary table to hold errors
    if (object_id('tempdb..#RAISERRORS') is null)
     create table #RAISERRORS (ErrorNumber int, ErrorMessage varchar(400), ErrorSeverity int, ErrorState int, ErrorLine int, ErrorProcedure varchar(128));
    
    -- this will determine if the transaction level of the query to programatically determine if we need to begin a new transaction or create a save point to rollback to
    declare @tc as int;
    set @tc = @@trancount;
    if (@tc = 0)
     begin transaction;
    else
     save transaction myTransaction;
    
    -- the code in the try block will be executed
    begin try
     declare @return_value = '0';
     set @return_value = '0';
     declare
      @ErrorNumber as int,
      @ErrorMessage as varchar(400),
      @ErrorSeverity as int,
      @ErrorState as int,
      @ErrorLine as int,
      @ErrorProcedure as varchar(128);
    
    
     -- assume that this procedure fails...
     exec @return_value = [dbo].[AssumeThisFails]
     if (@return_value <> 0)
      raiserror('This is my error message', 17, 1);
    
     -- the error severity of 17 will be considered a system error execution of this query will skip the following statements and resume at the begin catch block
     if (@tc = 0)
      commit transaction;
     return(0);
    end try
    
    
    -- the code in the catch block will be executed on raiserror("message", 17, 1)
    begin catch
      select
       @ErrorNumber = ERROR_NUMBER(),
       @ErrorMessage = ERROR_MESSAGE(),
       @ErrorSeverity = ERROR_SEVERITY(),
       @ErrorState = ERROR_STATE(),
       @ErrorLine = ERROR_LINE(),
       @ErrorProcedure = ERROR_PROCEDURE();
    
      insert #RAISERRORS (ErrorNumber, ErrorMessage, ErrorSeverity, ErrorState, ErrorLine, ErrorProcedure)
       values (@ErrorNumber, @ErrorMessage, @ErrorSeverity, @ErrorState, @ErrorLine, @ErrorProcedure);
    
      -- if i started the transaction
      if (@tc = 0)
      begin
       if (XACT_STATE() <> 0)
       begin
         select * from #RAISERRORS;
        rollback transaction;
        insert into [dbo].[Errors] (ErrorNumber, ErrorMessage, ErrorSeverity, ErrorState, ErrorLine, ErrorProcedure)
         select * from #RAISERRORS;
        insert [dbo].[Errors] (ErrorNumber, ErrorMessage, ErrorSeverity, ErrorState, ErrorLine, ErrorProcedure)
         values (@ErrorNumber, @ErrorMessage, @ErrorSeverity, @ErrorState, @ErrorLine, @ErrorProcedure);
        return(1);
       end
      end
      -- if i didn't start the transaction
      if (XACT_STATE() = 1)
      begin
       rollback transaction myTransaction;
       if (object_id('tempdb..#RAISERRORS') is not null)
        insert #RAISERRORS (ErrorNumber, ErrorMessage, ErrorSeverity, ErrorState, ErrorLine, ErrorProcedure)
         values (@ErrorNumber, @ErrorMessage, @ErrorSeverity, @ErrorState, @ErrorLine, @ErrorProcedure);
       else
        raiserror(@ErrorMessage, @ErrorSeverity, @ErrorState);
       return(2); 
      end
      else if (XACT_STATE() = -1)
      begin
       rollback transaction;
       if (object_id('tempdb..#RAISERRORS') is not null)
        insert #RAISERRORS (ErrorNumber, ErrorMessage, ErrorSeverity, ErrorState, ErrorLine, ErrorProcedure)
         values (@ErrorNumber, @ErrorMessage, @ErrorSeverity, @ErrorState, @ErrorLine, @ErrorProcedure);
       else
        raiserror(@ErrorMessage, @ErrorSeverity, @ErrorState);
       return(3);
      end
     end catch
    end
    
    2019-12-28 22:31:14
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
SQL Server 2017 立即下载
GeoMesa on Spark SQL 立即下载
原生SQL on Hadoop引擎- Apache HAWQ 2.x最新技术解密malili 立即下载