Blog Post

The Basics of TRY CATCH Blocks–#SQLNewBlogger

,

I was working with a customer and discussing how to do error handling. This is a short post that looks at how you can start adding TRY.. CATCH blocks to your code.

Another post for me that is simple and hopefully serves as an example for people trying to get blogging as #SQLNewBloggers.

TRY CATCH

This is a common error handling technique in other languages. C# uses it, as does Java, while Python has TRY EXCEPT. There are other examples, but these are good habits to get into when you don’t know how code will behave or if there is something in your data or environment that could cause an issue.

In SQL, I think many of us get used to writing one statement in a query and forget to do error handling, or transactions. However, this can be a good habit as your code might grow and people might add more statements that should execute.

A classic example of code is someone writing this:

DECLARE
   @id INT = 2
, @name VARCHAR(20) = 'Voice od the DBA'
, @stat INT = 1;

BEGIN TRAN;

INSERT dbo.Customer

(CustomerID, CustomerName, status)

VALUES

(@id, @name, @stat);

IF @@ERROR = 0

COMMIT;

ELSE

ROLLBACK;

Note that this does look for an error and then decide what to do. However, we could be better, especially if we wanted to possibly add a second insert or other work. We could do this:

DECLARE
   @id INT = 2
, @name VARCHAR(20) = 'Voice od the DBA'
, @stat INT = 1;

BEGIN TRY

BEGIN TRAN;

INSERT dbo.Customer

(CustomerID, CustomerName, status)

VALUES

(@id, @name, @stat);

COMMIT

END TRY

BEGIN CATCH

ROLLBACK

END CATCH

It doesn’t look like much, but this code could easily be enhanced with a better pattern. We can capture the various error messages like this:

DECLARE
   @id INT = 2
, @name VARCHAR(20) = 'Voice od the DBA'
, @stat INT = 1;

BEGIN TRY

BEGIN TRAN;

INSERT dbo.Customer

(CustomerID, CustomerName, status)

VALUES

(@id, @name, @stat);

COMMIT

END TRY

BEGIN CATCH

DECLARE @ErrorMessage NVARCHAR(4000);

DECLARE @ErrorSeverity INT;

DECLARE @ErrorState INT;

SELECT

@ErrorMessage = ERROR_MESSAGE(),

@ErrorSeverity = ERROR_SEVERITY(),

@ErrorState = ERROR_STATE();

RAISERROR (@ErrorMessage, -- Message text.

@ErrorSeverity, -- Severity.

@ErrorState -- State.

);

WHILE @@TRANCOUNT > 0

BEGIN

ROLLBACK TRANSACTION;

END

END CATCH

In this case, we have a few statements that work with the error, in this case using RAISERROR to raise this. We could also use THROW or add something else. If we had more inserts, like to a child table, we could encapsulate them all here. What’s more, if we had logging, we could log this before the rollback to another system if our logging were not transaction dependent.

Using TRY CATCH is really just structuring your code differently. Ideally, using something a snippet in SQL Prompt so your developers have an easy way to standardize error handling.

SQL New Blogger

This post took me about 15 minutes to structure and test. I looked at a few patterns, and I liked the one in this Stack Overflow answer as a good way to generically implement this structure.

You could write a similar post showing your next boss how you implement error handling, transactions, anything. Give it a try.

Original post (opens in new tab)
View comments in original post (opens in new tab)

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating