So we have multiple stored procs that get used during a morning SQL job and the procs get called in sequence. In the event one of the queries inside a proc fails, we have an error catching/logging that we do for each query so we know exactly what piece failed. But the problem is that some of these processes are very difficult to start over if something failed so I am thinking of implementing a TRANSACTION in each stored proc.
The current procedure is similar to this:
CREATE PROCEDURE [dbo].[spStep01]
(
@Return_Message Varchar(1024) OUT -- Error messages returned to the calling program
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @ErrorCode int
DECLARE @ApplicationNumber int
DECLARE @TaskNumber int
DECLARE @TaskCompleted smallint
DECLARE @TaskFailed smallint
DECLARE @TaskRunning smallint
DECLARE @ErrorSeverity smallint
DECLARE @ErrorState smallint
SELECT @ErrorCode = @@ERROR
SELECT @ApplicationNumber = 10
SELECT @TaskNumber = 1
SELECT @TaskCompleted = 0
SELECT @TaskFailed = -1
SELECT @TaskRunning = 1
SELECT @ErrorSeverity = 16
SELECT @ErrorState = 1
/***************************************************************************
* first insert
***************************************************************************/
BEGIN TRY
INSERT INTO ...
END TRY
BEGIN CATCH
SELECT @Return_Message = 'FAILED - first insert did not populate'
EXEC dbo.spTrackTask '', @ApplicationNumber, @TaskNumber, @TaskFailed, @Return_Message
RAISERROR (@Return_Message, @ErrorSeverity, @ErrorState)
RETURN
END CATCH
/***************************************************************************
* second insert
***************************************************************************/
BEGIN TRY
INSERT INTO ...
END TRY
BEGIN CATCH
SELECT @Return_Message = 'FAILED - second insert did not populate'
EXEC dbo.spTrackTask '', @ApplicationNumber, @TaskNumber, @TaskFailed, @Return_Message
RAISERROR (@Return_Message, @ErrorSeverity, @ErrorState)
RETURN
END CATCH
/***************************************************************************
* Procedure has completed successfully
***************************************************************************/
SELECT @Return_Message = 'SUCCESS - Inserts were complete'
EXEC dbo.spTrackTask '', @ApplicationNumber, @TaskNumber, @TaskCompleted, @Return_Message
/*************************************
* Get the Error Message for @@Error
*************************************/
IF @ErrorCode <> 0
BEGIN
SELECT @Return_Message = [Description] -- Return the SQL Server error
FROM master.dbo.SYSMESSAGES
WHERE error = @ErrorCode
END
/*************************************
* Return from the Stored Procedure
*************************************/
RETURN @ErrorCode -- =0 if success, <>0 if failure
END
What I am trying to determine is if I wrap all of the TRY/CATCH blocks in a TRANSACTION and an error is raised if it will rollback everything. I looked around on SO and found a few examples of one TRY/CATCH block but we would have multiple in most of the stored procs. I don’t have much experience with transactions so I am not 100% sure how to implement it correctly in this case.
Will wrapping it in a TRANSACTION work? Or is there a better way to do this?
How about this
Hope this does the trick for you, remember that everything inside a transaction should be committed or rolled back in one place, otherwise you’re better off having multiple transactions.