6232B_12

Module 12
Handling Errors in T-SQL
Code
Module Overview
• Understanding T-SQL Error Handling
• Implementing T-SQL Error Handling
• Implementing Structured Exception Handling
Lesson 1: Understanding T-SQL Error Handling
• Where T-SQL Errors Occur
• Types of Errors
• What's in an Error?
• Error Severity
• Demonstration 1A: Error Types and Severity
Where T-SQL Errors Occur
• T-SQL Errors can occur in all phases

Syntax of a statement is checked

Object names are resolved

Statement is executed
• Errors can be handled in two ways

Error handling code in the database engine

Error handling code in the calling application
Types of Errors
Category
Notes
Syntax Errors
Execution is never started
Object Resolution Errors
Execution is never started
Statement Terminating Errors
Execution resumes at next
statement
Scope Terminating
Execution resumes at next
statement after statement that
called the scope
Batch Terminating Errors
Aborts the batch
Connection Terminating Errors
Disconnects the session
Server Terminating Errors
Stops SQL Server (Rare)
What's in an Error?
• Errors raised by the database engine have the following
attributes:
Attribute
Description
Error number
Each error message has a unique error number
Error Message
String containing diagnostic info about the
cause of the error
Severity
Indicates how serious the error is
State
Value used to determine the location in code at
which an error occurred
Procedure Name
Name of the stored procedure or trigger in
which the error occurred (if applicable)
Line Number
Indicates in which line of a batch, stored
procedure, trigger or function generated the
error
Error Severity
• The severity of an error indicates the type of problem
encountered by SQL Server
Severity Range
Description
0 to 9
Informational messages
10
Informational messages that return status
information
11 to 16
Errors that can be corrected by the user
17 to 19
Software errors that cannot be corrected by the
user
20 to 24
Serious system errors
25
SQL Server service terminating error
Demonstration 1A: Error Types and Severity
In this demonstration you will:
• See how different types of errors are returned from T-SQL
statements
• See the types of messages that are related to severe
errors
• Query the sys.messages view and note which errors are
logged automatically
Lesson 2: Implementing T-SQL Error Handling
• Raising Errors
• Using @@ERROR
• Errors and Transactions
• Transaction Nesting Errors
• Raising Custom Errors
• Creating Alerts When Errors Occur
• Demonstration 2A: T-SQL Error Handling
Raising Errors
• RAISERROR

Allows raising errors in code

Is used to return errors and messages back to applications using the
same format as a system error
• RAISERROR can return either:

A user-defined error message created with sp_addmessage

A message string specified in the RAISERROR statement
DECLARE @DatabaseID int = DB_ID();
DECLARE @DatabaseName sysname = DB_NAME();
RAISERROR
(N'Current database ID:%d, database name: %s.',
10, -- Severity.
1, -- State.
@DatabaseID, -- First substitution argument.
@DatabaseName); -- Second substitution argument.
Using @@ERROR
• Returns zero if the last statement executed correctly
• Returns the error number if the statement generated an error
• Changes value on the completion of each statement
RAISERROR(N'Message', 16, 1);
IF @@ERROR <> 0
PRINT 'Error=' + CAST(@@ERROR AS VARCHAR(8));
GO
DECLARE @ErrorValue int;
RAISERROR(N'Message', 16, 1);
SET @ErrorValue = @@ERROR;
IF @ErrorValue <> 0
PRINT 'Error=' + CAST(@ErrorValue AS VARCHAR(8));
Errors and Transactions
• Most errors are statement terminating errors

Statement that caused them is rolled back

Execution continues with the next statement
• SET XACT_ABORT

When ON, errors that would abort the T-SQL statement will
abort the batch and roll back any enclosing transaction as well

When OFF (default value), in most cases only the T-SQL
statement that raised the error will be rolled back

Does not affect compile and syntax errors
Transaction Nesting Errors
• Any ROLLBACK causes all levels of transactions to be
rolled back

Nested transactions are not supported in SQL Server

Autonomous transactions are not supported in SQL Server
• @@TRANCOUNT can be used to test the transaction level
• Stored procedures must have the same @@TRANCOUNT
on entry and exit or error 286 is thrown

Common situation that occurs when attempting to nest
transactions
Raising Custom Errors
• sp_addmessage allows adding custom error messages

Error number must be 50000 or above

Can be specific to a language
EXECUTE sp_addmessage 61487, 10,
'Current DatabaseID: %d, Database Name: %s';
GO
DECLARE @DatabaseID int = DB_ID();
DECLARE @DatabaseName sysname = DB_NAME();
RAISERROR (61487,10,1,@DatabaseID,@DatabaseName);
Creating Alerts When Errors Occur
• Alerts can be raised on errors that are logged
• Messages (including system messages) can be altered to be
alert-raising by:

Using RAISERROR() WITH LOG

Altering a message to make it logged via sp_altermessage
Demonstration 2A: T-SQL Error Handling
In this demonstration, you will see:
• How to raise errors
• How severity affects errors
• How to add a custom error message
• How to raise a custom error message
• That custom error messages are instance-wide
• How to use @@ERROR
• That system error messages cannot be raised
Lesson 3: Implementing Structured Exception
Handling
• TRY CATCH Block Programming
• Error Handling Functions
• Catchable vs. Non-catchable Errors
• TRY CATCH and Transactions
• Errors in Managed Code
• Demonstration 3A: Deadlock Retry
TRY CATCH Block Programming
• Structured exception handling is more powerful than @@ERROR

Allows focus on the purpose of code rather than on error handling

TRY/CATCH blocks can be nested
• BEGIN CATCH must follow END TRY
BEGIN TRY
-- Generate divide-by-zero error.
SELECT 1/0;
END TRY
BEGIN CATCH
-- Execute the error retrieval routine.
EXECUTE Error.GeneralHandler;
END CATCH;
Error Handling Functions
• CATCH blocks have richer options for capturing error information
than was available through @@ERROR
• Error functions are able to return the error information
throughout the CATCH block, not just for the first statement
• Error handlers can be enclosed in a stored procedure for reuse
CREATE PROCEDURE Error.GeneralHandler
AS
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;
GO
Catchable vs. Non-catchable Errors
• Not all errors can be caught by TRY…CATCH blocks within
the same scope

Compile errors

Statement level recompilation issues

Errors that are not able to be caught in their current scope can
still be caught at the next outer scope
TRY CATCH and Transactions
• CATCH blocks do not automatically roll back transactions
• Code in the catch block needs to roll back any current transaction
(but only if there is a transaction)
SET XACT_ABORT ON;
BEGIN TRY
BEGIN TRAN;
-- perform work
COMMIT TRAN;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 ROLLBACK TRAN;
EXEC Error.GeneralHandler;
RETURN -1;
END CATCH;
Errors in Managed Code
• Errors can be caught using standard .NET try/catch/finally
handling within the high level languages used to create
managed code
• All errors that are passed back from managed code to T-
SQL will be wrapped in a 6522 error.
• Errors messages can contain nested error messages. SQL
CLR messages need to be unpacked to find the inner
exceptions rather than the 6522 error that they are
wrapped in.
• Managed code could execute a RAISERROR T-SQL
statement via a SqlCommand object.
Demonstration 3A: Deadlock Retry
In this demonstration you will see how to use structured
exception handling to retry deadlock errors
Lab 12: Handling Errors in T-SQL Code
• Exercise 1: Replace @@ERROR based error handling with
structured exception handling
• Challenge Exercise 2: Add deadlock retry logic to the
stored procedure (Only if time permits)
Logon information
Virtual machine
623XB-MIA-SQL
User name
AdventureWorks\Administrator
Password
Pa$$w0rd
Estimated time: 45 minutes
Lab Scenario
A company developer asks you for assistance with some
code he is modifying. The code was written some time back
and uses simple T-SQL error handling. He has heard that
structured exception handling is more powerful and wishes
to use it instead.
Lab Review
• Why do we need to test for transaction state in a CATCH
block?
• Why do we insert a delay within the retry logic for a
deadlock?
Module Review and Takeaways
• Review Questions
• Best Practices