module 12 handling errors in t-sql code. module overview understanding t-sql error handling...

27
Module 12 Handling Errors in T-SQL Code

Upload: christian-golden

Post on 27-Dec-2015

242 views

Category:

Documents


2 download

TRANSCRIPT

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.

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));

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';GODECLARE @DatabaseID int = DB_ID();DECLARE @DatabaseName sysname = DB_NAME();

RAISERROR (61487,10,1,@DatabaseID,@DatabaseName);

EXECUTE sp_addmessage 61487, 10, 'Current DatabaseID: %d, Database Name: %s';GODECLARE @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 TRYBEGIN CATCH -- Execute the error retrieval routine. EXECUTE Error.GeneralHandler;END CATCH;

BEGIN TRY -- Generate divide-by-zero error. SELECT 1/0;END TRYBEGIN 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.GeneralHandlerAS 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

CREATE PROCEDURE Error.GeneralHandlerAS 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 TRYBEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK TRAN; EXEC Error.GeneralHandler; RETURN -1;END CATCH;

SET XACT_ABORT ON;BEGIN TRY BEGIN TRAN; -- perform work COMMIT TRAN;END TRYBEGIN 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

Estimated time: 45 minutes

Virtual machine 623XB-MIA-SQL

User name AdventureWorks\Administrator

Password Pa$$w0rd

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