Click here to Skip to main content
15,881,204 members
Articles / Database Development / SQL Server

Using TRY...CATCH in Transact-SQL

Rate me:
Please Sign up or sign in to vote.
2.82/5 (16 votes)
25 Oct 20054 min read 253.5K   26   12
I will discuss the Try & catch error handling feature of the SQL SERVER 2005 (Yukon)

Introduction

Using TRY...CATCH in Transact-SQL

Purpose of this Article

I will discuss the new feature ( TRY...CATCH) for error handling in SQL SERVER 2005

Microsoft have introduced the TRY & CATCH syntax (TAC) for error handling is T-SQL, in SQL server 2005. The .NET must have used this syntax before also, as this TAC was initially introduced and now they are introducing this in SQL also.

How it works

As I have mentioned this TAC block is very similar to what be use in other.net languages. The idea is fairly simple

When an error condition is detected in a Transact-SQL statement contained in a TRY block, control is passed to a CATCH block where it can be processed.

Begin Try 
 The_Query_for_which_we_need_to_do_the_ Error_Handling 
End Try 
Begin Catch 
   
  If there is some error in the query within the Try block, this flow 
  will be passed to this Catch block. 
  
End catch 

If there are no errors inside the TRY block, control passes to the statement immediately after the associated END CATCH statement. If the END CATCH statement is the last statement in a stored procedure or trigger, control is passed to the statement that invoked the stored procedure or trigger.

Do TRY/CATCH blocks work for all errors?

No, please do take care of the following points

  • A TRY block must be followed immediately by a CATCH block.
  • TRY…CATCH constructs can be nested, which means that TRY…CATCH constructs can be placed inside other TRY and CATCH blocks. When an error occurs within a nested TRY block, program control is transferred to the CATCH block associated with the nested TRY block.
SQL
BEGIN TRY           
      Print ' I am level 1 '
          BEGIN TRY
            Print ' I am level 2 '
            SELECT 1/0;    
          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;   
    Print ' I am going out level 2   ' 
         END CATCH
    Print ' I am level 1 again '    
END TRY
BEGIN CATCH
    -- Execute the error retrieval routine.
        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;    
END CATCH

Output

SQL
 I am level 1 
 I am level 2 
----------- 
(0 row(s) affected)
ErrorNumber ErrorSeverity ErrorState ErrorProcedure ErrorLine ErrorMessage
8134        16            1          NULL               5     Divide by zero 
                                                            error encountered. 
(1 row(s) affected) 
 I am going out level 2   
 I am level 1 again 

In the code above the error is thrown from the Level 2 TAC block 
  • To handle an error that occurs within a given CATCH block, write a TRY…...CATCH block within the specified CATCH block.
  • Errors with a severity of 20 or higher that cause the Database Engine to terminate the connection will not be handled by the TRY…CATCH block. However, TRY…CATCH will handle errors with a severity of 20 or higher as long as the connection is not terminated.
  • Errors with a severity of 10 or lower are considered warnings or informational messages, and are not handled by TRY…CATCH blocks.

From the above two statement it is clear that

Try & Catch block will work for

Errors with a severity of 10 < TRY & Block <= Errors with a severity of 20

Error Functions

TRY…CATCH uses error functions to capture error information.

ERROR_NUMBER() returns the error number.

ERROR_MESSAGE() returns the complete text of the error message. The text includes the values supplied for any substitutable parameters such as lengths, object names, or times.

ERROR_SEVERITY() returns the error severity.

ERROR_STATE() returns the error state number.

ERROR_LINE() returns the line number inside the routine that caused the error.

ERROR_PROCEDURE() returns the name of the stored procedure or trigger where the error occurred.

Error information is retrieved using these functions from anywhere within the scope of the CATCH block of a TRY…CATCH construct. The error functions will return NULL if called outside the scope of a CATCH block. Error functions can be referenced inside a stored procedure and can be used to retrieve error information when the stored procedure is executed within the CATCH block. By doing this, it will not be necessary to type error handling code in every CATCH block.

Will the TRY / CATCH blocks catch Compile errors, such as syntax errors that prevent a batch from executing?

No, the TAC block will not catch the compile errors, if it is not called in the from of dynamic query or in some SP

In the below code the table does not exist, so we will get the error while we want to complie the code.The TAC block does not play any role here

SQL
BEGIN TRY
    -- This PRINT statement will run since the error
    -- occurs at the SELECT statement.
    PRINT N'Starting execution'
   
   SELECT * FROM NonExistentTable
    -- This SELECT statement will generate an object name
    -- resolution error since the table does not exist. 
      
END TRY
BEGIN CATCH
    SELECT 
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_MESSAGE() AS ErrorMessage;
END CATCH;
GO 
OutPut : 
Starting execution
Msg 208, Level 16, State 1, Line 6
Invalid object name 'NonExistentTable'.
I will try to put the above logic using a dynamic SQL. On doing so the code will compile, but will through a error, which will be caught by the TAC block

Dynamic query

SQL
BEGIN TRY
    -- This PRINT statement will run since the error
    -- occurs at the SELECT statement.
    PRINT N'Starting execution';
    DECLARE @SQL NVARCHAR(2000) 
    SET @SQL = 'SELECT * FROM NonExistentTable;'
    -- This SELECT statement will generate an object name
    -- resolution error since the table does not exist.
   EXEC sp_executesql  @SQL 
      
END TRY
BEGIN CATCH
    SELECT 
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_MESSAGE() AS ErrorMessage;
END CATCH;
GO 

Output : 
Starting execution
ErrorNumber ErrorMessage
----------- ------
208         Invalid object name 'NonExistentTable'. 
(1 row(s) affected)

Dealing with Transactions

In the TRY statement it may happen that we open a Transaction, but for some reason, the statement went to the respective catch block, then how is the open Transaction is going to behave.

In this state, however, the locks acquired by the transaction are maintained, and the connection is also kept open. The transaction's work is not reversed until a ROLLBACK statement is issued.

The code in a CATCH block should test for the state of a transaction by using the XACT_STATE function. XACT_STATE returns a -1 if the session has an uncommittable transaction. The CATCH block must not perform any actions that would generate writes to the log if XACT_STATE returns a -1. The following code example generates an error from a DDL statement and uses XACT_STATE to test the state of a transaction in order to take the most appropriate action.

SQL
CREATE TABLE TEMP ( A INT ) 
BEGIN TRY 
       -- BEGIN   Tran   
         ALTER TABLE TEMP
            DROP COLUMN author                 
         COMMIT TRAN 
END TRY
BEGIN CATCH
    -- Execute the error retrieval routine.
        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;   
        PRINT ' *****Value of XACT_STATE ****'+CONVERT(VARCHAR,XACT_STATE()) 
END CATCH
GO 
Output 
ErrorNumber ErrorSeverity ErrorState  ErrorProcedure  ErrorLine   ErrorMessage
----------- ------------- ----------- --------------------------------------
3930        16            1           NULL    3       The current transaction
                                                      cannot be committed and 
                                                      cannot support
                                                      operations that write
                                                      to the log file. Roll 
                                                      back the transaction.
(1 row(s) affected) 
 *****Value of XACT_STATE ****-1

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
He is working with reputed IT company in Hyderabad India .

He has got an total IT expereince of 4 yrs . I have been working with VB , .NET & SQL SERVER 2000 & Yukon .

he has done his B.Tech In Computer Science & Engg from North Eastern Regional Institute Of Science & Technolgy ( NERIST ) Arunachal Pradesh , Indian .

He enjoy's working on the latest technology , driving & cooking .


Comments and Discussions

 
QuestionUpdate in vb.net Pin
Member 1200327622-Sep-15 3:24
Member 1200327622-Sep-15 3:24 
GeneralMy vote of 2 Pin
PuneWala15-Jun-10 20:39
PuneWala15-Jun-10 20:39 
GeneralWrong Database Dude! Pin
Bill SerGio, The Infomercial King26-Oct-05 7:47
Bill SerGio, The Infomercial King26-Oct-05 7:47 
GeneralRe: Wrong Database Dude! Pin
Lasse28-Oct-05 9:37
Lasse28-Oct-05 9:37 
GeneralRe: Wrong Database Dude! Pin
Bill SerGio, The Infomercial King28-Oct-05 9:41
Bill SerGio, The Infomercial King28-Oct-05 9:41 
GeneralRe: Wrong Database Dude! Pin
Lasse28-Oct-05 10:33
Lasse28-Oct-05 10:33 
GeneralRe: Wrong Database Dude! Pin
Bill SerGio, The Infomercial King28-Oct-05 10:53
Bill SerGio, The Infomercial King28-Oct-05 10:53 
GeneralRe: Wrong Database Dude! Pin
Lasse28-Oct-05 11:03
Lasse28-Oct-05 11:03 
GeneralRe: Wrong Database Dude! Pin
Bill SerGio, The Infomercial King28-Oct-05 11:30
Bill SerGio, The Infomercial King28-Oct-05 11:30 
GeneralRe: Wrong Database Dude! Pin
Lasse28-Oct-05 11:39
Lasse28-Oct-05 11:39 
GeneralRe: Wrong Database Dude! PinPopular
snkscore15-Nov-07 4:21
snkscore15-Nov-07 4:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.