在事务中抛出异常



今天我试图在一个存储过程中编写一个事务,该存储过程在某些情况下返回不同的数字。c#代码有必要知道错误究竟是什么。问题是,如果事务没有完成,它会抛出同样的异常。

我不能在事务中抛出异常,总是给出错误的语法。我尝试使用这个模式:
THROW 51000, 'The record does not exist.', 1;

是否有可能做出这样的东西:

BEGIN TRAN
  TRY
  IF...
     THROW ERROR 4;
  IF..
    THROW ERROR 2;
COMPLETE TRAN;
CATCH
   RETURN ERROR NUMBER;

我只需要从存储过程返回的错误的具体数目。

你能给我举个例子吗?

注:我忘了我们的sql server是哪个版本了,不,我不在办公室。不是2008年就是2012年

可以使用以下语法:

BEGIN TRY
     BEGIN TRANSACTION
          IF ...  RAISERROR(51001, 16, 1)
          IF ...  RAISERROR(51002, 16, 1)
     COMMIT TRANSACTION
END TRY
BEGIN CATCH
     DECLARE @ErrorNumber INT = ERROR_NUMBER();
     DECLARE @ErrorLine INT = ERROR_LINE();
     DECLARE @ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE();
     DECLARE @ErrorSeverity INT = ERROR_SEVERITY();
     DECLARE @ErrorState INT = ERROR_STATE();
     IF @@TRANCOUNT > 0
          ROLLBACK TRANSACTION;
     RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
END CATCH

错误数应大于50000。可以使用sp_addmessage程序添加。Sql Server 2012中引入Throw。有一些不同之处。您可以在MSDN中轻松找到它们。

您应该使用RAISERROR(详细信息请参阅文档)而不是THROW(请参阅文档)

THROW只会在CATCH块中重新抛出一个现有的异常,而不是触发一个完整的新异常。它是在SQL Server 2012中引入的。抛出错误的两个函数的主要用法非常简单。如果在TRY中发生错误,并且您使用RAISERRORCATCH块中重新抛出错误-因为它在2008年是最先进的状态-它可能提供许多有用的信息,但是发生错误的代码行被转移到使用RAISERROR提出错误的行,而不是在真正发生错误的行。如果使用THROW,它将重新抛出错误并包含所有信息,甚至包括最初发生错误的原始行。

你可以自己抛出一个异常:

RAISERROR(N'Your Errormessage',16,1)

顺便说一下,RAISERROR使用的每个错误消息将具有50000或以上的errormessage。您可以用自己的id(大于50000)定义自己的错误消息。如果您定义了自己的消息id,则可以使用RAISERROR抛出用户定义的错误,如下所示:

RAISERROR(50001,16,1)

侧信息:您可以重载RAISERROR来解析错误消息中的值

RAISERROR(N'A error occurred while iterating over row ID %i',16,1,@rowId)

最新更新