今天我试图在一个存储过程中编写一个事务,在某个特定的回程中返回不同的数字。 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;
我只需要从存储过程返回的特定错误数。
你能举个例子吗?
P.S。我忘了哪个是我们的sql server的版本,不,我不在办公室。它是2008年或2012年。
答案 0 :(得分:3)
您可以使用以下语法:
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
程序。 Throw
中引入了Sql Server 2012
。有一些差异。您可以在MSDN
中轻松找到它们。
答案 1 :(得分:0)
您应该使用RAISERROR
(在documentation中阅读更多内容)而不是THROW
(请参阅documentation)。
THROW
只会在CATCH
块中重新抛出现有异常,而不会触发完整的新异常。它是在SQL Server 2012中引入的。抛出错误的两个函数的主要用法非常简单。如果TRY
内发生错误,并且您使用CATCH
在RAISERROR
块中重新抛出错误 - 这是2008年的最新状态 - 它可能会提供许多有用的信息但是发生错误的代码行转移到使用RAISERROR
引发错误的行,而不是错误发生的行。使用THROW
它将使用所有信息重新抛出错误,甚至是最初发生错误的原始行。
相反,您可以使用此方法抛出自己的异常:
RAISERROR(N'Your Errormessage',16,1)
顺便说一下,RAISERROR
使用的每条错误消息的错误消息都是50000或更高。您可以使用自己的ID定义自己的错误消息(大于50000)。如果您定义了自己的消息ID,则可以使用RAISERROR
抛出用户定义的错误,如下所示:
RAISERROR(50001,16,1)
旁边信息:您可以重载RAISERROR
以将值解析为错误消息。
RAISERROR(N'A error occurred while iterating over row ID %i',16,1,@rowId)