<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TRY&amp;CATCH &#8211; SQLpowered.com</title>
	<atom:link href="https://sqlpowered.com/tag/trycatch/feed/" rel="self" type="application/rss+xml" />
	<link>https://sqlpowered.com</link>
	<description>SQL Server + BI</description>
	<lastBuildDate>Thu, 11 Mar 2021 07:40:42 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://sqlpowered.com/wp-content/uploads/2020/07/FavIcon-e1594067873682-99x100.png</url>
	<title>TRY&amp;CATCH &#8211; SQLpowered.com</title>
	<link>https://sqlpowered.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>TRY &#038; CATCH pattern</title>
		<link>https://sqlpowered.com/try-catch-pattern/</link>
					<comments>https://sqlpowered.com/try-catch-pattern/#respond</comments>
		
		<dc:creator><![CDATA[Jan Dvořák]]></dc:creator>
		<pubDate>Fri, 08 Dec 2017 21:39:58 +0000</pubDate>
				<category><![CDATA[T-SQL]]></category>
		<category><![CDATA[TRY&CATCH]]></category>
		<guid isPermaLink="false">https://sqlpowered.com/?p=424</guid>

					<description><![CDATA[TRY &#38; CATCH should be used where reasonable to prevent unhandled exceptions in T-SQL code and routines. It&#8217;s prepared for copy/paste purposes for everyday use. We may have two basic types of pattern: The new one using THROW keyword The legacy one with RAISERROR() THROW version: BEGIN TRY BEGIN TRAN...]]></description>
										<content:encoded><![CDATA[<p>TRY &amp; CATCH should be used where reasonable to prevent unhandled exceptions in T-SQL code and routines. It&#8217;s prepared for copy/paste purposes for everyday use.</p>
<p>We may have two basic types of pattern:</p>
<ul>
<li>The <em>new</em> one using THROW keyword</li>
<li>The <em>legacy</em> one with RAISERROR()</li>
</ul>
<p><strong>THROW</strong> version<strong>:<br />
</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">BEGIN TRY
    BEGIN TRAN

		PRINT 1/0 -- "Divide by zero error encountered." error

END TRY
BEGIN CATCH

    IF @@TRANCOUNT &gt; 0
        ROLLBACK TRANSACTION

	;THROW

END CATCH

IF @@TRANCOUNT &gt; 0
	ROLLBACK
GO</pre>
<p><strong>RASIERROR()</strong> version<strong>:</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">BEGIN TRY

    BEGIN TRAN

		PRINT 1/0 -- "Divide by zero error encountered." error

END TRY
BEGIN CATCH

    IF @@TRANCOUNT &gt; 0
        ROLLBACK TRANSACTION

	DECLARE @Message NVARCHAR(4000)

	SET @Message = ERROR_MESSAGE()

    RAISERROR (@Message, 16, 1);

END CATCH

IF @@TRANCOUNT &gt; 0
	ROLLBACK
GO</pre>
<p>They both work pretty well for most of the usage scenarios but there is one very important difference to remember: <strong>The THROW statement is terminating the batch where it fires an error</strong>!</p>
<p>Let&#8217;s see it in action:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">BEGIN TRY
    BEGIN TRAN

		PRINT 1/0 -- "Divide by zero error encountered." error

END TRY
BEGIN CATCH

    IF @@TRANCOUNT &gt; 0
        ROLLBACK TRANSACTION

	;THROW

	SELECT 'This Wan''t be executed 1'

END CATCH

SELECT 'This Wan''t be executed 2'
GO</pre>
<p><img decoding="async" class="alignnone wp-image-4763" src="https://sqlpowered.com/wp-content/uploads/2017/12/TRY_CATCH_TROW.png" alt="" width="249" height="49" srcset="https://sqlpowered.com/wp-content/uploads/2017/12/TRY_CATCH_TROW.png 407w, https://sqlpowered.com/wp-content/uploads/2017/12/TRY_CATCH_TROW-300x59.png 300w, https://sqlpowered.com/wp-content/uploads/2017/12/TRY_CATCH_TROW-150x29.png 150w, https://sqlpowered.com/wp-content/uploads/2017/12/TRY_CATCH_TROW-360x71.png 360w, https://sqlpowered.com/wp-content/uploads/2017/12/TRY_CATCH_TROW-160x31.png 160w, https://sqlpowered.com/wp-content/uploads/2017/12/TRY_CATCH_TROW-320x63.png 320w" sizes="(max-width: 249px) 100vw, 249px" /></p>
<p>Once the THROW statement was executed it has also terminated the batch and SELECT statements weren&#8217;t executed. If we will run the same with RAISERROR() the result is different:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">BEGIN TRY

    BEGIN TRAN

		PRINT 1/0
	
END TRY
BEGIN CATCH

	DECLARE @Message NVARCHAR(4000)
	SET @Message = ERROR_MESSAGE()

	RAISERROR(@Message, 16, 1);
	
	SELECT 'This is executed 1'	

END CATCH

SELECT 'This is executed 1'	
GO</pre>
<p><img decoding="async" class="alignnone wp-image-4765" src="https://sqlpowered.com/wp-content/uploads/2017/12/TRY_CATCH_TROW_2.png" alt="" width="157" height="97" srcset="https://sqlpowered.com/wp-content/uploads/2017/12/TRY_CATCH_TROW_2.png 298w, https://sqlpowered.com/wp-content/uploads/2017/12/TRY_CATCH_TROW_2-150x93.png 150w, https://sqlpowered.com/wp-content/uploads/2017/12/TRY_CATCH_TROW_2-160x99.png 160w" sizes="(max-width: 157px) 100vw, 157px" /></p>
<p>Same time the error message will be fired in the Messages window.</p>
<p>This is a very important difference that can drastically affect more complex T-SQL logic especially in the case of nested stored procedures or retry logic patterns.</p>
<p>For more details see:</p>
<ul>
<li><a href="https://docs.microsoft.com/en-us/sql/t-sql/language-elements/throw-transact-sql?view=sql-server-ver15" target="_blank" rel="noopener noreferrer">THROW</a></li>
<li><a href="https://docs.microsoft.com/en-us/sql/t-sql/language-elements/raiserror-transact-sql?view=sql-server-ver15" target="_blank" rel="noopener noreferrer">RAISERROR()</a></li>
</ul>
<p>Even if it looks to be easy, using TRY &#8230; CATCH is very complex when the type of fired error or other conditions came in the game. The best article ever written on this topic is by <a href="http://www.sommarskog.se/error_handling/Part1.html" target="_blank" rel="noopener noreferrer">Erland Sommarskog</a>. I&#8217;m strongly recommending read it thru.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sqlpowered.com/try-catch-pattern/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Výpis chyb z CATCH bloku</title>
		<link>https://sqlpowered.com/vypis-chyb-z-catch-bloku/</link>
					<comments>https://sqlpowered.com/vypis-chyb-z-catch-bloku/#respond</comments>
		
		<dc:creator><![CDATA[Jan Dvořák]]></dc:creator>
		<pubDate>Sat, 02 May 2015 20:49:39 +0000</pubDate>
				<category><![CDATA[T-SQL]]></category>
		<category><![CDATA[TRY&CATCH]]></category>
		<guid isPermaLink="false">https://sqlpowered.com/?p=627</guid>

					<description><![CDATA[Při psaní složitějších rutin v T-SQL a zejména při zanořování uložených procedur a dalších pokročilých scénářích je určitě na místě předejít nekontrolovaným chybám využitím konstrukce TRY &#38; CATCH. Pokud nějaká chyba přeci jen nastane a zachytíme ji v CATCH bloku, potřebujeme vědět, o jakou chybu se jedná. Pokud nepošleme chybu...]]></description>
										<content:encoded><![CDATA[<p>Při psaní složitějších rutin v T-SQL a zejména při zanořování uložených procedur a dalších pokročilých scénářích je určitě na místě předejít nekontrolovaným chybám využitím konstrukce <a href="https://docs.microsoft.com/en-us/sql/t-sql/language-elements/try-catch-transact-sql?view=sql-server-2017" target="_blank" rel="noopener noreferrer">TRY &amp; CATCH</a>. Pokud nějaká chyba přeci jen nastane a zachytíme ji v CATCH bloku, potřebujeme vědět, o jakou chybu se jedná. Pokud nepošleme chybu dále z CATCH bloku pomocí THROW, je na nás, abychom pomocí systémových funkcí získali popis chyby a dále s ním pracovali, buď vrácením uživateli nebo zapsáním do logu. A není nic rozumnějšího, než vypisování chyb sjednotit pro celé databázové řešení a mít jednotný výstupní formát, který bude jak jednoduše strojově zpracovatelný, tak i uživatelsky přívětivý a přidá nějakou tu informaci navíc.</p>
<p>Jednou z elegantních možností je, že pro sestavení chybové zprávy vytvoříme samostatnou proceduru, kterou budeme následně volat z CATCH bloku bez dalšího zbytečného kódu.</p>
<p>Procedura pro sestavení chybové zprávy může vypadat například takto:</p>
<pre class="lang:tsql decode:true">CREATE OR ALTER PROCEDURE [dbo].[FireError]
AS
BEGIN    
    
	DECLARE @ErrorMessage NVARCHAR(MAX)
	DECLARE @ErrorSeverity INT
	DECLARE @ErrorState INT

	SET @ErrorSeverity = ERROR_SEVERITY()
	SET @ErrorState = ERROR_STATE()

    SET @ErrorMessage =  
        '|' + ISNULL(CAST(ERROR_NUMBER() AS NVARCHAR(10)), 'ERROR_NUMBER') +  ' | ' +
              ISNULL(CAST(@ErrorSeverity AS NVARCHAR(10)), 'ERROR_SEVERITY') +  ' | ' +
              ISNULL(CAST(@ErrorState AS NVARCHAR(10)), 'ERROR_STATE') +  ' | ' +
              ISNULL(ERROR_PROCEDURE(), 'CALLED_OUTSIDE_STORED_PROCEDURE') +  ' | ' +
              ISNULL(CAST(ERROR_LINE() AS NVARCHAR(10)), 'ERROR_LINE') +  ' | ' +
              ISNULL(ERROR_MESSAGE(), 'ERROR_MESSAGE')  + 
        '|'
    
	RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState)

	RETURN 0

END
GO</pre>
<p>Tělo procedury pouze volá systémové funkce pro získání popisu chyby a formátuje jejich výstup do uživatelský přívětivé podoby.</p>
<p>Proceduru pak můžeme volat v CATCH bloku takto:</p>
<pre class="lang:tsql decode:true">BEGIN TRY

	PRINT 1/0

END TRY
BEGIN CATCH

	EXEC [dbo].[FireError]

END CATCH
GO</pre>
<p><img decoding="async" class="alignnone size-full wp-image-3054" src="https://sqlpowered.com/wp-content/uploads/2015/05/TRY_CATCH_ErrorMessage_Formating_1.png" alt="" width="615" height="28" srcset="https://sqlpowered.com/wp-content/uploads/2015/05/TRY_CATCH_ErrorMessage_Formating_1.png 615w, https://sqlpowered.com/wp-content/uploads/2015/05/TRY_CATCH_ErrorMessage_Formating_1-150x7.png 150w, https://sqlpowered.com/wp-content/uploads/2015/05/TRY_CATCH_ErrorMessage_Formating_1-300x14.png 300w, https://sqlpowered.com/wp-content/uploads/2015/05/TRY_CATCH_ErrorMessage_Formating_1-160x7.png 160w, https://sqlpowered.com/wp-content/uploads/2015/05/TRY_CATCH_ErrorMessage_Formating_1-320x15.png 320w, https://sqlpowered.com/wp-content/uploads/2015/05/TRY_CATCH_ErrorMessage_Formating_1-520x24.png 520w" sizes="(max-width: 615px) 100vw, 615px" /></p>
<p>Na obrázku je vidět, jak vypadá zformátovaná chybová zpráva. A barevně je vyznačeno jedno drobné vylepšení, které jsme do sestavení chybové zprávy přidali: pokud již nastane v SQL Serveru uživatelská chyba, často první po čem budeme pátrat je, zda se jednalo o ad-hoc kód nebo došlo k chybě v uložené proceduře. Zde vidíme, že k chybě došlo v kódu mimo uloženou proceduru.</p>
<p>Pojďme nyní otestovat stejnou chybu, ale vyvolejme ji v těle testovací uložené procedury:</p>
<pre class="lang:tsql decode:true">CREATE PROCEDURE [dbo].[TestProcedure]
AS
BEGIN

	BEGIN TRY

		PRINT 1/0

	END TRY
	BEGIN CATCH

		EXEC [dbo].[FireError]
	
	END CATCH
    
END
GO

EXEC [dbo].[TestProcedure]
GO</pre>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-3056" src="https://sqlpowered.com/wp-content/uploads/2015/05/TRY_CATCH_ErrorMessage_Formating_2.png" alt="" width="556" height="29" srcset="https://sqlpowered.com/wp-content/uploads/2015/05/TRY_CATCH_ErrorMessage_Formating_2.png 556w, https://sqlpowered.com/wp-content/uploads/2015/05/TRY_CATCH_ErrorMessage_Formating_2-150x8.png 150w, https://sqlpowered.com/wp-content/uploads/2015/05/TRY_CATCH_ErrorMessage_Formating_2-300x16.png 300w, https://sqlpowered.com/wp-content/uploads/2015/05/TRY_CATCH_ErrorMessage_Formating_2-160x8.png 160w, https://sqlpowered.com/wp-content/uploads/2015/05/TRY_CATCH_ErrorMessage_Formating_2-320x17.png 320w, https://sqlpowered.com/wp-content/uploads/2015/05/TRY_CATCH_ErrorMessage_Formating_2-520x27.png 520w" sizes="auto, (max-width: 556px) 100vw, 556px" /></p>
<p>Nyní nám chybová zpráva přímo ukazuje název uložené procedury, ve které k chybě došlo a vím tak rovnou, kam do databáze sáhnout a chybu opravit.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sqlpowered.com/vypis-chyb-z-catch-bloku/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
