I have a stored procedure in production that does 2 things. It updates one table and then inserts a record into another. The first step (update) seems to be happening, but we found instances, examining the data where the second step was not performed. I looked at the data and confirmed that this is not a data problem. I have confirmed that requests return relevant data to ensure that requests are completed in normal circumstances. I do not know if there might be some kind of performance problem ... or a blocking problem that occurs in the second step that prevents this step.
Error handling for a stored procedure is as follows.
BEGIN TRY BEGIN TRANSACTION; -- perform update to data -- insert record into second table. IF ( @@ERROR = 0 AND @@TRANCOUNT > 0 ) COMMIT TRANSACTION; END TRY BEGIN CATCH IF ( @@TRANCOUNT > 0 ) BEGIN ROLLBACK TRANSACTION; END DECLARE @WebSafeErrorId INT; EXEC dbo.spErrorInsert @WebSafeErrorId OUTPUT, 'Proc'; -- Reraise the error back to the client. IF ( @WebSafeErrorId != 0 ) BEGIN DECLARE @Error VARCHAR(20); SET @Error = CAST( @WebSafeErrorId AS VARCHAR(20) ); RAISERROR( @Error, 11, 1 ); END ELSE BEGIN RAISERROR( 'An error has occurred but there is no error to log.', 11, 1 ); END END CATCH;
Of course, if an error occurred in this procedure due to which the insert did not occur, it would be logged and then raised. Code for spErrorInsert below ...
CREATE PROCEDURE [dbo].[spErrorInsert] @ReturnErrorId INT OUTPUT , @ErrorSourceType VARCHAR(4) = NULL , @ParentErrorId INT = NULL , @StackTrace VARCHAR(MAX) = NULL AS SET NOCOUNT ON; --SET XACT_ABORT ON; -- Will indicate an error was not logged. SET @ReturnErrorID = 0; DECLARE @ErrorSource VARCHAR(200) , @ErrorMessage VARCHAR(MAX) , @ComposedErrorMessage VARCHAR(MAX) , @ErrorLine INT , @ErrorSeverity INT , @ErrorState INT , @ErrorNumber INT; SET @ErrorSource = ERROR_PROCEDURE(); SET @ErrorMessage = ERROR_MESSAGE(); SET @ErrorLine = ERROR_LINE(); SET @ErrorSeverity = ERROR_SEVERITY(); SET @ErrorState = ERROR_STATE(); SET @ErrorNumber = ERROR_NUMBER(); SET @ComposedErrorMessage = 'Message: Error occurred in procedure ' + CAST( @ErrorSource AS VARCHAR(MAX) ) + ' on line ' + CAST( @ErrorLine AS VARCHAR(MAX) ) + '. Error: ' + @ErrorMessage; BEGIN TRY INSERT INTO Errors( ParentId , ErrorSourceType , ErrorSource , [Message] , [LineNo] , Severity , Stacktrace , ts) VALUES (@ParentErrorId , @ErrorSourceType --@ErrorSourceType --- NOTE: move this into a parameter ... , @ErrorSource , @ComposedErrorMessage , @ErrorLine , @ErrorState , @Stacktrace , GETDATE() ); SET @ReturnErrorId = SCOPE_IDENTITY(); END TRY BEGIN CATCH RAISERROR( 'An error has occurred but there is no error to log.', 11, 1 ); END CATCH;
I donβt know, maybe there is a way to get a snapshot of what is happening in the database at a certain time, when a certain procedure is called ... I'm not sure how to determine if something is wrong when it is needed? Are there any tools that I can use or sql functions that I don't know about?