<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>SQL Programmability &amp; API Development Team Blog : SQL Exception Handling</title><link>http://blogs.msdn.com/sqlprogrammability/archive/tags/SQL+Exception+Handling/default.aspx</link><description>Tags: SQL Exception Handling</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Server Side Error Handling - Part 3 (Why do I still see error messages from inside tsql try-block?)</title><link>http://blogs.msdn.com/sqlprogrammability/archive/2006/04/07/571048.aspx</link><pubDate>Fri, 07 Apr 2006 22:46:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:571048</guid><dc:creator>NaveenP</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/sqlprogrammability/comments/571048.aspx</comments><wfw:commentRss>http://blogs.msdn.com/sqlprogrammability/commentrss.aspx?PostID=571048</wfw:commentRss><description>&lt;P&gt;There are cases when you see error messages relayed from inside the try-block. Some are intuitive and some are not.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Compile Errors&lt;/STRONG&gt; - These errors can simply not be caught. This is true for any programming language. When compilation of a program generates an error it can not be caught by the enclosing try-block. As the batch has not started execution, there is no way BEGIN TRY would take affect. I am always asked how I differentiate between compile and non compile errors. Some errors like syntax errors are obvious, some are not. One way to figure it out is to put a PRINT statement immediately after the BEGIN TRY statement. If the message is not printed and you see an error message, it is a compile error and can not be caught.&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;BEGIN TRY&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;PRINT 'Inside Try-Block'&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;SELECT ** FROM T&amp;nbsp; /* will cause syntax error */&lt;BR&gt;END TRY&lt;BR&gt;BEGIN CATCH&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;SELECT error_number() as 'Error In Try Block'&lt;BR&gt;END CATCH&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;A compile error generated in the lower scope would be caught. This is because the compile of the lower scope happens during the execution of the enclosing scope (more specifically after the execution of BEGIN TRY).&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;BEGIN TRY&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;PRINT 'Inside Try-Block'&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;EXEC ('SELECT ** FROM T&amp;nbsp;)&amp;nbsp;/* compile error in the lower scope */&lt;BR&gt;END TRY&lt;BR&gt;BEGIN CATCH&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;SELECT error_number() as 'Error In Try Block'&lt;BR&gt;END CATCH&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;Note that in this case you will see the 'Inside Try-Block' message getting printed.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Recompile Errors&lt;/STRONG&gt; - They are raised when a statement recompiles because of change in schema, environment, statistics, etc. They are similar to compile errors, except that they would be raised after BEGIN TRY has executed. We debated on weather to catch such errors or not. Finally we decided against catching them to keep it consistent with compile errors. The decision was also influenced by the fact that on recompile we exit the execution driver in the SQL&amp;nbsp; Server and enter the compilation module to recompile the statement. This behavior is not guaranteed in future releases. We may decide to catch these errors as the BEGIN TRY was executed and the handler was activated.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Remote execution of a Procedure&lt;/STRONG&gt; - When a procedure/batch (pass-through) is executed remotely (through four-part name or EXECUTE AT), the error handling on the local server depends on the type of remote server and the error action at the remote server if it is a SQL Server.&lt;/LI&gt;
&lt;UL&gt;
&lt;LI dir=ltr&gt;If the remote server is not a SQL Server, it is difficult to parse the error message for its processing at the local server. Such error message from the remote server is relayed to the client without any processing at the local server. The local server though detects that an error happened on remote execution and it would raise a generic error. This generic error will be handled by the local tsql try-catch.&lt;/LI&gt;
&lt;LI dir=ltr&gt;If the remote server is SQL Server, the local server tries to find out if the remote execution resulted in batch abort or higher. If remote execution was aborted then the error causing the abort can be handled at the local server. All previous error messages are relayed. In the absence of batch abort, all error messages are relayed to the client without any processing at the local server. This behavior is consistent with @@error behavior in prior release of SQL Server. @@error was set if and only if the remote execution was aborted. We would like to have the same behavior for non-SQL Servers, but the oledb does not have any API to detect the error action at the server.&lt;/LI&gt;&lt;/UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Attentions&lt;/STRONG&gt; - Attentions are sent when a running query is cancelled. The server detects an attention and aborts the execution. There was a considerable debate on whether to catch attentions or not. Finally it was decided not to catch them (except for DTC attentions). Attentions (excluding DTC attention) do not result in an error message. If they were caught the error intrinsics would not be populated inside the catch block and no logic based on error number could be written. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;This concludes my talk on server side error handling. If you have any questions or comments please feel free to send them my way.&lt;/P&gt;
&lt;P&gt;Thanks&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=571048" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/sqlprogrammability/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://blogs.msdn.com/sqlprogrammability/archive/tags/SQL+Exception+Handling/default.aspx">SQL Exception Handling</category></item><item><title>Server Side Error Handling - Part 2 (Errors and Error Messages)</title><link>http://blogs.msdn.com/sqlprogrammability/archive/2006/04/03/567550.aspx</link><pubDate>Mon, 03 Apr 2006 23:08:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:567550</guid><dc:creator>NaveenP</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/sqlprogrammability/comments/567550.aspx</comments><wfw:commentRss>http://blogs.msdn.com/sqlprogrammability/commentrss.aspx?PostID=567550</wfw:commentRss><description>&lt;P&gt;&lt;FONT face=Arial&gt;Each error in the server has two parts - an error message that describes the error that happened in the server and an error action that determines the effect of the error on the statement, level, batch, transaction, connection and/or server.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;Server has instances of different combinations of errors and error messages. The major ones are:&lt;/FONT&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;FONT face=Arial&gt;&lt;STRONG&gt;One error, one error message&lt;/STRONG&gt; - This is the most common case and most intuitive.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Arial&gt;&lt;STRONG&gt;One error, two or more error messages&lt;/STRONG&gt; - When an error is raised in a some special context, the first message has information about the error, while subsequent messages provides information about the context. This becomes an issue inside tsql try-catch. In the absence of any notion about error collection, the catch block is activated with one of the error messages. As sql server 2000 would have set @@error to the last error message, we decided to set error intrinsics (error_message(), etc.) to the last error message inside the catch block. In other words sql server 2005 would ignore all but the last error message inside tsql try-catch. Many systems would merge these error messages into one. One way to merge two error messages would be to provide the first message as a payload of the context message. Backward compatibility prevents us from mergeing old error messages. Care would be taken to not have multiple error messages for one error in future releases.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Arial&gt;&lt;STRONG&gt;Multiple errors, multiple error messages&lt;/STRONG&gt; - In this situation the server displays as many information as possible before stopping execution. This is mostly useful in development when one wants to see all compile errors or permission failures before the execution is terminated. Inside tsql try-catch the ideal behavior would be to stop execution on first error and handle it in the catch block. This is what we have tried in sql server 2005. Note this is different from @@error behavior where it would be set to the last error.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Arial&gt;&lt;STRONG&gt;No error, one or more error messages&lt;/STRONG&gt; - This happens when server recovers from non-severe errors and continues with exectuion. In reality these are informational or warning messages. They should have been sent with lower severity (10 to be precise), but can not be done because of backward compatibility. As clients do not expect to see any error messages inside tsql try-catch, they are silently ignored inside a try-block. The execution happens as if nothing has happened.&lt;/FONT&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;Once an error happens, server determines the action to take. Statement abort will abort the current statement. Level abort will terminate an executing proc, and will be visible as a statement abort in the scope of the caller. Batch aborts will terminate the batch. Transaction abort will abort the batch and rollback the transaction. Severe errors would kill the connection, while extremely severe error will shutdown the server. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;Currently, the error action depends on the error message, the severity with which it is raised and the context in which it is raised. For tsql developer, it is very difficult to determine the error action for any error during development. Going forward we may enforce a rule where the error action just depends on the error message. To ensure that the error handling does not break on upgrades, this can only be done for new error messages.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;In next post I will continue the discussion on certain error messages that are still relayed to clients from inside tsql tr-catch.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;Thanks&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=567550" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/sqlprogrammability/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://blogs.msdn.com/sqlprogrammability/archive/tags/SQL+Exception+Handling/default.aspx">SQL Exception Handling</category></item><item><title>Server Side Error Handling - Part 1 (Migrating from @@error to tsql try-catch)</title><link>http://blogs.msdn.com/sqlprogrammability/archive/2006/03/30/565141.aspx</link><pubDate>Thu, 30 Mar 2006 21:17:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:565141</guid><dc:creator>NaveenP</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/sqlprogrammability/comments/565141.aspx</comments><wfw:commentRss>http://blogs.msdn.com/sqlprogrammability/commentrss.aspx?PostID=565141</wfw:commentRss><description>&lt;P&gt;Tsql try-catch was added to improve server side error handling in sql server 2005. This feature should have been part of early T-Sql. Better late than never.&lt;/P&gt;
&lt;P&gt;In absence of tsql try-catch, server-side error handling was done using @@error. This had necessitated statement abort as the error policy. Under this policy the execution of a batch/procedure continues after full or partial rollback of the tsql statement that raised an error.&lt;/P&gt;
&lt;P&gt;Command:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;print 'test @@error'&lt;BR&gt;select 4/0&lt;BR&gt;if (@@error = 8134)&lt;BR&gt;&amp;nbsp;print 'Error Encountered'&lt;BR&gt;print 'Execution Continues'&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Output:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;test @@error&lt;/P&gt;
&lt;P&gt;-----------&lt;BR&gt;Msg 8134, Level 16, State 1, Line 2&lt;BR&gt;Divide by zero error encountered.&lt;/P&gt;
&lt;P&gt;Error Encountered&lt;BR&gt;Execution Continues&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;There are two drawbacks:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;'Statement Abort' as an error policy is rarely found in a procedural language. This is counter-intuitive.&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;Clients do not expect to see any error message if an error is handled at the server.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&lt;BR&gt;The above batch can be replaced using tsql try-catch.&lt;/P&gt;
&lt;P&gt;Command:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;begin Try&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print ' test tsql try-catch'&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;select 4/0&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print 'Execution Halts'&lt;BR&gt;end try&lt;BR&gt;begin catch&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print ' error caught'&lt;BR&gt;end catch&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Output:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&amp;nbsp;test tsql try-catch&lt;/P&gt;
&lt;P&gt;-----------&lt;/P&gt;
&lt;P&gt;(0 row(s) affected)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;error caught&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;There is no 'Statement Abort' inside a tsql try-catch. Error is handled at the server and no error message is relayed to the client. The execution inside tsql try-catch stops on an error and the catch block is activated.&lt;/P&gt;
&lt;P&gt;For backwad compatibility we still have 'statement abort' as an error policy. Moving forward there is a chance that it might be deprecated.&lt;/P&gt;
&lt;P&gt;In next post, I will discuss why some errors are not caught (either sent to the client or ignored silently) by tsql try-catch.&lt;/P&gt;
&lt;P&gt;Thanks&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=565141" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/sqlprogrammability/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://blogs.msdn.com/sqlprogrammability/archive/tags/SQL+Exception+Handling/default.aspx">SQL Exception Handling</category></item></channel></rss>