370 likes | 666 Views
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?
E N D
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
What's in an Error? • Errors raised by the database engine have the following attributes:
Error Severity • The severity of an error indicates the type of problem encountered by SQL Server
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 @DatabaseIDint=DB_ID(); DECLARE @DatabaseNamesysname=DB_NAME(); RAISERROR (N'Currentdatabase 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(@@ERRORASVARCHAR(8)); GO DECLARE@ErrorValueint; RAISERROR(N'Message', 16, 1); SET @ErrorValue=@@ERROR; IF @ErrorValue<> 0 PRINT'Error='+CAST(@ErrorValueASVARCHAR(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 EXECUTEsp_addmessage61487, 10, 'Current DatabaseID: %d, Database Name: %s'; GO DECLARE @DatabaseIDint=DB_ID(); DECLARE @DatabaseNamesysname=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 BEGINTRY -- Generate divide-by-zero error. SELECT 1/0; ENDTRY BEGINCATCH -- Execute the error retrieval routine. EXECUTEError.GeneralHandler; ENDCATCH;
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 CREATEPROCEDUREError.GeneralHandler AS SELECT ERROR_NUMBER()ASErrorNumber, ERROR_SEVERITY()ASErrorSeverity, ERROR_STATE()asErrorState, ERROR_PROCEDURE()asErrorProcedure, ERROR_LINE()asErrorLine, ERROR_MESSAGE()asErrorMessage; 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) SETXACT_ABORTON; BEGINTRY BEGINTRAN; -- perform work COMMITTRAN; ENDTRY BEGINCATCH IF@@TRANCOUNT> 0 ROLLBACKTRAN; EXECError.GeneralHandler; RETURN-1; ENDCATCH;
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
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