Reputation: 33
Today I was trying to write a transaction, within a stored procedure that in certain returns different numbers. It is necessary the C# code to know what exactly was the error. The problem is, that if the transaction is not completed it throws the same exception.
I could not throw exception inside the transaction, always was giving wrong syntax. I was trying with this pattern:
THROW 51000, 'The record does not exist.', 1;
Is it possible to make something like this:
BEGIN TRAN
TRY
IF...
THROW ERROR 4;
IF..
THROW ERROR 2;
COMPLETE TRAN;
CATCH
RETURN ERROR NUMBER;
I just need the specific number of the error returned from the stored procedure.
Can you please give me an example of that?
P.S. I forgot which is the version of our sql server, no I'm not in the office. It is either 2008 or 2012.
Upvotes: 1
Views: 9083
Reputation: 3935
You should use RAISERROR
(read more in the documentation) instead of THROW
(see documentation).
THROW
will only re-throw an existing exception inside a CATCH
block instead triggering a complete new exception. It was introduced in SQL Server 2012. The main usage for two functions which throw an error is quite simple. If an error occur inside a TRY
, and you re-throw the error in your CATCH
block using RAISERROR
- as it was state of the art in 2008 - it may provide many useful information but the codeline in which the error occurred is shifted to the line where you raised the error using RAISERROR
, not in the line where the error really occurred. Using THROW
it will re-throw the error with all information, even the original line in which the error originally occurred.
Instead you can throw an own exception using this:
RAISERROR(N'Your Errormessage',16,1)
By the way, each error message used by RAISERROR
will have a errormessage of 50000 or above. You can define your own error messages with their own id's (above 50000). If you defined your own message id, you can use RAISERROR
to throw your user defined error like this:
RAISERROR(50001,16,1)
Side info: You can overload RAISERROR
to parse values into your error message.
RAISERROR(N'A error occurred while iterating over row ID %i',16,1,@rowId)
Upvotes: 0
Reputation: 35780
You can use the following syntax:
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
Error number should be greater then 50000
. You can add those with sp_addmessage
procedure. Throw
was introduced in Sql Server 2012
. There are some differences. You can easily find them in MSDN
.
Upvotes: 4