Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Data Management

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Your profile

    Search

    XML Feeds

    Google Ads

    « SQL Advent 2011 Day 22: Dynamic Management ViewsReplacing sysfiles With sys.database_files »
    comments

    In my Are you ready for SQL Server 2012 or are you still partying like it is 1999? post, I wrote about how you should start using SQL Server 2005 and SQL Server 2008 functionality now in order to prepare for SQL Server 2012. I still see tons of code that is written in the pre 2005 style and people still keep using those functions, procs and statements even though SQL Server 2005 and 2008 have much better functionality.

    Today we are going to take a look at TRY CATCH. Like in most modern programming languages, you put your code in the TRY block and you check for the errors in the CATCH block. SQL Server has a bunch of functions that will help you identify why your code failed, here is a list of the functions and what they return

    ERROR_NUMBER()
    returns the number of the error

    ERROR_SEVERITY()
    returns the severity of the error

    ERROR_STATE()
    returns the error state number

    ERROR_PROCEDURE()
    returns the name of the stored procedure or trigger where the error occurred, this will be NULL if you run an ad-hoc SQL statement

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

    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



    Let's run an example that generates a divide by zero error, in the catch we are just doing a simple select that calls the functions mentioned before to see what they return

    1. BEGIN TRY
    2.     --  divide-by-zero error.
    3.     SELECT 1/0
    4. END TRY
    5. BEGIN CATCH
    6.     SELECT
    7.     ERROR_NUMBER() AS ErrorNumber
    8.     ,ERROR_SEVERITY() AS ErrorSeverity
    9.     ,ERROR_STATE() AS ErrorState
    10.     ,ERROR_PROCEDURE() AS ErrorProcedure
    11.     ,ERROR_LINE() AS ErrorLine
    12.     ,ERROR_MESSAGE() AS ErrorMessage;
    13. END CATCH;


    ErrorNumber	ErrorSeverity	ErrorState	ErrorProcedure	ErrorLine	ErrorMessage
    8134	        16	        1	        NULL	        3	       Divide by zero 
                                                                                   error encountered.


    As you can see we got all that information back, that was pretty nice. Let's take it to the next step

    Create the following table to store all the error information in

    1. CREATE TABLE LogErrors (ErrorTime datetime,
    2.             ErrorNumber int,
    3.             ErrorSeverity int,
    4.             ErrorState int,
    5.             ErrorProc nvarchar(100),
    6.             ErrorLine int,
    7.             ErrorMessage nvarchar(1000))
    8. GO

    Create this stored procedure that will insert into the table we just created

    1. CREATE PROCEDURE prInsertError
    2. AS
    3. INSERT LogErrors
    4. SELECT GETDATE(),
    5.     ERROR_NUMBER(),
    6.     ERROR_SEVERITY(),
    7.     ERROR_STATE(),
    8.     ERROR_PROCEDURE(),
    9.     ERROR_LINE(),
    10.     ERROR_MESSAGE() ;
    11. GO

    Run these 3 queries, they will generate 3 inserts into the LogErrors table

    1. BEGIN TRY
    2.     SELECT 1/0
    3. END TRY
    4. BEGIN CATCH
    5.     EXEC prInsertError
    6. END CATCH;
    7.  
    8.  
    9. BEGIN TRY
    10.     SELECT convert(int,'a')
    11. END TRY
    12. BEGIN CATCH
    13.     EXEC prInsertError
    14. END CATCH;
    15.  
    16.  
    17. BEGIN TRY
    18.     SELECT convert(tinyint,300)
    19. END TRY
    20. BEGIN CATCH
    21.     EXEC prInsertError
    22. END CATCH;

    If you check now what is in the table, you will see 3 rows

    1. SELECT * FROM LogErrors


    ErrorTime ErrorNumber ErrorSeverity ErrorState ErrorProc ErrorLine ErrorMessage
    2011-12-21 20:08:20.890 8134 16 1 NULL 2 Divide by zero error encountered.
    2011-12-21 20:08:22.907 245 16 1 NULL 2 Conversion failed when converting the varchar value 'a' to data type int.
    2011-12-21 20:08:25.270 220 16 2 NULL 2 Arithmetic overflow error for data type tinyint, value = 300.



    That is all for today, as you can see error handling is much better than having to check for @@ERROR after every insert. You can also have 1 stored proc that you can call from everywhere and this proc will log all errors plus any other information you want to capture like user name, host name etc etc

    Come back tomorrow for the next post in this series

    About the Author

    User bio imageDenis has been working with SQL Server since version 6.5. Although he worked as an ASP/JSP/ColdFusion developer before the dot com bust, he has been working exclusively as a database developer/architect since 2002. In addition to English, Denis is also fluent in Croatian and Dutch, but he can curse in many other languages and dialects (just ask the SQL optimizer) He lives in Princeton, NJ with his wife and three kids.
    Social SitingsTwitterFacebookLinkedInHomePageFlickrLTD RSS Feed
    736 views
    Instapaper

    No feedback yet

    Leave a comment


    Your email address will not be revealed on this site.

    Your URL will be displayed.
    (Line breaks become <br />)
    (Name, email & website)
    (Allow users to contact you through a message form (your email will not be revealed.)