Advanced Concepts in SQL Server 2005
page 5 of 11
by Joydip Kanjilal
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 42774/ 67

Error handling

Error handling was a pretty tough job in the earlier versions of SQL Server. Developers had to perform lot of conditional checks for the error code returned after each INSERT, UPDATE or DELETE operations. Developers must check the @@ERROR attribute each time they might see the possibility of an error based operations. Error messages could be generated either from the SQL Server or thrown explicitly by the user. Let us first see how developers usually perform the error handling in SQL Server 2000. We shall have a stored procedure for our demonstration. Let us use AdventureWorks database for our demonstration purpose.

Listing 2

CREATE PROCEDURE ErrorHandlerDemo
AS
BEGIN
BEGIN TRANSACTION
DECLARE @EmpID AS BIGINT
INSERT INTO [HumanResources].[Employee] ([NationalIDNumber], [ContactID], 
[LoginID], [ManagerID], [Title], [BirthDate], [MaritalStatus], [Gender], 
[HireDate], [SalariedFlag], [VacationHours], [SickLeaveHours], [CurrentFlag], 
[rowguid], [ModifiedDate]) 
VALUES ('1441784507', 120439, 'adventure-works\guy43', 13456, 'Production 
Technician - WC60''19720515''M''M', '19960731', 0, 21, 30, 1, 
'AAE1D04A-C237-4974-B4D5-735247737718', '20040731')
IF @@ERROR != 0 GOTO ERROR_HANDLER
SET @EmpID = @@IDENTITY
INSERT INTO [HumanResources].[EmployeeAddress] ([EmployeeID], [AddressID], 
[rowguid], [ModifiedDate]) 
VALUES (@EmpID, 61, '77253AEF-8883-4E76-97AA-7B7DAC21A2CD''20041013 11:15:06.967')
IF @@ERROR != 0 GOTO ERROR_HANDLER
COMMIT TRANSACTION
ERROR_HANDLER:
    ROLLBACK TRANSACTION
    RETURN @@ERROR
END
GO

When we try to execute this procedure we get the output as:

Listing 3

Msg 547, Level 16, State 0, Procedure ErrorHandlerDemo, Line 11

The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Employee_Contact_ContactID." The conflict occurred in database "AdventureWorks" table "Person.Contact" column "ContactID."

The statement has been terminated.

As you could see, the error message has Msg, Level of severity, State and Line. The “Msg” holds the error number generated for the message, in this case 547. All the error messages are defined in the table called sys.messages. If you are going for custom error handling then you can utilize the sp_addmessage system procedure to implement new error messages.

Next, you have the severity “Level” of the message. Severity codes lie in the range of 0 to 25. Any error message above 20 will terminate the connection. Error messages from 17 to 20 specify a resource problem, from 11 to 16 specify error messages in the T-SQL scripts, and error messages below 11 specify warnings.

Next we have the "State" of the error message. This is an arbitrary integer range falling in between 0 to 127. This provides information on the source that has issued the error message. However, there is not much documentation disclosed by Microsoft on this.

Next is the "Line" number which tells us the line where the error has occurred in the procedure or T-SQL batch. And the last one is the message itself.

The understanding and implementation of the error handling in the earlier versions of SQL Server 2005 was fair enough, but was with a lot of housekeeping activity.  SQL Server 2005 provides flexible means to handle error handling mechanism by using the TRY and CATCH blocks.

The syntax looks like:

Listing 4

BEGIN
    TRY
    BEGIN TRANSACTION 
    …..
    --perform insert update and delete statements
    …..
    …..
    COMMIT TRANSACTION 
END TRY
BEGIN
--Start
    CATCH
    ROLLBACK TRANSACTION 
    PRINT ERROR_NUMBER()
    PRINT ERROR_SEVERITY()
    PRINT ERROR_STATE()
    PRINT ERROR_PROCEDURE()
    PRINT ERROR_LINE()
    PRINT ERROR_MESSAGE()
--End
END CATCH

So as you could see from the above script, the error handling mechanism is simplified. When an error occurs, the statement is terminated from the current execution point and it enters the catch block. The functions following the PRINT statements are built-in functions that provide information on the error message. You could also embed the code from start to end in a stored procedure and call it wherever you need. You can also log the error messages in a table for debugging purpose. AdventureWorks database handles error handling in similar manner; you could find procedures uspLogError and uspPrintError which do the job.

You could also use the RAISERROR to define you own custom error messages. The RAISERROR may take a system error code or a user defined error code which would be eventually fired by the server to the connected application or within the try..catch block. The example of using RAISERROR is:

Listing 5

RAISERROR (
-- Message text.
'A serious error has terminated the program. Error message is %s, Error code is %d.', 
-- Severity
     10, 
-- State
     1, 
-- Argument 1.
     '...statement conflicted...', 
-- Argument 2.
      52000); 

The output of this RAISERROR would look like:

A serious error has terminated the program. Error message is ...statement conflicted..., Error code is 52000.

Next time when you are working with T-SQL code, you need not really worry about implementing numerous checks for errors. The TRY..CATCH feature helps with a better approach for error handling which would minimize the size of your code, thus improving readability.


View Entire Article

User Comments

No comments posted yet.






Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-23 6:08:25 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search