BE PREPARED Error Handling & Optimizing T-SQL Code in SQL Server 2000 Stevan Popovski, MCSD Interbank Clearing Systems,KIBS stevanp@kibs.com.mk 2004 PASS SQL Server Academy Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Error handling target Database consistency Quick error detection Error cause identification Scouting out error location Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Developer’s prerequisites Low level of confidence High level of paranoia Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Errors classification 1 Expected errors – trapped errors (Raiserror, Return, Print, Select) 1. Information messages 2. Logical errors Unexpected errors 1. Compile Error (example: syntax error) 2. Run-time Error (example: constraint violation) Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Error message structure CREATE PROCEDURE dbo.Demo1Proc1 AS SELECT 'STRING'/2 GO EXEC Demo1Proc1 Server: Msg 245, Level 16, State 1, Procedure Demo1Proc1, Line 3 Syntax error converting the varchar value 'STRING' to a column of data type int. Message number Severity level State Procedure Line Message text Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Error detection VB6 On Error Resume Next Go To ErrHandler VB.NET Try , Catch, Finally, End Try SQL 2000 @@Error, Return parameter YUKON Begin Try, End Try Begin Catch, End Catch @@ERROR 0 - after successful execution err.number – after statement that generate error RETURN parameter 0 after successful execution of stored procedures There is no way for error suppression in SQL Server 2000 Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Batch definition A batch is a group of one or more Transact-SQL statements sent at one time from an application to SQL Server for execution Batch samples: GO <group og T-SQL statements> GO EXECUTE (“sql query”) sp_executesql (“sql query”) Execution of three nested procedures is one Batch Proc1 Proc2 Proc3 Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Scope definition The current executing procedure, function or triger called by other procedure is scope Proc1 – entire batch Proc2 – part of batch – scope1 Proc3 – part of batch and part of scope1 – scope2 Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Error classification 2 Statement level error Scope level error (depend on SQL Server “after error” behaviour) Statement level error Scope level error Batch level error Connection level error Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Statement level error The current statement is aborted and rolled back Execution continues with next statement If transaction is open it is not rolled back System function @@Error is equal to err.number Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Statement level error Table is created CREATE TABLE Demo2Table (p1 CHAR(8)) GO INSERT INTO Demo2Table VALUES ('in db1') INSERT INTO Demo2Table VALUES (‘more than 8') INSERT INTO Demo2Table VALUES ('in db3') SELECT * FROM Demo2Table (1 row(s) affected) Server: Msg 8152, Level 16, State 9, Line 1 String or binary data would be truncated. The statement has been terminated. (1 row(s) affected) Table is created First and third insert are executed Select statement is executed p1 in db1 in db3 Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Statement level error - samples Duplicate primary key Inserting Null value in not null column Check or Foreign Key violation Calling non existed stored procedure Permission denied Declaring same cursor second time Missing parameter in store procedure execution Rollback or Commit without active transaction Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Scope level error The current scope is aborted Execution continues on the next statement in the calling scope System function @@error is set to error number The aborted procedure does not have a return value Variable that receive the return value is unaffected Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Scope level error EXEC Demo3PrCaller CREATE PROCEDURE Demo3PrCaller AS DECLARE @Ret INT SET @Ret = 7777 EXEC @Ret = Demo3ScopeAbort PRINT 'Return' + str(@Ret) Procedure Demo3PrCaller, COMMIT or ROLLBACK TRANSACTION statement is missing. Return 7777 CREATE PROCEDURE Demo3ScopeAbort AS CREATE TABLE #Temp (p1 int not null) PRINT 'FIRST PRINT' BEGIN TRANSACTION INSERT INTO #Temp SELECT * FROM TabNonExist COMMIT TRANSACTION PRINT 'SECOND PRINT' FIRST PRINT Procedure Demo3ScopeAbort, Invalid object name TabNonExist SELECT ColNoEx FROM TabEx Procedure Demo3ScopeAbort COMMIT or ROLLBACK TRANSACTION statement is missing. Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy Invalid column name 'ColNoEx'.
Batch level error The execution of the entire batch is aborted Any open transaction is rolled back @@error is set, you can catch a non-zero error value in the next batch There is no way you can obstruct batch-abortion in T-SQL code Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Batch level error declare @Ret int exec @Ret = Demo4BatchAbort @@Error is not availible in this batch Return parameter is not set declare @Ret int exec @Ret = Demo4BatchAbort select @@Error select @Ret First select CREATE PROCEDURE Demo4BatchAbort AS DECLARE @Err as INT SELECT 'First select' declare @Param int exec Demo4WithoutError @Param SET @Err = @@Error SELECT ' Second select' IF @Err <> 0 RETURN @Err Server: Msg 8146, Level 16, State 1, Procedure Demo4WithoutError, Line 0 Procedure Demo4WithoutError has no parameters and arguments were supplied. CREATE PROCEDURE Demo4WithoutError AS SELECT 'There is no error in this procedure' Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Batch level error - samples Converting non-numeric string to numeric value Superfluous parameter to stored procedure Exceeding the maximum nesting-level (32) If batch is deadlock victim Running out of space for data file or transaction log Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Connection level error SQL Server terminates the connection Open transactions are Rolled back It is not possible to check @@Error Connection-termination examples: Errors in the SQL Server process Protocol errors in the communication Hardware problems Network problems Database corruptions Errors in dll components called by sp_OAxxx procedures Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Transactions A transaction is a sequence of operations performed as a single logical unit of work Atomicity A transaction must be an atomic unit of work; either all of its data modifications are performed, or none of them is performed Consistency When completed, a transaction must leave all data in a consistent state. Isolation Modifications made by concurrent transactions must be isolated from the modifications made by any other concurrent transactions Durability After a transaction has completed, its effects are permanently in place in the system Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
BEGIN - COMMIT – ROLLBACK TRANSACTION A COMMIT always balances a BEGIN TRANSACTION by reducing the transaction count by one A single ROLLBACK always rolls back the entire transaction Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Atomicity ??? BEGIN TRANSACTION Correct INSERT Icorrect UPDATE –Statement termination Error Correct DELETE COMMIT TRANSACTION In default mode (XACT_ABORT OFF): The first and third statement will be commited Atomicity is conditional Developers are responsible for transaction management IF @@Error <> 0 ROLLBACK TRANSACTION. Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Transaction mode Autocommit Transaction Mode Explicit Transaction Mode Implicit Transaction Mode Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Transaction Isolation Levels Dirty Read Non-Repeatable Read Phantom Read Uncommitted Yes Read Committed (default) No Repeatable Read Serializable Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
XACT_ABORT – enforce atomicity SET XACT_ABORT ON SET XACT_ABORT OFF --Demo5Tab p1 char(4),p2 char(12) BEGIN TRANSACTION INSERT INTO Demo5Tab Values('A','B') UPDATE Demo5Tab set P1 = 'very long string' UPDATE Demo5Tab set P2 = rtrim(P2) + '- Updated' COMMIT TRANSACTION GO SELECT * FROM Demo5Tab (1 row(s) affected) <error description> p1 p2 ------ ------------ (0 row(s) affected) (1 row(s) affected) <error description> p1 p2 ------ ------------ A B- Updated Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
XACT_ABORT & Scope L.Error SET XACT_ABORT ON exec Demo6PrCaller go select * from Demo6Tab p1 p2 ------ ------ 1 1 2 2 (2 row(s)affected) CREATE PROCEDURE Demo6PrCaller AS DECLARE @Ret INT BEGIN TRANSACTION INSERT INTO Demo6Tab Values('1','1') SET @Ret = 7777 EXEC @Ret = Demo6ScopeAbort PRINT 'Return' + str(@Ret) COMMIT TRANSACTION 1 row(s) affected Return 7777 1 row(s) affected CREATE PROCEDURE Demo6ScopeAbort AS INSERT INTO Demo6Tab Values('2','2') UPDATE TabNonExist set P1 = 'X' UPDATE Demo6Tab set P2 = rtrim(P2) + '- Updated' Invalid object name TabNonExist Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Scope level error – DEMO XACT_ABORT is unable to force atomicity if error causes scope level error Conclusion XACT_ABORT can’t ensure database consistency, without checking system function @@Error XACT_ABORT can’t help to localize error Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Creating and executing stored procedure Query processor Resolution (deferred name resolution) Create Procedure Parsing Insert Into syscomments query optimizer (execution plan ) Compile error execution plan in memory First Execution Execution Run time Successful execution Non First Execution Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
DNR & CodePage 1251 One of the following statements will generate error UPDATE TABLE TableName SET p1 = 1 UPDATE TABLE ТableName SET p1 = 1 Using similar letters but different ascii characters increase the risk of errors caused by referencing none existing objects. In this example T <> Т SELECT ASCII ('T') English – Latin T 84 SELECT ASCII ('Т') Macedonian – Cyrilic T 210 Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Error detection using system function @@Error (statement level error) DECLARE @Err AS INT EXEC ProcNonExist SET @Err = @@error IF @Err <> 0 SELECT 'ERROR ' + str(@Err) ELSE SELECT 'THERE IS NO ERROR' Server: Msg 2812, Level 16, State 62, Line 2 Could not find stored procedure 'ProcNonExist'. ERROR 2812 (1 row(s) affected) Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Error detection using system function @@Error (batch level error) CREATE TABLE Demo8Tab (p1 int) GO INSERT INTO Demo8Tab VALUES (‘this has to be int') IF @@ERROR <> 0 SELECT 'ERROR' ELSE SELECT 'OK' Server: Msg 245, Level 16, State 1, Line 1 Syntax error converting the varchar value 'this has to be int' to a column of data type int. ----- ERROR Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Short life of @@Error system function Declare name_Cursor cursor for select 'something' Declare name_Cursor cursor for select 'something_else' if @@error <> 0 select @@error Server: Msg 16915, Level 16, State 1, Line 2 A cursor with the name 'name_Cursor' already exists. ----------- declare @Err INT Declare name_Cursor cursor for select 'something' Declare name_Cursor cursor for select 'something_else' SET @Err = @@error if @Err <> 0 select @Err Server: Msg 16915, Level 16, State 1, Line 3 A cursor with the name 'name_Cursor' already exists. ----------- 16915 Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Pseudo Return parameter ansi_nulls on if null <> 0 select 'yes' else select 'no' ---- no ansi_nulls off if null <> 0 select 'yes' else select 'no' ---- yes Pseudo Return parameter DECLARE @Ret INT --it follow exec without error EXEC @Ret = Demo10Proc1 If @Ret = 0 Print 'OK' Else Print ‘Error' --sleduva scope abortion EXEC @Ret = Demo10Proc2 Else Print 'Error' OK <Error message …> OK It seems like both procedures return zero, But the second exec doesn’t affect return parameter and @Ret, In this case it is not enough to check IF @Ret = 0 Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Solution for pseudo Return DECLARE @Ret INT -- it follow exec without error EXEC @Ret = Demo10Proc1 SELECT @Ret = COALESCE(nullif(@Ret, 0),@@error,1001) If @Ret = 0 Print 'OK' Else Print ‘Error' -- it follow scope abortion EXEC @Ret = Demo10Proc2 OK <Error message…> Error COALESCE (expression1,...n) Returns the first nonnull expression among its arguments NULLIF ( expression , expression ) Returns a null value if the two specified expressions are equivalent Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Return - status number -1 Missing object. -2 Data type error. -3 Process was chosen as deadlock victim. -4 Permission error. -5 Syntax error. -6 Miscellaneous user error. -7 Resource error, such as out of space. -8 Nonfatal internal problem. -9 System limit was reached. -10 Fatal internal inconsistency. -11 -12 Table or index is corrupt. -13 Database is corrupt. -14 Hardware error. Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Handling “Error Handling” SYSTEM STATISTICAL FUNCTIONS @@PACKET_ERRORS @@TOTAL_ERRORS DATABASE OPTIONS ARITHABORT ARITHIGNORE ANSI_WARNINGS NUMERIC_ROUNDABORT ARITHABORT ANSI_WARNINGS Behavior ON Abort statement only. OFF Abort batch. Continue; value is NULL . Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Hierarchical view of stored procedures Clasification of stored procedures depend on nested level: First Level (FL) Procedure called by client application, FL procedure calls ML and LL stored procedures Middle Level (ML) Nested procedure called by other stored procedure, ML procedure calls ML or LL stored procedures Last Level (LL) Nested procedure called by FL or ML procedure, LL procedure doesn’t call other stored procedures Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Creating hierarchical view Finding real dependencies between stored procedures: Sysdepends inconsistency Developing solution to find real dependencies www.sqlservercentral.com/columnists/spopovski/findingrealdependencies.asp Creating hierarchy using dependencies: Proc1 Proc2 Proc2 Proc3 Proc4 Proc5 www.sqlservercentral.com/columnists/spopovski/viewingthehierarchyofstoredprocedures.asp Proc1 >---Proc2 >------Proc3 Proc4 >--Proc5 Hierarchical view benefits: Error Handling Control over data and business flow Documentation Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Last level procedure CREATE PROCEDURE Proc111 AS UPDATE Table1 … SET @Err = @@ERROR IF @Err <> 0 BEGIN [RAISERROR/XP_LOGEVENT] RETURN (@Err) END Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Middle level procedure CREATE PROCEDURE Proc11 AS UPDATE Table1 … SET @Err = @@ERROR IF @Err <> 0 BEGIN [RAISERROR/XP_LOGEVENT] RETURN (@Err) END EXEC @Ret = Proc111 SELECT @Ret = coalesce(nullif(@Ret, 0),@@error,1001) IF @Ret <> 0 BEGIN [RAISERROR/XP_LOGEVENT] RETURN (@Ret) END Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
First level procedure CREATE PROCEDURE Proc1 AS BEGIN TRANSACTION … UPDATE Table1 … SET @Err = @@ERROR IF @Err <> 0 BEGIN ROLLBACK TRANSACTION [RAISERROR/XP_LOGEVENT] RETURN (@Err) END EXEC @Ret = Proc11 SELECT @Ret = coalesce(nullif(@Ret, 0), @@error, 1001) IF @Ret <> 0 BEGIN ROLLBACK TRANSACTION [RAISERROR/XP_LOGEVENT] RETURN (@Ret) END COMMIT TRANSACTION Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Several considerations 1. Getting native error versus keeping error location 2. What if Error occurs in error handling block ? 3. To log or not to log ? 4. To raise or not to raise ? 5. Controling transactions in first level procedures 6. Avoiding recompilations 7. How to trap errors in user defined functions ? 8. Is it the stress test enough to avoid error handling blocks ? 9. Is it possible to make bullet proof stored procedure ? … Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Trapping errors with SQL Profiler Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
YUKON – Error Handling BEGIN TRY BEGIN Transaction SELECT ‘error’ / 0 COMMIT Transaction END TRY BEGIN CATCH TRAN_ABORT DECLARE @err int SELECT @err = @@error PRINT '@@error: ' + ltrim(str(@err)) ROLLBACK END CATCH Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
Links http://www.algonet.se/~sommar/error-handling-II.html http://www.sqlservercentral.com/columnists/spopovski/beprepared.asp http://support.microsoft.com/default.aspx?scid=kb;en-us;44519 Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy
THANK YOU ! Error Handling & Optimizing T-SQL Code in SQL Server 2000 * 205 June 25, 2004 – 9.45 2004 PASS SQL Server Academy