Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best practice use of SQL Server T-SQL error handling? [closed]

We have a large application mainly written in SQL Server 7.0, where all database calls are to stored procedures. We are now running SQL Server 2005, which offers more T-SQL features.

After just about every SELECT, INSERT, UPDATE, and DELETE, the @@ROWCOUNT and @@ERROR get captured into local variables and evaluated for problems. If there is a problem the following is done:

  • error message output parameter is set
  • rollback (if necessary) is done
  • info is written (INSERT) to log table
  • return with a error number, unique to this procedure (positive if fatal, negative is warning)

They all don't check the rows (only when it is known) and some differ with more or less log/debug info. Also, the rows logic is somethimes split from the error logic (on updates where a concurrency field is checked in the WHERE clause, rows=0 means someone else has updated the data). However, here is a fairly generic example:

SELECT, INSERT, UPDATE, or DELETE  SELECT @Error=@@ERROR, @Rows=@@ROWCOUNT IF @Rows!=1 OR @Error!=0 BEGIN     SET @ErrorMsg='ERROR 20, ' + ISNULL(OBJECT_NAME(@@PROCID), 'unknown')                                 + ' - unable to ???????? the ????.'     IF @@TRANCOUNT >0     BEGIN          ROLLBACK     END      SET @LogInfo=ISNULL(@LogInfo,'')+'; '+ISNULL(@ErrorMsg,'')+         + ' @YYYYY='        +dbo.FormatString(@YYYYY)         +', @XXXXX='        +dbo.FormatString(@XXXXX)         +', Error='         +dbo.FormatString(@Error)         +', Rows='          +dbo.FormatString(@Rows)      INSERT INTO MyLogTable (...,Message) VALUES (....,@LogInfo)      RETURN 20  END 

I am looking into replacing how we do this with the TRY-CATCH T-SQL. I've read about the TRY...CATCH (Transact-SQL) syntax, so don't just post some summary of that. I'm looking for any good ideas and how best to do or improve our error handling methods. It doesn't have to be Try-Catch, just any good or best practice use of T-SQL error handling.

like image 261
KM. Avatar asked Apr 07 '09 14:04

KM.


People also ask

Which of the following is used for error handling in SQL Server?

1. Which of the following blocks are used for error handling in SQL Server? Explanation: SQL Server 2005 introduced TRY… CATCH statement which helps us to handle the errors effectively in the back end.

Is it correct best practice to have the try catch block inside the transaction or should the transaction be inside the try block?

Option A is the correct choice. It is possible for all statements in a transaction to work and then the actual COMMIT to fail, so you keep the COMMIT inside your TRY block so that any failure of the COMMIT will be caught and you can gracefully handle this error and rollback.

Does T-SQL provide exception handling?

SQL Server provides TRY, CATCH blocks for exception handling. We can put all T-SQL statements into a TRY BLOCK and the code for exception handling can be put into a CATCH block. We can also generate user-defined errors using a THROW block.


2 Answers

You should read this:

http://www.sommarskog.se/error-handling-I.html

I can't recommend that link highly enough. It's a bit long, but in a good way.

There's a disclaimer at the front that it was originally written for SQL Server 2000, but it covers the new try/catch error handling abilities in SQL Server 2005+ as well.

like image 111
Joel Coehoorn Avatar answered Sep 20 '22 15:09

Joel Coehoorn


We currently use this template for any queries that we execute (you could leave out the Transaction stuff, if you don't need it in e.g. a DDL statement):

BEGIN TRANSACTION BEGIN TRY     // do your SQL statements here      COMMIT TRANSACTION END TRY BEGIN CATCH     SELECT          ERROR_NUMBER() AS ErrorNumber,         ERROR_SEVERITY() AS ErrorSeverity,         ERROR_STATE() AS ErrorState,         ERROR_PROCEDURE() AS ErrorProcedure,         ERROR_LINE() AS ErrorLine,         ERROR_MESSAGE() AS ErrorMessage      ROLLBACK TRANSACTION END CATCH 

Of course, you could easily insert the caught exception into your error log table.

It works really well for us. You could probably even automate some of the conversion from your old stored procs to a new format using Code Generation (e.g. CodeSmith) or some custom C# code.

like image 30
marc_s Avatar answered Sep 19 '22 15:09

marc_s