<?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"
	>

<channel>
	<title>rusanu.com</title>
	<atom:link href="http://rusanu.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://rusanu.com</link>
	<description>RUSANU CONSULTING LLC</description>
	<pubDate>Fri, 29 Jan 2010 00:51:41 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<item>
		<title>What deprecated features am I using?</title>
		<link>http://rusanu.com/2010/01/12/what-deprecated-features-am-i-using/</link>
		<comments>http://rusanu.com/2010/01/12/what-deprecated-features-am-i-using/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 19:37:20 +0000</pubDate>
		<dc:creator>remus</dc:creator>
		
		<category><![CDATA[Troubleshooting]]></category>

		<category><![CDATA[deprecated features]]></category>

		<category><![CDATA[sql]]></category>

		<category><![CDATA[sql server 2005]]></category>

		<category><![CDATA[sql server 2008]]></category>

		<category><![CDATA[tsql]]></category>

		<guid isPermaLink="false">http://rusanu.com/?p=606</guid>
		<description><![CDATA[Copyright Remus Rusanu 2010. Visit the original article at http://rusanu.com/2010/01/12/what-deprecated-features-am-i-using/&#160;&#160;
select instance_name as [Deprecated Feature]
  , cntr_value as [Frequency Used]
from sys.dm_os_performance_counters
where object_name = 'SQLServer:Deprecated Features'
and cntr_value &#62; 0
order by cntr_value desc


Quick way to tell which deprecated feature are used on a running instance of SQL Server. The performance counters reset at each server start up, [...]]]></description>
			<content:encoded><![CDATA[<p>Copyright Remus Rusanu 2010. Visit the original article at <a href="http://rusanu.com/2010/01/12/what-deprecated-features-am-i-using/">http://rusanu.com/2010/01/12/what-deprecated-features-am-i-using/</a></p>&nbsp;&nbsp;<br><p><code></p>
<pre><span style="color: Black"></span><span style="color:Blue">select </span><span style="color:Black">instance_name </span><span style="color:Blue">as </span><span style="color:Black">[Deprecated Feature]
  </span><span style="color:Gray">, </span><span style="color:Black">cntr_value </span><span style="color:Blue">as </span><span style="color:Black">[Frequency Used]
</span><span style="color:Blue">from </span><span style="color:Green">sys</span><span style="color:Gray">.</span><span style="color:Green">dm_os_performance_counters
</span><span style="color:Blue">where </span><span style="color:Fuchsia">object_name </span><span style="color:Gray">= </span><span style="color:Red">'SQLServer:Deprecated Features'
</span><span style="color:Gray">and </span><span style="color:Black">cntr_value </span><span style="color:Gray">&gt; </span><span style="color:Black">0
</span><span style="color:Blue">order by </span><span style="color:Black">cntr_value </span><span style="color:Blue">desc</span>
</pre>
<p></code></p>
<p>Quick way to tell which deprecated feature are used on a running instance of SQL Server. The performance counters reset at each server start up, so the interogation is relevant only after the server was up for some time. This will not tell you where is the usage comming from, but will give you a very quick idea what deprecated features are used most frequently by your apps.</p>
<p>If the SQL Server is a named instance, you have to query the proper counter category: <tt><span style="color:Red">&#8216;MSSQL$&lt;instancename&gt;:Deprecated Features&#8217;</span></tt></p>
]]></content:encoded>
			<wfw:commentRss>http://rusanu.com/2010/01/12/what-deprecated-features-am-i-using/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Applewood smoked Bacon milk Chocolate</title>
		<link>http://rusanu.com/2009/11/28/applewood-smoked-bacon-milk-chocolate/</link>
		<comments>http://rusanu.com/2009/11/28/applewood-smoked-bacon-milk-chocolate/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 23:18:53 +0000</pubDate>
		<dc:creator>remus</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[bacon]]></category>

		<category><![CDATA[chocolate]]></category>

		<guid isPermaLink="false">http://rusanu.com/?p=600</guid>
		<description><![CDATA[Copyright Remus Rusanu 2010. Visit the original article at http://rusanu.com/2009/11/28/applewood-smoked-bacon-milk-chocolate/&#160;&#160;
]]></description>
			<content:encoded><![CDATA[<p>Copyright Remus Rusanu 2010. Visit the original article at <a href="http://rusanu.com/2009/11/28/applewood-smoked-bacon-milk-chocolate/">http://rusanu.com/2009/11/28/applewood-smoked-bacon-milk-chocolate/</a></p>&nbsp;&nbsp;<br><div id="attachment_601" class="wp-caption alignnone" style="width: 510px"><a href="http://rusanu.com/wp-content/uploads/2009/11/baconchocolate.png"><img src="http://rusanu.com/wp-content/uploads/2009/11/baconchocolate.png" alt="Mo\&#039;s Bacon Bar" title="baconchocolate" width="500" height="1076" class="size-full wp-image-601" /></a><p class="wp-caption-text">Mo's Bacon Bar</p></div>
]]></content:encoded>
			<wfw:commentRss>http://rusanu.com/2009/11/28/applewood-smoked-bacon-milk-chocolate/feed/</wfw:commentRss>
		</item>
		<item>
		<title>System pagefile size on machines with large RAM</title>
		<link>http://rusanu.com/2009/11/22/system-pagefile-size-on-machines-with-large-ram/</link>
		<comments>http://rusanu.com/2009/11/22/system-pagefile-size-on-machines-with-large-ram/#comments</comments>
		<pubDate>Sun, 22 Nov 2009 22:33:17 +0000</pubDate>
		<dc:creator>remus</dc:creator>
		
		<category><![CDATA[Troubleshooting]]></category>

		<category><![CDATA[address space]]></category>

		<category><![CDATA[capacity planning]]></category>

		<category><![CDATA[memory]]></category>

		<category><![CDATA[out of memory]]></category>

		<category><![CDATA[pagefile]]></category>

		<category><![CDATA[sql server]]></category>

		<category><![CDATA[swap]]></category>

		<category><![CDATA[virtual memory]]></category>

		<guid isPermaLink="false">http://rusanu.com/?p=594</guid>
		<description><![CDATA[Copyright Remus Rusanu 2010. Visit the original article at http://rusanu.com/2009/11/22/system-pagefile-size-on-machines-with-large-ram/&#160;&#160;Irrelevant of the size of the RAM, you still need a pagefile at least 1.5 times the amount of physical RAM. This is true even if you have a 1 TB RAM machine, you&#8217;ll need 1.5 TB pagefile on disk (sounds crazy, but is true)
When a [...]]]></description>
			<content:encoded><![CDATA[<p>Copyright Remus Rusanu 2010. Visit the original article at <a href="http://rusanu.com/2009/11/22/system-pagefile-size-on-machines-with-large-ram/">http://rusanu.com/2009/11/22/system-pagefile-size-on-machines-with-large-ram/</a></p>&nbsp;&nbsp;<br><p>Irrelevant of the size of the RAM, you still need a pagefile at least 1.5 times the amount of physical RAM. This is true even if you have a 1 TB RAM machine, you&#8217;ll need 1.5 TB pagefile on disk (sounds crazy, but is true)</p>
<p>When a process asks for MEM_COMMIT memory via VirtualAlloc/VirtualAllocEx, the requested size needs to be reserved in the pagefile. This was true in the first Win NT system, and is still true today see <a href=" http://msdn.microsoft.com/en-us/library/ms810627.aspx" target="_blank">Managing Virtual Memory in Win32</a>:</p>
<blockquote><p>
When memory is committed, physical pages of memory are allocated <b>and space is reserved in a pagefile</b>.
</p></blockquote>
<p>Bare some extreme odd cases, SQL Server will always ask for MEM_COMMIT pages. And given the fact that SQL uses a <a href="http://msdn.microsoft.com/en-us/library/ms178145.aspx" target="_blank">Dynamic Memory Management</a> policy that reserves upfront as much buffer pool as possible (reserves and <i>commits</i> in terms of VAS), SQL Server will request at start up a huge reservation of space in the pagefile. If the pagefile is not properly sized errors 801/802 will start showing up in SQL&#8217;s ERRORLOG file and operations.</p>
<p>This always causes some confusion, as administrators erroneously assume that a large RAM eliminates the need for a pagefile. In truth the contrary happens, a large RAM increases the need for pagefile, just because of the inner workings of the Windows NT memory manager. Although reserved pagefile is, hopefully, never used, the problem of reserving such a huge pagefile file can be quite serious and needs to be accounted for during capacity planning.</p>
]]></content:encoded>
			<wfw:commentRss>http://rusanu.com/2009/11/22/system-pagefile-size-on-machines-with-large-ram/feed/</wfw:commentRss>
		</item>
		<item>
		<title>bugcollect.com: better customer support</title>
		<link>http://rusanu.com/2009/10/28/bugcollectcom-better-customer-support/</link>
		<comments>http://rusanu.com/2009/10/28/bugcollectcom-better-customer-support/#comments</comments>
		<pubDate>Thu, 29 Oct 2009 05:32:43 +0000</pubDate>
		<dc:creator>remus</dc:creator>
		
		<category><![CDATA[Announcements]]></category>

		<category><![CDATA[bug tracking]]></category>

		<category><![CDATA[bugcollect]]></category>

		<category><![CDATA[customer support]]></category>

		<category><![CDATA[system crash]]></category>

		<guid isPermaLink="false">http://rusanu.com/?p=578</guid>
		<description><![CDATA[Copyright Remus Rusanu 2010. Visit the original article at http://rusanu.com/2009/10/28/bugcollectcom-better-customer-support/&#160;&#160;I am a developer, I write applications for fun and profit, and I&#8217;ve been doing this basically my whole professional life. Over the years I&#8217;ve learned that it is important to understand the problems my users face. What are the most common issues, how often do [...]]]></description>
			<content:encoded><![CDATA[<p>Copyright Remus Rusanu 2010. Visit the original article at <a href="http://rusanu.com/2009/10/28/bugcollectcom-better-customer-support/">http://rusanu.com/2009/10/28/bugcollectcom-better-customer-support/</a></p>&nbsp;&nbsp;<br><p>I am a developer, I write applications for fun and profit, and I&#8217;ve been doing this basically my whole professional life. Over the years I&#8217;ve learned that it is important to understand the problems my users face. What are the most common issues, how often do they happen, who is most affected. I have tried the approach of logging into a text file and then asking my users to send me the log file. I&#8217;ve tried sending mail automatically from my application. It was useful, but my inbox just doesn&#8217;t scale to hundreds of messages that may happen after a &#8230; stormy release.</p>
<p>This is why I have created for myself an online service for application crash reporting. Applications can submit incident reports online and the service will collect them, aggregate them and do some initial analysis. I have been using this service in my applications over the past year and I think that if I find it so useful, perhaps you will too. So I&#8217;ve invested more resources into this, made it into a commercial product and put it out for everyone:<a href="bugcollect.com">http://bucollect.com</a>.</p>
<p>After an application is ready and published, bugcollect.com offers a private channel for collecting logging and crash reporting information. bugcollect.com analyzes crash reports and aggregates similar problems into buckets, groups incidents reported by the same source, helping the development team to focus on the most frequent crashes and problems. Developers get immediate feedback if a new release has a problem and they don&#8217;t have to ask for more information. Developers can also set up a response to an incident bucket, this response will be sent by bugcolect.com to any new incident report that falls into the same bucket. The application can then interpret this response and display feedback to the user, eg. it can instruct him about a new download available that fixes the problem.</p>
<p>bugcollect.com reporting differs from system crash reporting like iPhone crash, Mac &#8217;send to apple&#8217; or Windows Dr. Watson because it is application initiated. An application can decide to submit a report anytime it wishes, typically in an exception catch block. All reports submitted to bugcollect.com are private and can be viewed only by the account owner, the application development team.</p>
<p>bugcollect.com features a public RESTful XML based API for submitting reports. There are already available client libraries for .Net and Java, as well as appender components for log4net and log4j. More client libraries are under development and an iPhone library will be made available soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://rusanu.com/2009/10/28/bugcollectcom-better-customer-support/feed/</wfw:commentRss>
		</item>
		<item>
		<title>select count(*);</title>
		<link>http://rusanu.com/2009/10/26/select-count/</link>
		<comments>http://rusanu.com/2009/10/26/select-count/#comments</comments>
		<pubDate>Mon, 26 Oct 2009 19:49:59 +0000</pubDate>
		<dc:creator>remus</dc:creator>
		
		<category><![CDATA[Samples]]></category>

		<category><![CDATA[count]]></category>

		<category><![CDATA[query]]></category>

		<category><![CDATA[select]]></category>

		<category><![CDATA[sql server]]></category>

		<category><![CDATA[trivia]]></category>

		<guid isPermaLink="false">http://rusanu.com/?p=572</guid>
		<description><![CDATA[Copyright Remus Rusanu 2010. Visit the original article at http://rusanu.com/2009/10/26/select-count/&#160;&#160;Quick trivia: what is the result of running SELECT COUNT(*);?
That&#8217;s right, no FROM clause, just COUNT(*). The answer may be a little bit surprising, is 1. When you query SELECT 1; the result is, as expected, 1. And SELECT 2; will return 2. So SELECT COUNT(2); [...]]]></description>
			<content:encoded><![CDATA[<p>Copyright Remus Rusanu 2010. Visit the original article at <a href="http://rusanu.com/2009/10/26/select-count/">http://rusanu.com/2009/10/26/select-count/</a></p>&nbsp;&nbsp;<br><p>Quick trivia: what is the result of running <code>SELECT COUNT(*);</code>?</p>
<p>That&#8217;s right, no <code>FROM</code> clause, just <code>COUNT(*)</code>. The answer may be a little bit surprising, is <bb>1</bb>. When you query <code>SELECT 1;</code> the result is, as expected, 1. And <code>SELECT 2;</code> will return 2. So <code>SELECT COUNT(2);</code> returns, as expected, 1, after all it counts how many rows are in the result set. But <code>SELECT COUNT(*);</code> has a certain smell of voo-doo to it. Ok, is the * project operator, but project from&#8230; what exactly? It feels eerie, like a count is materialized out of the blue.</p>
<p>How about <code>SELECT COUNT(*) [MyTable]</code>. Well, that&#8217;s actually just a shortcut for <code>SELECT COUNT(*) AS [MyTable]</code>, so it still returns 1 but in a column named <code>MyTable</code>. Now you understand why my heart missed a bit when I checked how I initialized a replication subscription and I forgot to type in <b><code>FROM</code></b>&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://rusanu.com/2009/10/26/select-count/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Asynchronous T-SQL at SQL Saturday #26</title>
		<link>http://rusanu.com/2009/09/28/asynchronous-t-sql-at-sql-saturday-26/</link>
		<comments>http://rusanu.com/2009/09/28/asynchronous-t-sql-at-sql-saturday-26/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 02:06:42 +0000</pubDate>
		<dc:creator>remus</dc:creator>
		
		<category><![CDATA[Announcements]]></category>

		<category><![CDATA[asynchronous processing]]></category>

		<category><![CDATA[presentation]]></category>

		<category><![CDATA[speaker]]></category>

		<category><![CDATA[sqlpass]]></category>

		<category><![CDATA[tsql]]></category>

		<guid isPermaLink="false">http://rusanu.com/?p=565</guid>
		<description><![CDATA[Copyright Remus Rusanu 2010. Visit the original article at http://rusanu.com/2009/09/28/asynchronous-t-sql-at-sql-saturday-26/&#160;&#160;The Seattle area PASS group is organizing the SQL Saturday #26 in Redmond on October 2nd. There are many sessions to fill 3 tracks for a full day and all of them look quite interesting. The full schedule is available at http://www.sqlsaturday.com/schedule.aspx. The event is free [...]]]></description>
			<content:encoded><![CDATA[<p>Copyright Remus Rusanu 2010. Visit the original article at <a href="http://rusanu.com/2009/09/28/asynchronous-t-sql-at-sql-saturday-26/">http://rusanu.com/2009/09/28/asynchronous-t-sql-at-sql-saturday-26/</a></p>&nbsp;&nbsp;<br><p>The Seattle area PASS group is organizing the <a href="http://www.sqlsaturday.com/eventhome.aspx?eventid=30" target="_blank">SQL Saturday #26 in Redmond on October 2nd</a>. There are many sessions to fill 3 tracks for a full day and all of them look quite interesting. The full schedule is available at <a href="http://www.sqlsaturday.com/schedule.aspx?eventid=30" target="_blank">http://www.sqlsaturday.com/schedule.aspx</a>. The event is free and you get to hear presentations by such popular SQL persona as <a href="http://www.sqlserverinternals.com/" target="_blank">Kalen Delaney</a>!</p>
<p>On the 10:15 slot yours truly will be talking about <a href="http://www.sqlsaturday.com/viewsession.aspx?sessionid=735">Asynchronous T-SQL processing</a>. See you this Saturday at the new Commons MS campus in Redmond.</p>
]]></content:encoded>
			<wfw:commentRss>http://rusanu.com/2009/09/28/asynchronous-t-sql-at-sql-saturday-26/feed/</wfw:commentRss>
		</item>
		<item>
		<title>On SQL Server boolean operator short-circuit</title>
		<link>http://rusanu.com/2009/09/13/on-sql-server-boolean-operator-short-circuit/</link>
		<comments>http://rusanu.com/2009/09/13/on-sql-server-boolean-operator-short-circuit/#comments</comments>
		<pubDate>Sun, 13 Sep 2009 19:36:38 +0000</pubDate>
		<dc:creator>remus</dc:creator>
		
		<category><![CDATA[Tutorials]]></category>

		<category><![CDATA[boolean]]></category>

		<category><![CDATA[evaluation]]></category>

		<category><![CDATA[expression]]></category>

		<category><![CDATA[short-circuit]]></category>

		<category><![CDATA[sql]]></category>

		<category><![CDATA[tsql]]></category>

		<guid isPermaLink="false">http://rusanu.com/?p=557</guid>
		<description><![CDATA[Copyright Remus Rusanu 2010. Visit the original article at http://rusanu.com/2009/09/13/on-sql-server-boolean-operator-short-circuit/&#160;&#160;Recently I had several discussions all circling around the short-circuit of boolean expressions in Transact-SQL queries. Many developers that come from an imperative language background like C are relying on boolean short-circuit to occur when SQL queries are executed. Often they take this expectation to extreme [...]]]></description>
			<content:encoded><![CDATA[<p>Copyright Remus Rusanu 2010. Visit the original article at <a href="http://rusanu.com/2009/09/13/on-sql-server-boolean-operator-short-circuit/">http://rusanu.com/2009/09/13/on-sql-server-boolean-operator-short-circuit/</a></p>&nbsp;&nbsp;<br><p>Recently I had several discussions all circling around the short-circuit of boolean expressions in Transact-SQL queries. Many developers that come from an imperative language background like C are relying on boolean short-circuit to occur when SQL queries are executed. Often they take this expectation to extreme and the correctness of the result is actually relying on the short-circuit to occur:</p>
<p><code></p>
<pre>
<span style="color: Black"></span><span style="color:Blue">select</span><span style="color:Black">&nbsp;</span><span style="color:Red">'Will&nbsp;not&nbsp;divide&nbsp;by&nbsp;zero!'</span><span style="color:Black">&nbsp;</span><span style="color:Blue">where</span><span style="color:Black">&nbsp;1</span><span style="color:Gray">=</span><span style="color:Black">1&nbsp;</span><span style="color:Gray">or</span><span style="color:Black">&nbsp;1</span><span style="color:Gray">/</span><span style="color:Black">0</span><span style="color:Gray">=</span><span style="color:Black">0</span>
</pre>
<p></code></p>
<p>In the SQL snippet above the expression on the right side of the OR operator would cause a division by zero if ever evaluated. Yet the query executes fine and the successful result is seen as proof that operator short-circuit does happen! Well, is that all there is? Of course not. An <a href="http://en.wikipedia.org/wiki/Universal_quantification" target="_blank">universal quantification</a> cannot be demonstrated with an example. But it can be proven false with one single counter example!</p>
<p>Luckily I have two aces on my sleeve: for one I know how the Query Optimizer works. Second, I&#8217;ve stayed close enough to Microsoft CSS front lines for 6 months to see actual cases pouring in from developers bitten by the short-circuit assumption. Here is my counter-example case:</p>
<p><code></p>
<pre>
<span style="color: Black"></span><span style="color:Blue">create</span><span style="color:Black">&nbsp;</span><span style="color:Blue">table</span><span style="color:Black">&nbsp;eav&nbsp;</span><span style="color:Gray">(
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;eav_id&nbsp;</span><span style="color:Blue">int</span><span style="color:Black">&nbsp;</span><span style="color:Blue">identity</span><span style="color:Gray">(</span><span style="color:Black">1</span><span style="color:Gray">,</span><span style="color:Black">1</span><span style="color:Gray">)</span><span style="color:Black">&nbsp;</span><span style="color:Blue">primary</span><span style="color:Black">&nbsp;</span><span style="color:Blue">key</span><span style="color:Gray">,
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;attribute&nbsp;</span><span style="color:Blue">varchar</span><span style="color:Gray">(</span><span style="color:Black">50</span><span style="color:Gray">)</span><span style="color:Black">&nbsp;</span><span style="color:Gray">not</span><span style="color:Black">&nbsp;</span><span style="color:Gray">null,
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;is_numeric&nbsp;</span><span style="color:Blue">bit</span><span style="color:Black">&nbsp;</span><span style="color:Gray">not</span><span style="color:Black">&nbsp;</span><span style="color:Gray">null,
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;[value]&nbsp;</span><span style="color:Blue">sql_variant</span><span style="color:Black">&nbsp;</span><span style="color:Gray">null);
</span><span style="color:Blue">create</span><span style="color:Black">&nbsp;</span><span style="color:Blue">index</span><span style="color:Black">&nbsp;eav_attribute&nbsp;</span><span style="color:Blue">on</span><span style="color:Black">&nbsp;eav</span><span style="color:Gray">(</span><span style="color:Black">attribute</span><span style="color:Gray">)</span><span style="color:Black">&nbsp;</span><span style="color:Blue">include</span><span style="color:Black">&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">[value]</span><span style="color:Gray">);
</span><span style="color:Black">go

</span><span style="color:Green">--&nbsp;Fill&nbsp;the&nbsp;table&nbsp;with&nbsp;random&nbsp;values
</span><span style="color:Blue">set</span><span style="color:Black">&nbsp;</span><span style="color:Blue">nocount</span><span style="color:Black">&nbsp;</span><span style="color:Blue">on
declare</span><span style="color:Black">&nbsp;@i&nbsp;</span><span style="color:Blue">int</span><span style="color:Gray">;
</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;@i&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;0</span><span style="color:Gray">;
</span><span style="color:Blue">while</span><span style="color:Black">&nbsp;@i&nbsp;</span><span style="color:Gray">&lt;</span><span style="color:Black">&nbsp;100000
</span><span style="color:Blue">begin
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">declare</span><span style="color:Black">&nbsp;@attribute&nbsp;</span><span style="color:Blue">varchar</span><span style="color:Gray">(</span><span style="color:Black">50</span><span style="color:Gray">),
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@is_numeric&nbsp;</span><span style="color:Blue">bit</span><span style="color:Gray">,
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@value&nbsp;</span><span style="color:Blue">sql_variant</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;@attribute&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Red">'A'</span><span style="color:Black">&nbsp;</span><span style="color:Gray">+</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">cast</span><span style="color:Gray">(</span><span style="color:Fuchsia">cast</span><span style="color:Gray">(</span><span style="color:Fuchsia">rand</span><span style="color:Gray">()*</span><span style="color:Black">1000&nbsp;</span><span style="color:Blue">as</span><span style="color:Black">&nbsp;&nbsp;</span><span style="color:Blue">int</span><span style="color:Gray">)</span><span style="color:Black">&nbsp;</span><span style="color:Blue">as</span><span style="color:Black">&nbsp;</span><span style="color:Blue">varchar</span><span style="color:Gray">(</span><span style="color:Black">3</span><span style="color:Gray">));
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;@is_numeric&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Blue">case</span><span style="color:Black">&nbsp;</span><span style="color:Blue">when</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">rand</span><span style="color:Gray">()</span><span style="color:Black">&nbsp;</span><span style="color:Gray">&gt;</span><span style="color:Black">&nbsp;0.5&nbsp;</span><span style="color:Blue">then</span><span style="color:Black">&nbsp;1&nbsp;</span><span style="color:Blue">else</span><span style="color:Black">&nbsp;0&nbsp;</span><span style="color:Blue">end</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">if</span><span style="color:Black">&nbsp;1</span><span style="color:Gray">=</span><span style="color:Black">@is_numeric
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;@value&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">cast</span><span style="color:Gray">(</span><span style="color:Fuchsia">rand</span><span style="color:Gray">()</span><span style="color:Black">&nbsp;</span><span style="color:Gray">*</span><span style="color:Black">&nbsp;100&nbsp;</span><span style="color:Blue">as</span><span style="color:Black">&nbsp;</span><span style="color:Blue">int</span><span style="color:Gray">);
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">else
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;@value&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Red">'Lorem&nbsp;ipsum'</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">insert</span><span style="color:Black">&nbsp;</span><span style="color:Blue">into</span><span style="color:Black">&nbsp;eav&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">attribute</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;is_numeric</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;[value]</span><span style="color:Gray">)
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">values</span><span style="color:Black">&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">@attribute</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@is_numeric</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@value</span><span style="color:Gray">);
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;@i&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;@i</span><span style="color:Gray">+</span><span style="color:Black">1</span><span style="color:Gray">;
</span><span style="color:Blue">end
</span><span style="color:Black">go

</span><span style="color:Green">--&nbsp;insert&nbsp;a&nbsp;'trap'
</span><span style="color:Blue">insert</span><span style="color:Black">&nbsp;</span><span style="color:Blue">into</span><span style="color:Black">&nbsp;eav&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">attribute</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;is_numeric</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;[value]</span><span style="color:Gray">)
</span><span style="color:Blue">values</span><span style="color:Black">&nbsp;</span><span style="color:Gray">(</span><span style="color:Red">'B1'</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;0</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;</span><span style="color:Red">'Gotch&nbsp;ya'</span><span style="color:Gray">);
</span><span style="color:Black">GO

</span><span style="color:Green">--&nbsp;select&nbsp;the&nbsp;'trap'&nbsp;value
</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;[value]&nbsp;</span><span style="color:Blue">from</span><span style="color:Black">&nbsp;eav&nbsp;</span><span style="color:Blue">where</span><span style="color:Black">&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;attribute&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Red">'B1'</span><span style="color:Black">&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">and</span><span style="color:Black">&nbsp;is_numeric&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;1&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">and</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">cast</span><span style="color:Gray">(</span><span style="color:Black">[value]&nbsp;</span><span style="color:Blue">as</span><span style="color:Black">&nbsp;</span><span style="color:Blue">int</span><span style="color:Gray">)</span><span style="color:Black">&nbsp;</span><span style="color:Gray">&gt;</span><span style="color:Black">&nbsp;50
go</span>
</pre>
<p></code></p>
<pre>
<span style="color: Red">Msg&nbsp;245,&nbsp;Level&nbsp;16,&nbsp;State&nbsp;1,&nbsp;Line&nbsp;3
Conversion&nbsp;failed&nbsp;when&nbsp;converting&nbsp;the&nbsp;varchar&nbsp;value&nbsp;'Gotch&nbsp;ya'&nbsp;to&nbsp;data&nbsp;type&nbsp;int.</span>
</pre>
<p>This happens on SQL Server 2005 SP2. Clearly, the conversion <b>does</b> occur even though the value is marked as &#8216;not numeric&#8217;. Whats going on here? To better understand, lets insert a known value that can be converted and then run the same query again and look at the execution plan:</p>
<p><code></p>
<pre>
<span style="color: Black"></span><span style="color:Blue">insert</span><span style="color:Black">&nbsp;</span><span style="color:Blue">into</span><span style="color:Black">&nbsp;eav&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">attribute</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;is_numeric</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;[value]</span><span style="color:Gray">)
</span><span style="color:Blue">values</span><span style="color:Black">&nbsp;</span><span style="color:Gray">(</span><span style="color:Red">'B2'</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;1</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;65</span><span style="color:Gray">);
</span><span style="color:Black">go

</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;[value]&nbsp;</span><span style="color:Blue">from</span><span style="color:Black">&nbsp;eav&nbsp;</span><span style="color:Blue">where</span><span style="color:Black">&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;attribute&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Red">'B2'</span><span style="color:Black">&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">and</span><span style="color:Black">&nbsp;is_numeric&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;1&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">and</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">cast</span><span style="color:Gray">(</span><span style="color:Black">[value]&nbsp;</span><span style="color:Blue">as</span><span style="color:Black">&nbsp;</span><span style="color:Blue">int</span><span style="color:Gray">)</span><span style="color:Black">&nbsp;</span><span style="color:Gray">&gt;</span><span style="color:Black">&nbsp;50
go
</span>
</pre>
<p></code><br />
<div id="attachment_559" class="wp-caption alignnone" style="width: 510px"><a href="http://rusanu.com/wp-content/uploads/2009/09/short-circuit.png"><img src="http://rusanu.com/wp-content/uploads/2009/09/short-circuit.png" alt="boolean short-circuit counter example query plan" title="short-circuit" width="500" height="123" class="size-full wp-image-559" /></a><p class="wp-caption-text">boolean short-circuit counter example query plan</p></div></p>
<p>Looking at the plan we can see how the query is actually evaluated: seek on the non-clustered index for the attribute &#8216;B2&#8242;, project the &#8216;value&#8217;, filter for the value predicate &#8216;cast([value] as int)>50&#8242; <i>then</i> perform a nested join to look up the &#8216;is_boolean&#8217; in the clustered index! So <b>the right side of the AND operator is evaluated first</b>. Q.E.D.</p>
<p>Is this a bug? Of course not. SQL is a declarative language, the query optimizer is free to choose any execution path that provide the requested result. Boolean operator short-circuit is <b>NOT GUARANTEED</b>. My query has set up a trap for the query optimizer, by providing a tempting execution path using the non-clustered index. For my example to work I had to set up a large table and enough distinct values of &#8216;attribute&#8217; so that the optimizer would see the non-clustered index access followed by bookmark look up as a better plan than a clustered scan. And it is, by all means a better plan. But then I placed my trap: by adding the &#8216;value&#8217; as an included column in the non-clustered index, I give the optimizer a too sweet to resists opportunity to evaluate the filter predicate on the &#8216;value&#8217; column <i>before</i> it evaluates the filter predicate on the &#8216;is_numeric&#8217; column, thus forcing the break on the short-circuit assumption.</p>
]]></content:encoded>
			<wfw:commentRss>http://rusanu.com/2009/09/13/on-sql-server-boolean-operator-short-circuit/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Passing Parameters to a Background Procedure</title>
		<link>http://rusanu.com/2009/08/18/passing-parameters-to-a-background-procedure/</link>
		<comments>http://rusanu.com/2009/08/18/passing-parameters-to-a-background-procedure/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 18:21:47 +0000</pubDate>
		<dc:creator>remus</dc:creator>
		
		<category><![CDATA[Samples]]></category>

		<category><![CDATA[Tutorials]]></category>

		<category><![CDATA[activation]]></category>

		<category><![CDATA[asynchronous procedure]]></category>

		<category><![CDATA[background]]></category>

		<category><![CDATA[long running]]></category>

		<category><![CDATA[parameters]]></category>

		<category><![CDATA[sql server]]></category>

		<category><![CDATA[tsql]]></category>

		<guid isPermaLink="false">http://rusanu.com/?p=532</guid>
		<description><![CDATA[Copyright Remus Rusanu 2010. Visit the original article at http://rusanu.com/2009/08/18/passing-parameters-to-a-background-procedure/&#160;&#160;I have posted previously an example how to invoke a procedure asynchronously using service Broker activation. Several readers have inquired how to extend this mechanism to add parameters to the background launched procedure.
Passing parameters to a single well know procedure is easy: the parameters are be [...]]]></description>
			<content:encoded><![CDATA[<p>Copyright Remus Rusanu 2010. Visit the original article at <a href="http://rusanu.com/2009/08/18/passing-parameters-to-a-background-procedure/">http://rusanu.com/2009/08/18/passing-parameters-to-a-background-procedure/</a></p>&nbsp;&nbsp;<br><p>I have posted previously an example <a href="http://rusanu.com/2009/08/05/asynchronous-procedure-execution">how to invoke a procedure asynchronously</a> using service Broker activation. Several readers have inquired how to extend this mechanism to add parameters to the background launched procedure.</p>
<p>Passing parameters to a single well know procedure is easy: the parameters are be added to the message body and the activated procedure looks them up in the received XML, passing them to the called procedure. But is significantly more complex to create a generic mechanism that can pass parameters to any procedure. The problem is the type system, because the parameters have unknown types and the activated procedure has to pass proper typed parameters to the invoked procedure.</p>
<p>A generic solution should accept a variety of parameter types and should deal with the peculiarities of Transact-SQL parameters passing, namely the named parameters capabilities. Also the invocation wrapper <tt>usp_AsyncExecInvoke</tt>  should directly accept the parameters for the desired background procedure. After considering several alternatives, I settled on the following approach:</></p>
<ul>
<li>Rely on the generic <a href="http://msdn.microsoft.com/en-us/library/ms173829.aspx" target="_blank">sql_variant</a> data type available in SQL Server. The invocation wrapper <tt>usp_AsyncExecInvoke</tt> accept all the parameters as <tt>sql_variant</tt>.</li>
<li>Pass the background procedure parameter names explicitly to the invocation wrapper <tt>usp_AsyncExecInvoke</tt>.</li>
<li>Always used named parameters in the background procedure invocation.</li>
<li>Build a dynamic SQL batch to invoke the background procedure that deals with the required parameter type conversions.</li>
</ul>
<h2>Accepting Parameters</h2>
<p>The invocation wrapper <tt>usp_AsyncExecInvoke<tt> has changed the signature to accept a variable number of parameters:</p>
<pre>
<span style="color: Black"></span><span style="color:Blue">create procedure </span><span style="color:Black">[usp_AsyncExecInvoke]
    @procedureName </span><span style="color:Blue">sysname
    </span><span style="color:Gray">, </span><span style="color:Black">@p1 </span><span style="color:Blue">sql_variant </span><span style="color:Gray">= NULL, </span><span style="color:Black">@n1 </span><span style="color:Blue">sysname </span><span style="color:Gray">= NULL
    , </span><span style="color:Black">@p2 </span><span style="color:Blue">sql_variant </span><span style="color:Gray">= NULL, </span><span style="color:Black">@n2 </span><span style="color:Blue">sysname </span><span style="color:Gray">= NULL
    , </span><span style="color:Black">@p3 </span><span style="color:Blue">sql_variant </span><span style="color:Gray">= NULL, </span><span style="color:Black">@n3 </span><span style="color:Blue">sysname </span><span style="color:Gray">= NULL
    , </span><span style="color:Black">@p4 </span><span style="color:Blue">sql_variant </span><span style="color:Gray">= NULL, </span><span style="color:Black">@n4 </span><span style="color:Blue">sysname </span><span style="color:Gray">= NULL
    , </span><span style="color:Black">@p5 </span><span style="color:Blue">sql_variant </span><span style="color:Gray">= NULL, </span><span style="color:Black">@n5 </span><span style="color:Blue">sysname </span><span style="color:Gray">= NULL
    , </span><span style="color:Black">@token </span><span style="color:Blue">uniqueidentifier output</span>
</pre>
<p>The new parameters are used to collect the desired parameter values <i>and names</i> to be passed to the background procedure. So sonsider you would like to make the following traditional, synchronous, call:</p>
<pre>
<span style="color: Black"></span><span style="color:Blue">exec </span><span style="color:Black">usp_withParam @id </span><span style="color:Gray">= </span><span style="color:Black">1.0
	</span><span style="color:Gray">, </span><span style="color:Black">@name </span><span style="color:Gray">= </span><span style="color:Black">N</span><span style="color:Red">'Foo'
	</span><span style="color:Gray">, </span><span style="color:Black">@bytes </span><span style="color:Gray">= </span><span style="color:Black">0xBAADF00D</span><span style="color:Gray">;</span>
</pre>
<p>The equivalent asynchronous invocation would need to pass the parameter values (1.0, &#8216;Foo&#8217; and 0xbaadf00d) as @p1, @p2 and @p3 respectively and the parameter names (@id, @name and @bytes) as @n1, @n2 and @n3:
<pre>
<span style="color: Black"></span><span style="color:Blue">exec </span><span style="color:Black">usp_AsyncExecInvoke @procedureName </span><span style="color:Gray">= </span><span style="color:Black">N</span><span style="color:Red">'usp_withParam'
 </span><span style="color:Gray">, </span><span style="color:Black">@p1 </span><span style="color:Gray">= </span><span style="color:Black">1.0</span><span style="color:Gray">, </span><span style="color:Black">@n1 </span><span style="color:Gray">= </span><span style="color:Black">N</span><span style="color:Red">'@id'
 </span><span style="color:Gray">, </span><span style="color:Black">@p2 </span><span style="color:Gray">= </span><span style="color:Black">N</span><span style="color:Red">'Foo'</span><span style="color:Gray">, </span><span style="color:Black">@n2</span><span style="color:Gray">=</span><span style="color:Red">'@name'
 </span><span style="color:Gray">, </span><span style="color:Black">@p3 </span><span style="color:Gray">= </span><span style="color:Black">0xBAADF00D</span><span style="color:Gray">, </span><span style="color:Black">@n3 </span><span style="color:Gray">= </span><span style="color:Red">'@bytes'
 </span><span style="color:Gray">, </span><span style="color:Black">@token </span><span style="color:Gray">= </span><span style="color:Black">@token </span><span style="color:Blue">output</span><span style="color:Gray">;</span>
</pre>
<p>The invocation wrapper will pack the parameter names, values and type information into the message body. The parameter type information is deduced at run time from the actual parameters, by using the <a href="http://msdn.microsoft.com/en-us/library/ms178550.aspx" target="_blank">SQL_VARIANT_PROPERTY</a> system function. This is the XML message body corresponding to the invocation above (note how the varbinary parameter was encoded using base64 encoding):</p>
<pre>
<span style="color: Black"></span><span style="color:Blue">&lt;</span><span style="color:Maroon">procedure</span><span style="color:Blue">&gt;
  &lt;</span><span style="color:Maroon">name</span><span style="color:Blue">&gt;</span><span style="color:Black">usp_withParam</span><span style="color:Blue">&lt;/</span><span style="color:Maroon">name</span><span style="color:Blue">&gt;
  &lt;</span><span style="color:Maroon">parameters</span><span style="color:Blue">&gt;
    &lt;</span><span style="color:Maroon">parameter </span><span style="color:Red">Name</span><span style="color:Blue">=</span><span style="color:Black">"</span><span style="color:Blue">@id</span><span style="color:Black">" </span><span style="color:Red">BaseType</span><span style="color:Blue">=</span><span style="color:Black">"</span><span style="color:Blue">numeric</span><span style="color:Black">" </span><span style="color:Red">Precision</span><span style="color:Blue">=</span><span style="color:Black">"</span><span style="color:Blue">2</span><span style="color:Black">" </span><span style="color:Red">Scale</span><span style="color:Blue">=</span><span style="color:Black">"</span><span style="color:Blue">1</span><span style="color:Black">" </span><span style="color:Red">MaxLength</span><span style="color:Blue">=</span><span style="color:Black">"</span><span style="color:Blue">5</span><span style="color:Black">"</span><span style="color:Blue">&gt;</span><span style="color:Black">1.0</span><span style="color:Blue">&lt;/</span><span style="color:Maroon">parameter</span><span style="color:Blue">&gt;
    &lt;</span><span style="color:Maroon">parameter </span><span style="color:Red">Name</span><span style="color:Blue">=</span><span style="color:Black">"</span><span style="color:Blue">@name</span><span style="color:Black">" </span><span style="color:Red">BaseType</span><span style="color:Blue">=</span><span style="color:Black">"</span><span style="color:Blue">nvarchar</span><span style="color:Black">" </span><span style="color:Red">Precision</span><span style="color:Blue">=</span><span style="color:Black">"</span><span style="color:Blue">0</span><span style="color:Black">" </span><span style="color:Red">Scale</span><span style="color:Blue">=</span><span style="color:Black">"</span><span style="color:Blue">0</span><span style="color:Black">" </span><span style="color:Red">MaxLength</span><span style="color:Blue">=</span><span style="color:Black">"</span><span style="color:Blue">6</span><span style="color:Black">"</span><span style="color:Blue">&gt;</span><span style="color:Black">Foo</span><span style="color:Blue">&lt;/</span><span style="color:Maroon">parameter</span><span style="color:Blue">&gt;
    &lt;</span><span style="color:Maroon">parameter </span><span style="color:Red">Name</span><span style="color:Blue">=</span><span style="color:Black">"</span><span style="color:Blue">@bytes</span><span style="color:Black">" </span><span style="color:Red">BaseType</span><span style="color:Blue">=</span><span style="color:Black">"</span><span style="color:Blue">varbinary</span><span style="color:Black">" </span>
          <span style="color:Red">Precision</span><span style="color:Blue">=</span><span style="color:Black">"</span><span style="color:Blue">0</span><span style="color:Black">" </span><span style="color:Red">Scale</span><span style="color:Blue">=</span><span style="color:Black">"</span><span style="color:Blue">0</span><span style="color:Black">" </span><span style="color:Red">MaxLength</span><span style="color:Blue">=</span><span style="color:Black">"</span><span style="color:Blue">4</span><span style="color:Black">"</span><span style="color:Blue">&gt;</span><span style="color:Black">uq3wDQ==</span><span style="color:Blue">&lt;/</span><span style="color:Maroon">parameter</span><span style="color:Blue">&gt;
  &lt;/</span><span style="color:Maroon">parameters</span><span style="color:Blue">&gt;
&lt;/</span><span style="color:Maroon">procedure</span><span style="color:Blue">&gt;</span>
</pre>
<h2>Extracting the Parameters</h2>
<p>The activated procedure job is now significantly more complex because of the task of extracting the parameter names, types and value and constructing a proper Transact-SQL statement to invoke the original procedure. A new helper procedure was added, <tt>usp_procedureInvokeHelper</tt>, that constructs a dynamic SQL batch from a invokation message body. Here is the dynamic SQL that results from our sample invocation:</p>
<pre>
<span style="color: Black"></span><span style="color:Blue">declare </span><span style="color:Black">@pt1 </span><span style="color:Blue">numeric</span><span style="color:Gray">(</span><span style="color:Black">2</span><span style="color:Gray">,</span><span style="color:Black">1</span><span style="color:Gray">)
</span><span style="color:Blue">declare </span><span style="color:Black">@pt2 </span><span style="color:Blue">nvarchar</span><span style="color:Gray">(</span><span style="color:Black">6</span><span style="color:Gray">)
</span><span style="color:Blue">declare </span><span style="color:Black">@pt3 </span><span style="color:Blue">varbinary</span><span style="color:Gray">(</span><span style="color:Black">4</span><span style="color:Gray">)
</span><span style="color:Blue">select </span><span style="color:Black">@pt1</span><span style="color:Gray">=</span><span style="color:Black">@x</span><span style="color:Gray">.</span><span style="color:Black">value</span><span style="color:Gray">(</span><span style="color:Red">N'(//procedure/parameters/parameter)[1]'</span><span style="color:Gray">, </span><span style="color:Red">N'numeric(2,1)'</span><span style="color:Gray">);
</span><span style="color:Blue">select </span><span style="color:Black">@pt2</span><span style="color:Gray">=</span><span style="color:Black">@x</span><span style="color:Gray">.</span><span style="color:Black">value</span><span style="color:Gray">(</span><span style="color:Red">N'(//procedure/parameters/parameter)[2]'</span><span style="color:Gray">, </span><span style="color:Red">N'nvarchar(6)'</span><span style="color:Gray">);
</span><span style="color:Blue">select </span><span style="color:Black">@pt3</span><span style="color:Gray">=</span><span style="color:Black">@x</span><span style="color:Gray">.</span><span style="color:Black">value</span><span style="color:Gray">(</span><span style="color:Red">N'(//procedure/parameters/parameter)[3]'</span><span style="color:Gray">, </span><span style="color:Red">N'varbinary(4)'</span><span style="color:Gray">);
</span><span style="color:Blue">exec </span><span style="color:Black">[usp_withParam]  @id</span><span style="color:Gray">=</span><span style="color:Black">@pt1</span><span style="color:Gray">,</span><span style="color:Black">@name</span><span style="color:Gray">=</span><span style="color:Black">@pt2</span><span style="color:Gray">,</span><span style="color:Black">@bytes</span><span style="color:Gray">=</span><span style="color:Black">@pt3
</span>
</pre>
<h2>Limitations</h2>
<p>Because the invocation wrapper uses sql_variant typed parameters, all sql_variant restrictions apply to this sample. Most notably the wrapper will not accept XML type parameters nor large data types like varchar(max) or varbinary(max). It is possible to work around these limitations but it would complicate my sample beyond the point of being usefull as an example how to pass the parameters.</p>
<p>Because the error handling of the activated procedure will rollback in case of error, passing in a message that results in a procedure invocation error will cause the activation to rollback repeatedly and the poison message detection mechanism will kick in, deactivating the queue. A trivial example is if we omit the required @id parameter for our sample invocation.</p>
<h2>The code</h2>
<pre>
<span style="color: Black"></span><span style="color:Blue">create table </span><span style="color:Black">[AsyncExecResults] </span><span style="color:Gray">(
 </span><span style="color:Black">[token] </span><span style="color:Blue">uniqueidentifier primary key
 </span><span style="color:Gray">, </span><span style="color:Black">[submit_time] </span><span style="color:Blue">datetime </span><span style="color:Gray">not null
 , </span><span style="color:Black">[start_time] </span><span style="color:Blue">datetime </span><span style="color:Gray">null
 , </span><span style="color:Black">[finish_time] </span><span style="color:Blue">datetime </span><span style="color:Gray">null
 , </span><span style="color:Black">[error_number] </span><span style="color:Blue">int </span><span style="color:Gray">null
 , </span><span style="color:Black">[error_message] </span><span style="color:Blue">nvarchar</span><span style="color:Gray">(</span><span style="color:Black">2048</span><span style="color:Gray">) null);
</span><span style="color:Blue">go

create queue </span><span style="color:Black">[AsyncExecQueue]</span><span style="color:Gray">;
</span><span style="color:Blue">go

create service </span><span style="color:Black">[AsyncExecService] </span><span style="color:Blue">on queue </span><span style="color:Black">[AsyncExecQueue] </span><span style="color:Gray">(</span><span style="color:Black">[DEFAULT]</span><span style="color:Gray">);
</span><span style="color:Blue">GO

</span><span style="color:Green">-- Dynamic SQL helper procedure
-- Extracts the parameters from the message body
-- Creates the invocation Transact-SQL batch
-- Invokes the dynmic SQL batch
</span><span style="color:Blue">create procedure </span><span style="color:Black">[usp_procedureInvokeHelper] </span><span style="color:Gray">(</span><span style="color:Black">@x </span><span style="color:Blue">xml</span><span style="color:Gray">)
</span><span style="color:Blue">as
begin
    set nocount on</span><span style="color:Gray">;

    </span><span style="color:Blue">declare </span><span style="color:Black">@stmt </span><span style="color:Blue">nvarchar</span><span style="color:Gray">(</span><span style="color:Fuchsia">max</span><span style="color:Gray">)
        , </span><span style="color:Black">@stmtDeclarations </span><span style="color:Blue">nvarchar</span><span style="color:Gray">(</span><span style="color:Fuchsia">max</span><span style="color:Gray">)
        , </span><span style="color:Black">@stmtValues </span><span style="color:Blue">nvarchar</span><span style="color:Gray">(</span><span style="color:Fuchsia">max</span><span style="color:Gray">)
        , </span><span style="color:Black">@i </span><span style="color:Blue">int
        </span><span style="color:Gray">, </span><span style="color:Black">@countParams </span><span style="color:Blue">int
        </span><span style="color:Gray">, </span><span style="color:Black">@namedParams </span><span style="color:Blue">nvarchar</span><span style="color:Gray">(</span><span style="color:Fuchsia">max</span><span style="color:Gray">)
        , </span><span style="color:Black">@paramName </span><span style="color:Blue">sysname
        </span><span style="color:Gray">, </span><span style="color:Black">@paramType </span><span style="color:Blue">sysname
        </span><span style="color:Gray">, </span><span style="color:Black">@paramPrecision </span><span style="color:Blue">int
        </span><span style="color:Gray">, </span><span style="color:Black">@paramScale </span><span style="color:Blue">int
        </span><span style="color:Gray">, </span><span style="color:Black">@paramLength </span><span style="color:Blue">int
        </span><span style="color:Gray">, </span><span style="color:Black">@paramTypeFull </span><span style="color:Blue">nvarchar</span><span style="color:Gray">(</span><span style="color:Black">300</span><span style="color:Gray">)
        , </span><span style="color:Black">@comma </span><span style="color:Blue">nchar</span><span style="color:Gray">(</span><span style="color:Black">1</span><span style="color:Gray">)

    </span><span style="color:Blue">select </span><span style="color:Black">@i </span><span style="color:Gray">= </span><span style="color:Black">0
        </span><span style="color:Gray">, </span><span style="color:Black">@stmtDeclarations </span><span style="color:Gray">= </span><span style="color:Red">N''
        </span><span style="color:Gray">, </span><span style="color:Black">@stmtValues </span><span style="color:Gray">= </span><span style="color:Red">N''
        </span><span style="color:Gray">, </span><span style="color:Black">@namedParams </span><span style="color:Gray">= </span><span style="color:Red">N''
        </span><span style="color:Gray">, </span><span style="color:Black">@comma </span><span style="color:Gray">= </span><span style="color:Red">N''

    </span><span style="color:Blue">declare </span><span style="color:Black">crsParam </span><span style="color:Blue">cursor forward_only static read_only for
        select </span><span style="color:Black">x</span><span style="color:Gray">.</span><span style="color:Black">value</span><span style="color:Gray">(</span><span style="color:Red">N'@Name'</span><span style="color:Gray">, </span><span style="color:Red">N'sysname'</span><span style="color:Gray">)
            , </span><span style="color:Black">x</span><span style="color:Gray">.</span><span style="color:Black">value</span><span style="color:Gray">(</span><span style="color:Red">N'@BaseType'</span><span style="color:Gray">, </span><span style="color:Red">N'sysname'</span><span style="color:Gray">)
            , </span><span style="color:Black">x</span><span style="color:Gray">.</span><span style="color:Black">value</span><span style="color:Gray">(</span><span style="color:Red">N'@Precision'</span><span style="color:Gray">, </span><span style="color:Red">N'int'</span><span style="color:Gray">)
            , </span><span style="color:Black">x</span><span style="color:Gray">.</span><span style="color:Black">value</span><span style="color:Gray">(</span><span style="color:Red">N'@Scale'</span><span style="color:Gray">, </span><span style="color:Red">N'int'</span><span style="color:Gray">)
            , </span><span style="color:Black">x</span><span style="color:Gray">.</span><span style="color:Black">value</span><span style="color:Gray">(</span><span style="color:Red">N'@MaxLength'</span><span style="color:Gray">, </span><span style="color:Red">N'int'</span><span style="color:Gray">)
        </span><span style="color:Blue">from </span><span style="color:Black">@x</span><span style="color:Gray">.</span><span style="color:Black">nodes</span><span style="color:Gray">(</span><span style="color:Red">N'//procedure/parameters/parameter'</span><span style="color:Gray">) </span><span style="color:Black">t</span><span style="color:Gray">(</span><span style="color:Black">x</span><span style="color:Gray">);
    </span><span style="color:Blue">open </span><span style="color:Black">crsParam</span><span style="color:Gray">;

    </span><span style="color:Blue">fetch next from </span><span style="color:Black">crsParam </span><span style="color:Blue">into </span><span style="color:Black">@paramName
        </span><span style="color:Gray">, </span><span style="color:Black">@paramType
        </span><span style="color:Gray">, </span><span style="color:Black">@paramPrecision
        </span><span style="color:Gray">, </span><span style="color:Black">@paramScale
        </span><span style="color:Gray">, </span><span style="color:Black">@paramLength</span><span style="color:Gray">;
    </span><span style="color:Blue">while </span><span style="color:Gray">(</span><span style="color:Fuchsia">@@fetch_status </span><span style="color:Gray">= </span><span style="color:Black">0</span><span style="color:Gray">)
    </span><span style="color:Blue">begin
        select </span><span style="color:Black">@i </span><span style="color:Gray">= </span><span style="color:Black">@i </span><span style="color:Gray">+ </span><span style="color:Black">1</span><span style="color:Gray">;

        </span><span style="color:Blue">select </span><span style="color:Black">@paramTypeFull </span><span style="color:Gray">= </span><span style="color:Black">@paramType </span><span style="color:Gray">+
            </span><span style="color:Blue">case
            when </span><span style="color:Black">@paramType </span><span style="color:Gray">in (</span><span style="color:Red">N'varchar'
                </span><span style="color:Gray">, </span><span style="color:Red">N'nvarchar'
                </span><span style="color:Gray">, </span><span style="color:Red">N'varbinary'
                </span><span style="color:Gray">, </span><span style="color:Red">N'char'
                </span><span style="color:Gray">, </span><span style="color:Red">N'nchar'
                </span><span style="color:Gray">, </span><span style="color:Red">N'binary'</span><span style="color:Gray">) </span><span style="color:Blue">then
                </span><span style="color:Red">N'(' </span><span style="color:Gray">+ </span><span style="color:Fuchsia">cast</span><span style="color:Gray">(</span><span style="color:Black">@paramLength </span><span style="color:Blue">as nvarchar</span><span style="color:Gray">(</span><span style="color:Black">5</span><span style="color:Gray">)) + </span><span style="color:Red">N')'
            </span><span style="color:Blue">when </span><span style="color:Black">@paramType </span><span style="color:Gray">in (</span><span style="color:Red">N'numeric'</span><span style="color:Gray">) </span><span style="color:Blue">then
                </span><span style="color:Red">N'(' </span><span style="color:Gray">+ </span><span style="color:Fuchsia">cast</span><span style="color:Gray">(</span><span style="color:Black">@paramPrecision </span><span style="color:Blue">as nvarchar</span><span style="color:Gray">(</span><span style="color:Black">10</span><span style="color:Gray">)) + </span><span style="color:Red">N',' </span><span style="color:Gray">+
                </span><span style="color:Fuchsia">cast</span><span style="color:Gray">(</span><span style="color:Black">@paramScale </span><span style="color:Blue">as nvarchar</span><span style="color:Gray">(</span><span style="color:Black">10</span><span style="color:Gray">))+ </span><span style="color:Red">N')'
            </span><span style="color:Blue">else </span><span style="color:Red">N''
            </span><span style="color:Blue">end</span><span style="color:Gray">;

        </span><span style="color:Green">-- Some basic sanity check on the input XML
        </span><span style="color:Blue">if </span><span style="color:Gray">(</span><span style="color:Black">@paramName </span><span style="color:Gray">is NULL
            or </span><span style="color:Black">@paramType </span><span style="color:Gray">is NULL
            or </span><span style="color:Black">@paramTypeFull </span><span style="color:Gray">is NULL
            or </span><span style="color:Fuchsia">charindex</span><span style="color:Gray">(</span><span style="color:Red">N''''</span><span style="color:Gray">, </span><span style="color:Black">@paramName</span><span style="color:Gray">) &gt; </span><span style="color:Black">0
            </span><span style="color:Gray">or </span><span style="color:Fuchsia">charindex</span><span style="color:Gray">(</span><span style="color:Red">N''''</span><span style="color:Gray">, </span><span style="color:Black">@paramTypeFull</span><span style="color:Gray">) &gt; </span><span style="color:Black">0</span><span style="color:Gray">)
            </span><span style="color:Blue">raiserror</span><span style="color:Gray">(</span><span style="color:Red">N'Incorrect parameter attributes %i: %s:%s %i:%i:%i'
                </span><span style="color:Gray">, </span><span style="color:Black">16</span><span style="color:Gray">, </span><span style="color:Black">10</span><span style="color:Gray">, </span><span style="color:Black">@i</span><span style="color:Gray">, </span><span style="color:Black">@paramName</span><span style="color:Gray">, </span><span style="color:Black">@paramType
                </span><span style="color:Gray">, </span><span style="color:Black">@paramPrecision</span><span style="color:Gray">, </span><span style="color:Black">@paramScale</span><span style="color:Gray">, </span><span style="color:Black">@paramLength</span><span style="color:Gray">);

        </span><span style="color:Blue">select </span><span style="color:Black">@stmtDeclarations </span><span style="color:Gray">= </span><span style="color:Black">@stmtDeclarations </span><span style="color:Gray">+ </span><span style="color:Red">N'
declare @pt' </span><span style="color:Gray">+ </span><span style="color:Fuchsia">cast</span><span style="color:Gray">(</span><span style="color:Black">@i </span><span style="color:Blue">as varchar</span><span style="color:Gray">(</span><span style="color:Black">3</span><span style="color:Gray">)) + </span><span style="color:Red">N' ' </span><span style="color:Gray">+ </span><span style="color:Black">@paramTypeFull
            </span><span style="color:Gray">, </span><span style="color:Black">@stmtValues </span><span style="color:Gray">= </span><span style="color:Black">@stmtValues </span><span style="color:Gray">+ </span><span style="color:Red">N'
select @pt' </span><span style="color:Gray">+ </span><span style="color:Fuchsia">cast</span><span style="color:Gray">(</span><span style="color:Black">@i </span><span style="color:Blue">as varchar</span><span style="color:Gray">(</span><span style="color:Black">3</span><span style="color:Gray">)) + </span><span style="color:Red">N'=@x.value(
    N''(//procedure/parameters/parameter)[' </span><span style="color:Gray">+ </span><span style="color:Fuchsia">cast</span><span style="color:Gray">(</span><span style="color:Black">@i </span><span style="color:Blue">as varchar</span><span style="color:Gray">(</span><span style="color:Black">3</span><span style="color:Gray">)) 
                + </span><span style="color:Red">N']'', N''' </span><span style="color:Gray">+ </span><span style="color:Black">@paramTypeFull </span><span style="color:Gray">+ </span><span style="color:Red">''');'
            </span><span style="color:Gray">, </span><span style="color:Black">@namedParams </span><span style="color:Gray">= </span><span style="color:Black">@namedParams </span><span style="color:Gray">+ </span><span style="color:Black">@comma </span><span style="color:Gray">+ </span><span style="color:Black">@paramName
                </span><span style="color:Gray">+ </span><span style="color:Red">N'=@pt' </span><span style="color:Gray">+ </span><span style="color:Fuchsia">cast</span><span style="color:Gray">(</span><span style="color:Black">@i </span><span style="color:Blue">as varchar</span><span style="color:Gray">(</span><span style="color:Black">3</span><span style="color:Gray">));

        </span><span style="color:Blue">select </span><span style="color:Black">@comma </span><span style="color:Gray">= </span><span style="color:Red">N','</span><span style="color:Gray">;

        </span><span style="color:Blue">fetch next from </span><span style="color:Black">crsParam </span><span style="color:Blue">into </span><span style="color:Black">@paramName
            </span><span style="color:Gray">, </span><span style="color:Black">@paramType
            </span><span style="color:Gray">, </span><span style="color:Black">@paramPrecision
            </span><span style="color:Gray">, </span><span style="color:Black">@paramScale
            </span><span style="color:Gray">, </span><span style="color:Black">@paramLength</span><span style="color:Gray">;
    </span><span style="color:Blue">end

    close </span><span style="color:Black">crsParam</span><span style="color:Gray">;
    </span><span style="color:Blue">deallocate </span><span style="color:Black">crsParam</span><span style="color:Gray">;        

    </span><span style="color:Blue">select </span><span style="color:Black">@stmt </span><span style="color:Gray">= </span><span style="color:Black">@stmtDeclarations </span><span style="color:Gray">+ </span><span style="color:Black">@stmtValues </span><span style="color:Gray">+ </span><span style="color:Red">N'
exec ' </span><span style="color:Gray">+ </span><span style="color:Fuchsia">quotename</span><span style="color:Gray">(</span><span style="color:Black">@x</span><span style="color:Gray">.</span><span style="color:Black">value</span><span style="color:Gray">(</span><span style="color:Red">N'(//procedure/name)[1]'</span><span style="color:Gray">, </span><span style="color:Red">N'sysname'</span><span style="color:Gray">));

    </span><span style="color:Blue">if </span><span style="color:Gray">(</span><span style="color:Black">@namedParams </span><span style="color:Gray">!= </span><span style="color:Red">N''</span><span style="color:Gray">)
        </span><span style="color:Blue">select </span><span style="color:Black">@stmt </span><span style="color:Gray">= </span><span style="color:Black">@stmt </span><span style="color:Gray">+ </span><span style="color:Red">N' ' </span><span style="color:Gray">+ </span><span style="color:Black">@namedParams</span><span style="color:Gray">;

    </span><span style="color:Blue">exec </span><span style="color:Maroon">sp_executesql </span><span style="color:Black">@stmt</span><span style="color:Gray">, </span><span style="color:Red">N'@x xml'</span><span style="color:Gray">, </span><span style="color:Black">@x</span><span style="color:Gray">;
</span><span style="color:Blue">end
go

create procedure </span><span style="color:Black">usp_AsyncExecActivated
</span><span style="color:Blue">as
begin
    set nocount on</span><span style="color:Gray">;
    </span><span style="color:Blue">declare </span><span style="color:Black">@h </span><span style="color:Blue">uniqueidentifier
        </span><span style="color:Gray">, </span><span style="color:Black">@messageTypeName </span><span style="color:Blue">sysname
        </span><span style="color:Gray">, </span><span style="color:Black">@messageBody </span><span style="color:Blue">varbinary</span><span style="color:Gray">(</span><span style="color:Fuchsia">max</span><span style="color:Gray">)
        , </span><span style="color:Black">@xmlBody </span><span style="color:Blue">xml
        </span><span style="color:Gray">, </span><span style="color:Black">@startTime </span><span style="color:Blue">datetime
        </span><span style="color:Gray">, </span><span style="color:Black">@finishTime </span><span style="color:Blue">datetime
        </span><span style="color:Gray">, </span><span style="color:Black">@execErrorNumber </span><span style="color:Blue">int
        </span><span style="color:Gray">, </span><span style="color:Black">@execErrorMessage </span><span style="color:Blue">nvarchar</span><span style="color:Gray">(</span><span style="color:Black">2048</span><span style="color:Gray">)
        , </span><span style="color:Black">@xactState </span><span style="color:Blue">smallint
        </span><span style="color:Gray">, </span><span style="color:Black">@token </span><span style="color:Blue">uniqueidentifier</span><span style="color:Gray">;

    </span><span style="color:Blue">begin transaction</span><span style="color:Gray">;
    </span><span style="color:Blue">begin try</span><span style="color:Gray">;
        </span><span style="color:Blue">receive top</span><span style="color:Gray">(</span><span style="color:Black">1</span><span style="color:Gray">)
            </span><span style="color:Black">@h </span><span style="color:Gray">= </span><span style="color:Black">[conversation_handle]
            </span><span style="color:Gray">, </span><span style="color:Black">@messageTypeName </span><span style="color:Gray">= </span><span style="color:Black">[message_type_name]
            </span><span style="color:Gray">, </span><span style="color:Black">@messageBody </span><span style="color:Gray">= </span><span style="color:Black">[message_body]
            </span><span style="color:Blue">from </span><span style="color:Black">[AsyncExecQueue]</span><span style="color:Gray">;
        </span><span style="color:Blue">if </span><span style="color:Gray">(</span><span style="color:Black">@h </span><span style="color:Gray">is not null)
        </span><span style="color:Blue">begin
            if </span><span style="color:Gray">(</span><span style="color:Black">@messageTypeName </span><span style="color:Gray">= </span><span style="color:Red">N'DEFAULT'</span><span style="color:Gray">)
            </span><span style="color:Blue">begin
                </span><span style="color:Green">-- The DEFAULT message type is a procedure invocation.
                --
                </span><span style="color:Blue">select </span><span style="color:Black">@xmlBody </span><span style="color:Gray">= </span><span style="color:Fuchsia">CAST</span><span style="color:Gray">(</span><span style="color:Black">@messageBody </span><span style="color:Blue">as xml</span><span style="color:Gray">);

                </span><span style="color:Blue">save transaction </span><span style="color:Black">usp_AsyncExec_procedure</span><span style="color:Gray">;
                </span><span style="color:Blue">select </span><span style="color:Black">@startTime </span><span style="color:Gray">= </span><span style="color:Fuchsia">GETUTCDATE</span><span style="color:Gray">();
                </span><span style="color:Blue">begin try
                    exec </span><span style="color:Black">[usp_procedureInvokeHelper] @xmlBody</span><span style="color:Gray">;
                </span><span style="color:Blue">end try
                begin catch
                </span><span style="color:Green">-- This catch block tries to deal with failures of the procedure execution
                -- If possible it rolls back to the savepoint created earlier, allowing
                -- the activated procedure to continue. If the executed procedure
                -- raises an error with severity 16 or higher, it will doom the transaction
                -- and thus rollback the RECEIVE. Such case will be a poison message,
                -- resulting in the queue disabling.
                --
                </span><span style="color:Blue">select </span><span style="color:Black">@execErrorNumber </span><span style="color:Gray">= </span><span style="color:Fuchsia">ERROR_NUMBER</span><span style="color:Gray">(),
                    </span><span style="color:Black">@execErrorMessage </span><span style="color:Gray">= </span><span style="color:Fuchsia">ERROR_MESSAGE</span><span style="color:Gray">(),
                    </span><span style="color:Black">@xactState </span><span style="color:Gray">= </span><span style="color:Fuchsia">XACT_STATE</span><span style="color:Gray">();
                </span><span style="color:Blue">if </span><span style="color:Gray">(</span><span style="color:Black">@xactState </span><span style="color:Gray">= -</span><span style="color:Black">1</span><span style="color:Gray">)
                </span><span style="color:Blue">begin
                    rollback</span><span style="color:Gray">;
                    </span><span style="color:Blue">raiserror</span><span style="color:Gray">(</span><span style="color:Red">N'Unrecoverable error in procedure: %i: %s'</span><span style="color:Gray">, </span><span style="color:Black">16</span><span style="color:Gray">, </span><span style="color:Black">10</span><span style="color:Gray">,
                        </span><span style="color:Black">@execErrorNumber</span><span style="color:Gray">, </span><span style="color:Black">@execErrorMessage</span><span style="color:Gray">);
                </span><span style="color:Blue">end
                else if </span><span style="color:Gray">(</span><span style="color:Black">@xactState </span><span style="color:Gray">= </span><span style="color:Black">1</span><span style="color:Gray">)
                </span><span style="color:Blue">begin
                    rollback transaction </span><span style="color:Black">usp_AsyncExec_procedure</span><span style="color:Gray">;
                </span><span style="color:Blue">end
                end catch

                select </span><span style="color:Black">@finishTime </span><span style="color:Gray">= </span><span style="color:Fuchsia">GETUTCDATE</span><span style="color:Gray">();
                </span><span style="color:Blue">select </span><span style="color:Black">@token </span><span style="color:Gray">= </span><span style="color:Black">[conversation_id]
                    </span><span style="color:Blue">from </span><span style="color:Green">sys</span><span style="color:Gray">.</span><span style="color:Green">conversation_endpoints
                    </span><span style="color:Blue">where </span><span style="color:Black">[conversation_handle] </span><span style="color:Gray">= </span><span style="color:Black">@h</span><span style="color:Gray">;
                </span><span style="color:Blue">if </span><span style="color:Gray">(</span><span style="color:Black">@token </span><span style="color:Gray">is null)
                </span><span style="color:Blue">begin
                    raiserror</span><span style="color:Gray">(</span><span style="color:Red">N'Internal consistency error: conversation not found'</span><span style="color:Gray">, </span><span style="color:Black">16</span><span style="color:Gray">, </span><span style="color:Black">20</span><span style="color:Gray">);
                </span><span style="color:Blue">end
                update </span><span style="color:Black">[AsyncExecResults] </span><span style="color:Blue">set
                    </span><span style="color:Black">[start_time] </span><span style="color:Gray">= </span><span style="color:Black">@starttime
                    </span><span style="color:Gray">, </span><span style="color:Black">[finish_time] </span><span style="color:Gray">= </span><span style="color:Black">@finishTime
                    </span><span style="color:Gray">, </span><span style="color:Black">[error_number] </span><span style="color:Gray">= </span><span style="color:Black">@execErrorNumber
                    </span><span style="color:Gray">, </span><span style="color:Black">[error_message] </span><span style="color:Gray">= </span><span style="color:Black">@execErrorMessage
                    </span><span style="color:Blue">where </span><span style="color:Black">[token] </span><span style="color:Gray">= </span><span style="color:Black">@token</span><span style="color:Gray">;
                </span><span style="color:Blue">if </span><span style="color:Gray">(</span><span style="color:Black">0 </span><span style="color:Gray">= </span><span style="color:Fuchsia">@@ROWCOUNT</span><span style="color:Gray">)
                </span><span style="color:Blue">begin
                    raiserror</span><span style="color:Gray">(</span><span style="color:Red">N'Internal consistency error: token not found'</span><span style="color:Gray">, </span><span style="color:Black">16</span><span style="color:Gray">, </span><span style="color:Black">30</span><span style="color:Gray">);
                </span><span style="color:Blue">end
                end conversation </span><span style="color:Black">@h</span><span style="color:Gray">;
            </span><span style="color:Blue">end
            else if </span><span style="color:Gray">(</span><span style="color:Black">@messageTypeName </span><span style="color:Gray">= </span><span style="color:Red">N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'</span><span style="color:Gray">)
            </span><span style="color:Blue">begin
                end conversation </span><span style="color:Black">@h</span><span style="color:Gray">;
            </span><span style="color:Blue">end
            else if </span><span style="color:Gray">(</span><span style="color:Black">@messageTypeName </span><span style="color:Gray">= </span><span style="color:Red">N'http://schemas.microsoft.com/SQL/ServiceBroker/Error'</span><span style="color:Gray">)
            </span><span style="color:Blue">begin
                declare </span><span style="color:Black">@errorNumber </span><span style="color:Blue">int
                    </span><span style="color:Gray">, </span><span style="color:Black">@errorMessage </span><span style="color:Blue">nvarchar</span><span style="color:Gray">(</span><span style="color:Black">4000</span><span style="color:Gray">);
                </span><span style="color:Blue">with </span><span style="color:Black">xmlnamespaces </span><span style="color:Gray">(</span><span style="color:Blue">DEFAULT </span><span style="color:Red">N'http://schemas.microsoft.com/SQL/ServiceBroker/Error'</span><span style="color:Gray">)
                </span><span style="color:Blue">select </span><span style="color:Black">@errorNumber </span><span style="color:Gray">= </span><span style="color:Black">@xmlBody</span><span style="color:Gray">.</span><span style="color:Black">value</span><span style="color:Gray">(</span><span style="color:Red">'(/Error/Code)[1]'</span><span style="color:Gray">, </span><span style="color:Red">'INT'</span><span style="color:Gray">),
                    </span><span style="color:Black">@errorMessage </span><span style="color:Gray">= </span><span style="color:Black">@xmlBody</span><span style="color:Gray">.</span><span style="color:Black">value</span><span style="color:Gray">(</span><span style="color:Red">'(/Error/Description)[1]'</span><span style="color:Gray">, </span><span style="color:Red">'NVARCHAR(4000)'</span><span style="color:Gray">);
                </span><span style="color:Blue">raiserror</span><span style="color:Gray">(</span><span style="color:Red">N'A conversation error was encountered: %i: %s'</span><span style="color:Gray">, </span><span style="color:Black">1</span><span style="color:Gray">, </span><span style="color:Black">40</span><span style="color:Gray">,
                    </span><span style="color:Black">@errorNumber</span><span style="color:Gray">, </span><span style="color:Black">@errorMessage</span><span style="color:Gray">);
                </span><span style="color:Blue">end conversation </span><span style="color:Black">@h</span><span style="color:Gray">;
           </span><span style="color:Blue">end
           else
           begin
                raiserror</span><span style="color:Gray">(</span><span style="color:Red">N'Received unexpected message type: %s'</span><span style="color:Gray">, </span><span style="color:Black">16</span><span style="color:Gray">, </span><span style="color:Black">50</span><span style="color:Gray">, </span><span style="color:Black">@messageTypeName</span><span style="color:Gray">);
           </span><span style="color:Blue">end
        end
        commit</span><span style="color:Gray">;
    </span><span style="color:Blue">end try
    begin catch
        declare </span><span style="color:Black">@error </span><span style="color:Blue">int
         </span><span style="color:Gray">, </span><span style="color:Black">@message </span><span style="color:Blue">nvarchar</span><span style="color:Gray">(</span><span style="color:Black">2048</span><span style="color:Gray">);
        </span><span style="color:Blue">select </span><span style="color:Black">@error </span><span style="color:Gray">= </span><span style="color:Fuchsia">ERROR_NUMBER</span><span style="color:Gray">()
            , </span><span style="color:Black">@message </span><span style="color:Gray">= </span><span style="color:Fuchsia">ERROR_MESSAGE</span><span style="color:Gray">()
            , </span><span style="color:Black">@xactState </span><span style="color:Gray">= </span><span style="color:Fuchsia">XACT_STATE</span><span style="color:Gray">();
        </span><span style="color:Blue">if </span><span style="color:Gray">(</span><span style="color:Black">@xactState </span><span style="color:Gray">&lt;&gt; </span><span style="color:Black">0</span><span style="color:Gray">)
        </span><span style="color:Blue">begin
         rollback</span><span style="color:Gray">;
        </span><span style="color:Blue">end</span><span style="color:Gray">;
        </span><span style="color:Blue">raiserror</span><span style="color:Gray">(</span><span style="color:Red">N'Error: %i, %s'</span><span style="color:Gray">, </span><span style="color:Black">1</span><span style="color:Gray">, </span><span style="color:Black">60</span><span style="color:Gray">,  </span><span style="color:Black">@error</span><span style="color:Gray">, </span><span style="color:Black">@message</span><span style="color:Gray">) </span><span style="color:Blue">with </span><span style="color:Fuchsia">log</span><span style="color:Gray">;
    </span><span style="color:Blue">end catch
end
go

alter queue </span><span style="color:Black">[AsyncExecQueue]
    </span><span style="color:Blue">with activation </span><span style="color:Gray">(
    </span><span style="color:Blue">procedure_name </span><span style="color:Gray">= </span><span style="color:Black">[usp_AsyncExecActivated]
    </span><span style="color:Gray">, </span><span style="color:Blue">max_queue_readers </span><span style="color:Gray">= </span><span style="color:Black">1
    </span><span style="color:Gray">, </span><span style="color:Blue">execute as owner
    </span><span style="color:Gray">, </span><span style="color:Blue">status </span><span style="color:Gray">= </span><span style="color:Blue">on</span><span style="color:Gray">);
</span><span style="color:Blue">go

</span><span style="color:Green">-- Helper function to create the XML element 
-- for a passed in parameter
</span><span style="color:Blue">create function </span><span style="color:Black">[dbo]</span><span style="color:Gray">.</span><span style="color:Black">[fn_DescribeSqlVariant] </span><span style="color:Gray">(
 </span><span style="color:Black">@p </span><span style="color:Blue">sql_variant
 </span><span style="color:Gray">, </span><span style="color:Black">@n </span><span style="color:Blue">sysname</span><span style="color:Gray">)
</span><span style="color:Blue">returns xml
with schemabinding
as
begin
 return </span><span style="color:Gray">(
 </span><span style="color:Blue">select </span><span style="color:Black">@n </span><span style="color:Blue">as </span><span style="color:Black">[@Name]
  </span><span style="color:Gray">, </span><span style="color:Fuchsia">sql_variant_property</span><span style="color:Gray">(</span><span style="color:Black">@p</span><span style="color:Gray">, </span><span style="color:Red">'BaseType'</span><span style="color:Gray">) </span><span style="color:Blue">as </span><span style="color:Black">[@BaseType]
  </span><span style="color:Gray">, </span><span style="color:Fuchsia">sql_variant_property</span><span style="color:Gray">(</span><span style="color:Black">@p</span><span style="color:Gray">, </span><span style="color:Red">'Precision'</span><span style="color:Gray">) </span><span style="color:Blue">as </span><span style="color:Black">[@Precision]
  </span><span style="color:Gray">, </span><span style="color:Fuchsia">sql_variant_property</span><span style="color:Gray">(</span><span style="color:Black">@p</span><span style="color:Gray">, </span><span style="color:Red">'Scale'</span><span style="color:Gray">) </span><span style="color:Blue">as </span><span style="color:Black">[@Scale]
  </span><span style="color:Gray">, </span><span style="color:Fuchsia">sql_variant_property</span><span style="color:Gray">(</span><span style="color:Black">@p</span><span style="color:Gray">, </span><span style="color:Red">'MaxLength'</span><span style="color:Gray">) </span><span style="color:Blue">as </span><span style="color:Black">[@MaxLength]
  </span><span style="color:Gray">, </span><span style="color:Black">@p
  </span><span style="color:Blue">for xml path</span><span style="color:Gray">(</span><span style="color:Red">'parameter'</span><span style="color:Gray">), </span><span style="color:Blue">type</span><span style="color:Gray">)
</span><span style="color:Blue">end
GO

</span><span style="color:Green">-- Invocation wrapper. Accepts arbitrary
-- named parameetrs to be passed to the
-- background procedure
</span><span style="color:Blue">create procedure </span><span style="color:Black">[usp_AsyncExecInvoke]
    @procedureName </span><span style="color:Blue">sysname
    </span><span style="color:Gray">, </span><span style="color:Black">@p1 </span><span style="color:Blue">sql_variant </span><span style="color:Gray">= NULL, </span><span style="color:Black">@n1 </span><span style="color:Blue">sysname </span><span style="color:Gray">= NULL
    , </span><span style="color:Black">@p2 </span><span style="color:Blue">sql_variant </span><span style="color:Gray">= NULL, </span><span style="color:Black">@n2 </span><span style="color:Blue">sysname </span><span style="color:Gray">= NULL
    , </span><span style="color:Black">@p3 </span><span style="color:Blue">sql_variant </span><span style="color:Gray">= NULL, </span><span style="color:Black">@n3 </span><span style="color:Blue">sysname </span><span style="color:Gray">= NULL
    , </span><span style="color:Black">@p4 </span><span style="color:Blue">sql_variant </span><span style="color:Gray">= NULL, </span><span style="color:Black">@n4 </span><span style="color:Blue">sysname </span><span style="color:Gray">= NULL
    , </span><span style="color:Black">@p5 </span><span style="color:Blue">sql_variant </span><span style="color:Gray">= NULL, </span><span style="color:Black">@n5 </span><span style="color:Blue">sysname </span><span style="color:Gray">= NULL
    , </span><span style="color:Black">@token </span><span style="color:Blue">uniqueidentifier output
as
begin
    declare </span><span style="color:Black">@h </span><span style="color:Blue">uniqueidentifier
     </span><span style="color:Gray">, </span><span style="color:Black">@xmlBody </span><span style="color:Blue">xml
        </span><span style="color:Gray">, </span><span style="color:Black">@trancount </span><span style="color:Blue">int</span><span style="color:Gray">;
    </span><span style="color:Blue">set nocount on</span><span style="color:Gray">;

 </span><span style="color:Blue">set </span><span style="color:Black">@trancount </span><span style="color:Gray">= </span><span style="color:Fuchsia">@@trancount</span><span style="color:Gray">;
    </span><span style="color:Blue">if </span><span style="color:Black">@trancount </span><span style="color:Gray">= </span><span style="color:Black">0
        </span><span style="color:Blue">begin transaction
    else
        save transaction </span><span style="color:Black">usp_AsyncExecInvoke</span><span style="color:Gray">;
    </span><span style="color:Blue">begin try
        begin </span><span style="color:Black">dialog </span><span style="color:Blue">conversation </span><span style="color:Black">@h
            </span><span style="color:Blue">from service </span><span style="color:Black">[AsyncExecService]
            </span><span style="color:Blue">to service </span><span style="color:Red">N'AsyncExecService'</span><span style="color:Gray">, </span><span style="color:Red">'current database'
            </span><span style="color:Blue">with encryption </span><span style="color:Gray">= </span><span style="color:Blue">off</span><span style="color:Gray">;
        </span><span style="color:Blue">select </span><span style="color:Black">@token </span><span style="color:Gray">= </span><span style="color:Black">[conversation_id]
            </span><span style="color:Blue">from </span><span style="color:Green">sys</span><span style="color:Gray">.</span><span style="color:Green">conversation_endpoints
            </span><span style="color:Blue">where </span><span style="color:Black">[conversation_handle] </span><span style="color:Gray">= </span><span style="color:Black">@h</span><span style="color:Gray">;

        </span><span style="color:Blue">select </span><span style="color:Black">@xmlBody </span><span style="color:Gray">= (
            </span><span style="color:Blue">select </span><span style="color:Black">@procedureName </span><span style="color:Blue">as </span><span style="color:Black">[name]
            </span><span style="color:Gray">, (</span><span style="color:Blue">select </span><span style="color:Gray">* </span><span style="color:Blue">from </span><span style="color:Gray">(
                </span><span style="color:Blue">select </span><span style="color:Black">[dbo]</span><span style="color:Gray">.</span><span style="color:Black">[fn_DescribeSqlVariant] </span><span style="color:Gray">(</span><span style="color:Black">@p1</span><span style="color:Gray">, </span><span style="color:Black">@n1</span><span style="color:Gray">) </span><span style="color:Blue">AS </span><span style="color:Black">[*] 
                    </span><span style="color:Blue">WHERE </span><span style="color:Black">@p1 </span><span style="color:Gray">IS NOT NULL
                </span><span style="color:Blue">union </span><span style="color:Gray">all </span><span style="color:Blue">select </span><span style="color:Black">[dbo]</span><span style="color:Gray">.</span><span style="color:Black">[fn_DescribeSqlVariant] </span><span style="color:Gray">(</span><span style="color:Black">@p2</span><span style="color:Gray">, </span><span style="color:Black">@n2</span><span style="color:Gray">) </span><span style="color:Blue">AS </span><span style="color:Black">[*] 
                    </span><span style="color:Blue">WHERE </span><span style="color:Black">@p2 </span><span style="color:Gray">IS NOT NULL
                </span><span style="color:Blue">union </span><span style="color:Gray">all </span><span style="color:Blue">select </span><span style="color:Black">[dbo]</span><span style="color:Gray">.</span><span style="color:Black">[fn_DescribeSqlVariant] </span><span style="color:Gray">(</span><span style="color:Black">@p3</span><span style="color:Gray">, </span><span style="color:Black">@n3</span><span style="color:Gray">) </span><span style="color:Blue">AS </span><span style="color:Black">[*] 
                    </span><span style="color:Blue">WHERE </span><span style="color:Black">@p3 </span><span style="color:Gray">IS NOT NULL
                </span><span style="color:Blue">union </span><span style="color:Gray">all </span><span style="color:Blue">select </span><span style="color:Black">[dbo]</span><span style="color:Gray">.</span><span style="color:Black">[fn_DescribeSqlVariant] </span><span style="color:Gray">(</span><span style="color:Black">@p4</span><span style="color:Gray">, </span><span style="color:Black">@n4</span><span style="color:Gray">) </span><span style="color:Blue">AS </span><span style="color:Black">[*] 
                    </span><span style="color:Blue">WHERE </span><span style="color:Black">@p4 </span><span style="color:Gray">IS NOT NULL
                </span><span style="color:Blue">union </span><span style="color:Gray">all </span><span style="color:Blue">select </span><span style="color:Black">[dbo]</span><span style="color:Gray">.</span><span style="color:Black">[fn_DescribeSqlVariant] </span><span style="color:Gray">(</span><span style="color:Black">@p5</span><span style="color:Gray">, </span><span style="color:Black">@n5</span><span style="color:Gray">) </span><span style="color:Blue">AS </span><span style="color:Black">[*] 
                    </span><span style="color:Blue">WHERE </span><span style="color:Black">@p5 </span><span style="color:Gray">IS NOT NULL
                ) </span><span style="color:Blue">as </span><span style="color:Black">p </span><span style="color:Blue">for xml path</span><span style="color:Gray">(</span><span style="color:Red">''</span><span style="color:Gray">), </span><span style="color:Blue">type
            </span><span style="color:Gray">) </span><span style="color:Blue">as </span><span style="color:Black">[parameters]
            </span><span style="color:Blue">for xml path</span><span style="color:Gray">(</span><span style="color:Red">'procedure'</span><span style="color:Gray">), </span><span style="color:Blue">type</span><span style="color:Gray">);
        </span><span style="color:Blue">send on conversation </span><span style="color:Black">@h </span><span style="color:Gray">(</span><span style="color:Black">@xmlBody</span><span style="color:Gray">);
        </span><span style="color:Blue">insert into </span><span style="color:Black">[AsyncExecResults]
            </span><span style="color:Gray">(</span><span style="color:Black">[token]</span><span style="color:Gray">, </span><span style="color:Black">[submit_time]</span><span style="color:Gray">)
            </span><span style="color:Blue">values
            </span><span style="color:Gray">(</span><span style="color:Black">@token</span><span style="color:Gray">, </span><span style="color:Fuchsia">getutcdate</span><span style="color:Gray">());
    </span><span style="color:Blue">if </span><span style="color:Black">@trancount </span><span style="color:Gray">= </span><span style="color:Black">0
        </span><span style="color:Blue">commit</span><span style="color:Gray">;
    </span><span style="color:Blue">end try
    begin catch
        declare </span><span style="color:Black">@error </span><span style="color:Blue">int
            </span><span style="color:Gray">, </span><span style="color:Black">@message </span><span style="color:Blue">nvarchar</span><span style="color:Gray">(</span><span style="color:Black">2048</span><span style="color:Gray">)
            , </span><span style="color:Black">@xactState </span><span style="color:Blue">smallint</span><span style="color:Gray">;
        </span><span style="color:Blue">select </span><span style="color:Black">@error </span><span style="color:Gray">= </span><span style="color:Fuchsia">ERROR_NUMBER</span><span style="color:Gray">()
            , </span><span style="color:Black">@message </span><span style="color:Gray">= </span><span style="color:Fuchsia">ERROR_MESSAGE</span><span style="color:Gray">()
            , </span><span style="color:Black">@xactState </span><span style="color:Gray">= </span><span style="color:Fuchsia">XACT_STATE</span><span style="color:Gray">();
        </span><span style="color:Blue">if </span><span style="color:Black">@xactState </span><span style="color:Gray">= -</span><span style="color:Black">1
            </span><span style="color:Blue">rollback</span><span style="color:Gray">;
        </span><span style="color:Blue">if </span><span style="color:Black">@xactState </span><span style="color:Gray">= </span><span style="color:Black">1 </span><span style="color:Gray">and </span><span style="color:Black">@trancount </span><span style="color:Gray">= </span><span style="color:Black">0
            </span><span style="color:Blue">rollback
        if </span><span style="color:Black">@xactState </span><span style="color:Gray">= </span><span style="color:Black">1 </span><span style="color:Gray">and </span><span style="color:Black">@trancount </span><span style="color:Gray">&gt; </span><span style="color:Black">0
            </span><span style="color:Blue">rollback transaction </span><span style="color:Black">usp_my_procedure_name</span><span style="color:Gray">;

        </span><span style="color:Blue">raiserror</span><span style="color:Gray">(</span><span style="color:Red">N'Error: %i, %s'</span><span style="color:Gray">, </span><span style="color:Black">16</span><span style="color:Gray">, </span><span style="color:Black">1</span><span style="color:Gray">, </span><span style="color:Black">@error</span><span style="color:Gray">, </span><span style="color:Black">@message</span><span style="color:Gray">);
    </span><span style="color:Blue">end catch
end
go

</span><span style="color:Green">-- Sample invocation example
-- The usp_withParam will insert 
-- all the received parameters into this table
-- 
</span><span style="color:Blue">create table </span><span style="color:Black">[withParam] </span><span style="color:Gray">(
    </span><span style="color:Black">id </span><span style="color:Blue">numeric</span><span style="color:Gray">(</span><span style="color:Black">4</span><span style="color:Gray">,</span><span style="color:Black">1</span><span style="color:Gray">) NULL
    , </span><span style="color:Black">name </span><span style="color:Blue">varchar</span><span style="color:Gray">(</span><span style="color:Black">150</span><span style="color:Gray">) NULL
    , </span><span style="color:Blue">date datetime  </span><span style="color:Gray">NULL
    , </span><span style="color:Black">value </span><span style="color:Blue">int </span><span style="color:Gray">NULL
    , </span><span style="color:Black">bytes </span><span style="color:Blue">varbinary</span><span style="color:Gray">(</span><span style="color:Fuchsia">max</span><span style="color:Gray">) NULL);
</span><span style="color:Blue">go

create procedure </span><span style="color:Black">usp_withParam
 @id </span><span style="color:Blue">numeric</span><span style="color:Gray">(</span><span style="color:Black">4</span><span style="color:Gray">,</span><span style="color:Black">1</span><span style="color:Gray">)
 , </span><span style="color:Black">@name </span><span style="color:Blue">varchar</span><span style="color:Gray">(</span><span style="color:Black">150</span><span style="color:Gray">)
 , </span><span style="color:Black">@date </span><span style="color:Blue">datetime </span><span style="color:Gray">= NULL
 , </span><span style="color:Black">@value </span><span style="color:Blue">int </span><span style="color:Gray">= </span><span style="color:Black">0
 </span><span style="color:Gray">, </span><span style="color:Black">@bytes </span><span style="color:Blue">varbinary</span><span style="color:Gray">(</span><span style="color:Fuchsia">max</span><span style="color:Gray">) = NULL
</span><span style="color:Blue">as
begin
    insert into </span><span style="color:Black">[withParam] </span><span style="color:Gray">(
        </span><span style="color:Black">id
        </span><span style="color:Gray">, </span><span style="color:Black">name
        </span><span style="color:Gray">, </span><span style="color:Blue">date
        </span><span style="color:Gray">, </span><span style="color:Black">value
        </span><span style="color:Gray">, </span><span style="color:Black">bytes</span><span style="color:Gray">)
     </span><span style="color:Blue">select </span><span style="color:Black">@id </span><span style="color:Blue">as </span><span style="color:Black">[id]
      </span><span style="color:Gray">, </span><span style="color:Black">@name </span><span style="color:Blue">as </span><span style="color:Black">[name]
      </span><span style="color:Gray">, </span><span style="color:Black">@date </span><span style="color:Blue">as </span><span style="color:Black">[date]
      </span><span style="color:Gray">, </span><span style="color:Black">@value </span><span style="color:Blue">as </span><span style="color:Black">[value]
      </span><span style="color:Gray">, </span><span style="color:Black">@bytes </span><span style="color:Blue">as </span><span style="color:Black">[bytes]
</span><span style="color:Blue">end
go

declare </span><span style="color:Black">@token </span><span style="color:Blue">uniqueidentifier</span><span style="color:Gray">;

</span><span style="color:Blue">exec </span><span style="color:Black">usp_AsyncExecInvoke @procedureName </span><span style="color:Gray">= </span><span style="color:Red">N'usp_withParam'
 </span><span style="color:Gray">, </span><span style="color:Black">@p1 </span><span style="color:Gray">= </span><span style="color:Black">1.0</span><span style="color:Gray">, </span><span style="color:Black">@n1 </span><span style="color:Gray">= </span><span style="color:Red">N'@id'
 </span><span style="color:Gray">, </span><span style="color:Black">@p2 </span><span style="color:Gray">= </span><span style="color:Red">N'Foo'</span><span style="color:Gray">, </span><span style="color:Black">@n2</span><span style="color:Gray">=</span><span style="color:Red">'@name'
 </span><span style="color:Gray">, </span><span style="color:Black">@p3 </span><span style="color:Gray">= </span><span style="color:Black">0xBAADF00D</span><span style="color:Gray">, </span><span style="color:Black">@n3 </span><span style="color:Gray">= </span><span style="color:Red">'@bytes'
 </span><span style="color:Gray">, </span><span style="color:Black">@token </span><span style="color:Gray">= </span><span style="color:Black">@token </span><span style="color:Blue">output</span><span style="color:Gray">;

</span><span style="color:Blue">waitfor delay </span><span style="color:Red">'00:00:05'</span><span style="color:Gray">;

</span><span style="color:Blue">select </span><span style="color:Gray">* </span><span style="color:Blue">from </span><span style="color:Black">AsyncExecResults</span><span style="color:Gray">;
</span><span style="color:Blue">select </span><span style="color:Gray">* </span><span style="color:Blue">from </span><span style="color:Black">withParam</span><span style="color:Gray">;

</span><span style="color:Blue">go</span>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://rusanu.com/2009/08/18/passing-parameters-to-a-background-procedure/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Asynchronous procedure execution</title>
		<link>http://rusanu.com/2009/08/05/asynchronous-procedure-execution/</link>
		<comments>http://rusanu.com/2009/08/05/asynchronous-procedure-execution/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 08:26:42 +0000</pubDate>
		<dc:creator>remus</dc:creator>
		
		<category><![CDATA[Samples]]></category>

		<category><![CDATA[Tutorials]]></category>

		<category><![CDATA[activation]]></category>

		<category><![CDATA[asynchronous procedure]]></category>

		<category><![CDATA[long running]]></category>

		<category><![CDATA[sql server]]></category>

		<category><![CDATA[tsql]]></category>

		<guid isPermaLink="false">http://rusanu.com/?p=514</guid>
		<description><![CDATA[Copyright Remus Rusanu 2010. Visit the original article at http://rusanu.com/2009/08/05/asynchronous-procedure-execution/&#160;&#160;Update: a version of this sample that accepts parameters is available in the post Passing Parameters to a Background Procedure
Recently an user on StackOverflow raised the question Execute a stored procedure from a windows form asynchronously and then disconnect?.  This is a known problem, how [...]]]></description>
			<content:encoded><![CDATA[<p>Copyright Remus Rusanu 2010. Visit the original article at <a href="http://rusanu.com/2009/08/05/asynchronous-procedure-execution/">http://rusanu.com/2009/08/05/asynchronous-procedure-execution/</a></p>&nbsp;&nbsp;<br><p><b>Update:</b> a version of this sample that accepts parameters is available in the post <a href="http://rusanu.com/2009/08/18/passing-parameters-to-a-background-procedure/">Passing Parameters to a Background Procedure</a></p>
<p>Recently an user on StackOverflow raised the question <a href="http://stackoverflow.com/questions/1229438/execute-a-stored-procedure-from-a-windows-form-asynchronously-and-then-disconnect" target="_blank">Execute a stored procedure from a windows form asynchronously and then disconnect?</a>.  This is a known problem, how to invoke a long running procedure on SQL Server without constraining the client to wait for the procedure execution to terminate. Most times I&#8217;ve seen this question raised in the context of web applications when waiting for a result means delaying the response to the client browser. On Web apps the time constraint is even more drastic, the developer often desires to launch the procedure and immediately return the page even when the execution lasts only few seconds. The application will retrieve the execution result later, usually via an Ajax call driven by the returned page script.</p>
<p>Frankly I was a bit surprised to see that the responses gravitated either around the SqlClient asynchronous methods (BeginExecute&#8230;) or around having a dedicated process with the sole pupose of maintaining the client connection alive for the duration of the long running procedure.</p>
<p>This problem is perfectly addressed by Service Broker Activation. Since I wanted to preserve the solution for further reference, I decided to put it in as a blog entry, with additional comments. For many of you Service Broker aficionados that read my blog regularly, this article is not innovative as is mostly a rehash of well known techniques I&#8217;ve been talking about on forums for many years now.</p>
<p>I&#8217;m going to use a table to store the result of the procedure execution. In this version I&#8217;ll keep things simple by not allowing for any parameters to be passed to the procedure, nor collecting any execution result set data. So the table will only contain the procedure start time, the execution finish time and any error that occurred during the procedure execution:</p>
<pre>
<span style="color: Black"></span><span style="color:Blue">create</span><span style="color:Black">&nbsp;</span><span style="color:Blue">table</span><span style="color:Black">&nbsp;[AsyncExecResults]&nbsp;</span><span style="color:Gray">(
</span><span style="color:Black">	[token]&nbsp;</span><span style="color:Blue">uniqueidentifier</span><span style="color:Black">&nbsp;</span><span style="color:Blue">primary</span><span style="color:Black">&nbsp;</span><span style="color:Blue">key
</span><span style="color:Black">	</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;[submit_time]&nbsp;</span><span style="color:Blue">datetime</span><span style="color:Black">&nbsp;</span><span style="color:Gray">not</span><span style="color:Black">&nbsp;</span><span style="color:Gray">null
</span><span style="color:Black">	</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;[start_time]&nbsp;</span><span style="color:Blue">datetime</span><span style="color:Black">&nbsp;</span><span style="color:Gray">null
</span><span style="color:Black">	</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;[finish_time]&nbsp;</span><span style="color:Blue">datetime</span><span style="color:Black">&nbsp;</span><span style="color:Gray">null
</span><span style="color:Black">	</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;[error_number]	</span><span style="color:Blue">int</span><span style="color:Black">&nbsp;</span><span style="color:Gray">null
</span><span style="color:Black">	</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;[error_message]&nbsp;</span><span style="color:Blue">nvarchar</span><span style="color:Gray">(</span><span style="color:Black">2048</span><span style="color:Gray">)</span><span style="color:Black">&nbsp;</span><span style="color:Gray">null);
</span><span style="color:Black">go
</pre>
<p>Next we&#8217;re going to create the service and queue we need. I will use one single service for both roles (initiator and target) and I won&#8217;t create an explicit contract, relying instead on the predefined DEFAULT contract:</p>
<pre>
</span><span style="color:Blue">create</span><span style="color:Black">&nbsp;</span><span style="color:Blue">queue</span><span style="color:Black">&nbsp;[AsyncExecQueue]</span><span style="color:Gray">;
</span><span style="color:Black">go

</span><span style="color:Blue">create</span><span style="color:Black">&nbsp;</span><span style="color:Blue">service</span><span style="color:Black">&nbsp;[AsyncExecService]&nbsp;</span><span style="color:Blue">on</span><span style="color:Black">&nbsp;</span><span style="color:Blue">queue</span><span style="color:Black">&nbsp;[AsyncExecQueue]&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">[DEFAULT]</span><span style="color:Gray">);
</span><span style="color:Black">GO
</span>
</pre>
<p>Next is the core of our asynchronous execution: the activated procedure. The procedure has to dequeue the message that specifies the user procedure, run the procedure and write the result in the results table. I will also deploy the error handling template I elaborated on my previous article <a href="http://rusanu.com/2009/06/11/exception-handling-and-nested-transactions/" target="_blank">Exception handling and nested transactions</a>:</p>
<pre>
<span style="color: Black"></span><span style="color:Blue">create</span><span style="color:Black">&nbsp;</span><span style="color:Blue">procedure</span><span style="color:Black">&nbsp;usp_AsyncExecActivated
</span><span style="color:Blue">as
begin
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">set</span><span style="color:Black">&nbsp;</span><span style="color:Blue">nocount</span><span style="color:Black">&nbsp;</span><span style="color:Blue">on</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">declare</span><span style="color:Black">&nbsp;@h&nbsp;</span><span style="color:Blue">uniqueidentifier
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@messageTypeName&nbsp;</span><span style="color:Blue">sysname
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@messageBody&nbsp;</span><span style="color:Blue">varbinary</span><span style="color:Gray">(</span><span style="color:Fuchsia">max</span><span style="color:Gray">)
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@xmlBody&nbsp;</span><span style="color:Blue">xml
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@procedureName&nbsp;</span><span style="color:Blue">sysname
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@startTime&nbsp;</span><span style="color:Blue">datetime
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@finishTime&nbsp;</span><span style="color:Blue">datetime
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@execErrorNumber&nbsp;</span><span style="color:Blue">int
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@execErrorMessage&nbsp;</span><span style="color:Blue">nvarchar</span><span style="color:Gray">(</span><span style="color:Black">2048</span><span style="color:Gray">)
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@xactState&nbsp;</span><span style="color:Blue">smallint
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@token&nbsp;</span><span style="color:Blue">uniqueidentifier</span><span style="color:Gray">;
</span><span style="color:Black">	
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin</span><span style="color:Black">&nbsp;</span><span style="color:Blue">transaction</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin</span><span style="color:Black">&nbsp;</span><span style="color:Blue">try</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">receive</span><span style="color:Black">&nbsp;</span><span style="color:Blue">top</span><span style="color:Gray">(</span><span style="color:Black">1</span><span style="color:Gray">)</span><span style="color:Black">&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@h&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;[conversation_handle]
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@messageTypeName&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;[message_type_name]
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@messageBody&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;[message_body]
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">from</span><span style="color:Black">&nbsp;[AsyncExecQueue]</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">if</span><span style="color:Black">&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">@h&nbsp;</span><span style="color:Gray">is</span><span style="color:Black">&nbsp;</span><span style="color:Gray">not</span><span style="color:Black">&nbsp;</span><span style="color:Gray">null)
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">if</span><span style="color:Black">&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">@messageTypeName&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;N</span><span style="color:Red">'DEFAULT'</span><span style="color:Gray">)
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Green">--&nbsp;The&nbsp;DEFAULT&nbsp;message&nbsp;type&nbsp;is&nbsp;a&nbsp;procedure&nbsp;invocation.
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Green">--&nbsp;Extract&nbsp;the&nbsp;name&nbsp;of&nbsp;the&nbsp;procedure&nbsp;from&nbsp;the&nbsp;message&nbsp;body.
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Green">--
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;@xmlBody&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">CAST</span><span style="color:Gray">(</span><span style="color:Black">@messageBody&nbsp;</span><span style="color:Blue">as</span><span style="color:Black">&nbsp;</span><span style="color:Blue">xml</span><span style="color:Gray">);
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;@procedureName&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;@xmlBody</span><span style="color:Gray">.</span><span style="color:Black">value</span><span style="color:Gray">(
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Red">'(//procedure/name)[1]'
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;</span><span style="color:Red">'sysname'</span><span style="color:Gray">);

</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">save</span><span style="color:Black">&nbsp;</span><span style="color:Blue">transaction</span><span style="color:Black">&nbsp;usp_AsyncExec_procedure</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;@startTime&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">GETUTCDATE</span><span style="color:Gray">();
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin</span><span style="color:Black">&nbsp;</span><span style="color:Blue">try
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">exec</span><span style="color:Black">&nbsp;@procedureName</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end</span><span style="color:Black">&nbsp;</span><span style="color:Blue">try
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin</span><span style="color:Black">&nbsp;</span><span style="color:Blue">catch
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Green">--&nbsp;This&nbsp;catch&nbsp;block&nbsp;tries&nbsp;to&nbsp;deal&nbsp;with&nbsp;failures&nbsp;of&nbsp;the&nbsp;procedure&nbsp;execution
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Green">--&nbsp;If&nbsp;possible&nbsp;it&nbsp;rolls&nbsp;back&nbsp;to&nbsp;the&nbsp;savepoint&nbsp;created&nbsp;earlier,&nbsp;allowing
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Green">--&nbsp;the&nbsp;activated&nbsp;procedure&nbsp;to&nbsp;continue.&nbsp;If&nbsp;the&nbsp;executed&nbsp;procedure&nbsp;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Green">--&nbsp;raises&nbsp;an&nbsp;error&nbsp;with&nbsp;severity&nbsp;16&nbsp;or&nbsp;higher,&nbsp;it&nbsp;will&nbsp;doom&nbsp;the&nbsp;transaction
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Green">--&nbsp;and&nbsp;thus&nbsp;rollback&nbsp;the&nbsp;RECEIVE.&nbsp;Such&nbsp;case&nbsp;will&nbsp;be&nbsp;a&nbsp;poison&nbsp;message,
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Green">--&nbsp;resulting&nbsp;in&nbsp;the&nbsp;queue&nbsp;disabling.
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Green">--
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;@execErrorNumber&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">ERROR_NUMBER</span><span style="color:Gray">(),
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@execErrorMessage&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">ERROR_MESSAGE</span><span style="color:Gray">(),
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@xactState&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">XACT_STATE</span><span style="color:Gray">();
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">if</span><span style="color:Black">&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">@xactState&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Gray">-</span><span style="color:Black">1</span><span style="color:Gray">)
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">rollback</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">raiserror</span><span style="color:Gray">(</span><span style="color:Black">N</span><span style="color:Red">'Unrecoverable&nbsp;error&nbsp;in&nbsp;procedure&nbsp;%s:&nbsp;%i:&nbsp;%s'</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;16</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;10</span><span style="color:Gray">,
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@procedureName</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@execErrorNumber</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@execErrorMessage</span><span style="color:Gray">);
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">else</span><span style="color:Black">&nbsp;</span><span style="color:Blue">if</span><span style="color:Black">&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">@xactState&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;1</span><span style="color:Gray">)
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">rollback</span><span style="color:Black">&nbsp;</span><span style="color:Blue">transaction</span><span style="color:Black">&nbsp;usp_AsyncExec_procedure</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end</span><span style="color:Black">&nbsp;</span><span style="color:Blue">catch

</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;@finishTime&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">GETUTCDATE</span><span style="color:Gray">();
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;@token&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;[conversation_id]&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">from</span><span style="color:Black">&nbsp;</span><span style="color:Green">sys.conversation_endpoints</span><span style="color:Black">&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">where</span><span style="color:Black">&nbsp;[conversation_handle]&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;@h</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">if</span><span style="color:Black">&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">@token&nbsp;</span><span style="color:Gray">is</span><span style="color:Black">&nbsp;</span><span style="color:Gray">null)
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">raiserror</span><span style="color:Gray">(</span><span style="color:Black">N</span><span style="color:Red">'Internal&nbsp;consistency&nbsp;error:&nbsp;conversation&nbsp;not&nbsp;found'</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;16</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;20</span><span style="color:Gray">);
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">update</span><span style="color:Black">&nbsp;[AsyncExecResults]&nbsp;</span><span style="color:Blue">set
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[start_time]&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;@starttime
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;[finish_time]&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;@finishTime
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;[error_number]&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;@execErrorNumber
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;[error_message]&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;@execErrorMessage
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">where</span><span style="color:Black">&nbsp;[token]&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;@token</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">if</span><span style="color:Black">&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">0&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">@@ROWCOUNT</span><span style="color:Gray">)
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">raiserror</span><span style="color:Gray">(</span><span style="color:Black">N</span><span style="color:Red">'Internal&nbsp;consistency&nbsp;error:&nbsp;token&nbsp;not&nbsp;found'</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;16</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;30</span><span style="color:Gray">);
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end</span><span style="color:Black">&nbsp;</span><span style="color:Blue">conversation</span><span style="color:Black">&nbsp;@h</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end</span><span style="color:Black">&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">else</span><span style="color:Black">&nbsp;</span><span style="color:Blue">if</span><span style="color:Black">&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">@messageTypeName&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;N</span><span style="color:Red">'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'</span><span style="color:Gray">)
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end</span><span style="color:Black">&nbsp;</span><span style="color:Blue">conversation</span><span style="color:Black">&nbsp;@h</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">else</span><span style="color:Black">&nbsp;</span><span style="color:Blue">if</span><span style="color:Black">&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">@messageTypeName&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;N</span><span style="color:Red">'http://schemas.microsoft.com/SQL/ServiceBroker/Error'</span><span style="color:Gray">)
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">declare</span><span style="color:Black">&nbsp;@errorNumber&nbsp;</span><span style="color:Blue">int
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@errorMessage&nbsp;</span><span style="color:Blue">nvarchar</span><span style="color:Gray">(</span><span style="color:Black">4000</span><span style="color:Gray">);
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">with</span><span style="color:Black">&nbsp;</span><span style="color:Blue">xmlnamespaces</span><span style="color:Black">&nbsp;</span><span style="color:Gray">(</span><span style="color:Blue">DEFAULT</span><span style="color:Black">&nbsp;N</span><span style="color:Red">'http://schemas.microsoft.com/SQL/ServiceBroker/Error'</span><span style="color:Gray">)
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;@errorNumber&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;@xmlBody</span><span style="color:Gray">.</span><span style="color:Black">value&nbsp;</span><span style="color:Gray">(</span><span style="color:Red">'(/Error/Code)[1]'</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;</span><span style="color:Red">'INT'</span><span style="color:Gray">),
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@errorMessage&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;@xmlBody</span><span style="color:Gray">.</span><span style="color:Black">value&nbsp;</span><span style="color:Gray">(</span><span style="color:Red">'(/Error/Description)[1]'</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;</span><span style="color:Red">'NVARCHAR(4000)'</span><span style="color:Gray">);
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">raiserror</span><span style="color:Gray">(</span><span style="color:Black">N</span><span style="color:Red">'A&nbsp;conversation&nbsp;error&nbsp;was&nbsp;encountered:&nbsp;%i:&nbsp;%s'</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;1</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;40</span><span style="color:Gray">,
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@errorNumber</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@errorMessage</span><span style="color:Gray">);</span><span style="color:Black">&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end</span><span style="color:Black">&nbsp;</span><span style="color:Blue">conversation</span><span style="color:Black">&nbsp;@h</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">else
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">raiserror</span><span style="color:Gray">(</span><span style="color:Black">N</span><span style="color:Red">'Received&nbsp;unexpected&nbsp;message&nbsp;type:&nbsp;%s'</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;16</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;50</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@messageTypeName</span><span style="color:Gray">);
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">commit</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end</span><span style="color:Black">&nbsp;</span><span style="color:Blue">try
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin</span><span style="color:Black">&nbsp;</span><span style="color:Blue">catch
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">declare</span><span style="color:Black">&nbsp;@error&nbsp;</span><span style="color:Blue">int
</span><span style="color:Black">	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@message&nbsp;</span><span style="color:Blue">nvarchar</span><span style="color:Gray">(</span><span style="color:Black">2048</span><span style="color:Gray">);
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;@error&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">ERROR_NUMBER</span><span style="color:Gray">()
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@message&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">ERROR_MESSAGE</span><span style="color:Gray">()
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@xactState&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">XACT_STATE</span><span style="color:Gray">();
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">if</span><span style="color:Black">&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">@xactState&nbsp;</span><span style="color:Gray">&lt;&gt;</span><span style="color:Black">&nbsp;0</span><span style="color:Gray">)
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin
</span><span style="color:Black">	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">rollback</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">raiserror</span><span style="color:Gray">(</span><span style="color:Black">N</span><span style="color:Red">'Error:&nbsp;%i,&nbsp;%s'</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;1</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;60</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;&nbsp;@error</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@message</span><span style="color:Gray">)</span><span style="color:Black">&nbsp;</span><span style="color:Blue">with</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">log</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end</span><span style="color:Black">&nbsp;</span><span style="color:Blue">catch
end
</span><span style="color:Black">go
</span>
</pre>
<p>To make the procedure activated we need to attach it to our service queue. This will ensure this procedure is run whenever a message arrives to our [AsyncExecService]:</p>
<pre>
<span style="color: Black"></span><span style="color:Blue">alter</span><span style="color:Black">&nbsp;</span><span style="color:Blue">queue</span><span style="color:Black">&nbsp;[AsyncExecQueue]
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">with</span><span style="color:Black">&nbsp;activation&nbsp;</span><span style="color:Gray">(
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;procedure_name&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;[usp_AsyncExecActivated]
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;max_queue_readers&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;1
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;</span><span style="color:Blue">execute</span><span style="color:Black">&nbsp;</span><span style="color:Blue">as</span><span style="color:Black">&nbsp;</span><span style="color:Blue">owner
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;</span><span style="color:Blue">status</span><span style="color:Black">&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Blue">on</span><span style="color:Gray">);
</span><span style="color:Black">go
</span>
</pre>
<p>And finaly the last piece of the puzzle: the procedure that submits the message to invoke the desired asyncronous executed procedure. This procedure resturns an output parameter &#8216;token&#8217; than can be used to lookup the asynchronous execution result.</p>
<pre>
<span style="color: Black"></span><span style="color:Blue">create</span><span style="color:Black">&nbsp;</span><span style="color:Blue">procedure</span><span style="color:Black">&nbsp;[usp_AsyncExecInvoke]
&nbsp;&nbsp;&nbsp;&nbsp;@procedureName&nbsp;</span><span style="color:Blue">sysname
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@token&nbsp;</span><span style="color:Blue">uniqueidentifier</span><span style="color:Black">&nbsp;</span><span style="color:Blue">output
as
begin
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">declare</span><span style="color:Black">&nbsp;@h&nbsp;</span><span style="color:Blue">uniqueidentifier
</span><span style="color:Black">	&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@xmlBody&nbsp;</span><span style="color:Blue">xml
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@trancount&nbsp;</span><span style="color:Blue">int</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">set</span><span style="color:Black">&nbsp;</span><span style="color:Blue">nocount</span><span style="color:Black">&nbsp;</span><span style="color:Blue">on</span><span style="color:Gray">;

</span><span style="color:Black">	</span><span style="color:Blue">set</span><span style="color:Black">&nbsp;@trancount&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">@@trancount</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">if</span><span style="color:Black">&nbsp;@trancount&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;0
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin</span><span style="color:Black">&nbsp;</span><span style="color:Blue">transaction
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">else
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">save</span><span style="color:Black">&nbsp;</span><span style="color:Blue">transaction</span><span style="color:Black">&nbsp;usp_AsyncExecInvoke</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin</span><span style="color:Black">&nbsp;</span><span style="color:Blue">try
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin</span><span style="color:Black">&nbsp;</span><span style="color:Blue">dialog</span><span style="color:Black">&nbsp;</span><span style="color:Blue">conversation</span><span style="color:Black">&nbsp;@h
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">from</span><span style="color:Black">&nbsp;</span><span style="color:Blue">service</span><span style="color:Black">&nbsp;[AsyncExecService]
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">to</span><span style="color:Black">&nbsp;</span><span style="color:Blue">service</span><span style="color:Black">&nbsp;N</span><span style="color:Red">'AsyncExecService'</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;</span><span style="color:Red">'current&nbsp;database'
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">with</span><span style="color:Black">&nbsp;</span><span style="color:Blue">encryption</span><span style="color:Black">&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Blue">off</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;@token&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;[conversation_id]
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">from</span><span style="color:Black">&nbsp;</span><span style="color:Green">sys.conversation_endpoints
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">where</span><span style="color:Black">&nbsp;[conversation_handle]&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;@h</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;@xmlBody&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Gray">(
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;@procedureName&nbsp;</span><span style="color:Blue">as</span><span style="color:Black">&nbsp;[name]
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">for</span><span style="color:Black">&nbsp;</span><span style="color:Blue">xml</span><span style="color:Black">&nbsp;</span><span style="color:Blue">path</span><span style="color:Gray">(</span><span style="color:Red">'procedure'</span><span style="color:Gray">),</span><span style="color:Black">&nbsp;</span><span style="color:Blue">type</span><span style="color:Gray">);
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">send</span><span style="color:Black">&nbsp;</span><span style="color:Blue">on</span><span style="color:Black">&nbsp;</span><span style="color:Blue">conversation</span><span style="color:Black">&nbsp;@h&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">@xmlBody</span><span style="color:Gray">);
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">insert</span><span style="color:Black">&nbsp;</span><span style="color:Blue">into</span><span style="color:Black">&nbsp;[AsyncExecResults]
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">[token]</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;[submit_time]</span><span style="color:Gray">)
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">values
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">@token</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">getutcdate</span><span style="color:Gray">());
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">if</span><span style="color:Black">&nbsp;@trancount&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;0
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">commit</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end</span><span style="color:Black">&nbsp;</span><span style="color:Blue">try
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">begin</span><span style="color:Black">&nbsp;</span><span style="color:Blue">catch
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">declare</span><span style="color:Black">&nbsp;@error&nbsp;</span><span style="color:Blue">int
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@message&nbsp;</span><span style="color:Blue">nvarchar</span><span style="color:Gray">(</span><span style="color:Black">2048</span><span style="color:Gray">)
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@xactState&nbsp;</span><span style="color:Blue">smallint</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;@error&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">ERROR_NUMBER</span><span style="color:Gray">()
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@message&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">ERROR_MESSAGE</span><span style="color:Gray">()
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@xactState&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Fuchsia">XACT_STATE</span><span style="color:Gray">();
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">if</span><span style="color:Black">&nbsp;@xactState&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;</span><span style="color:Gray">-</span><span style="color:Black">1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">rollback</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">if</span><span style="color:Black">&nbsp;@xactState&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;1&nbsp;</span><span style="color:Gray">and</span><span style="color:Black">&nbsp;@trancount&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;0
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">rollback
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">if</span><span style="color:Black">&nbsp;@xactState&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;1&nbsp;</span><span style="color:Gray">and</span><span style="color:Black">&nbsp;@trancount&nbsp;</span><span style="color:Gray">&gt;</span><span style="color:Black">&nbsp;0
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">rollback</span><span style="color:Black">&nbsp;</span><span style="color:Blue">transaction</span><span style="color:Black">&nbsp;usp_my_procedure_name</span><span style="color:Gray">;

</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">raiserror</span><span style="color:Gray">(</span><span style="color:Black">N</span><span style="color:Red">'Error:&nbsp;%i,&nbsp;%s'</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;16</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;1</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@error</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@message</span><span style="color:Gray">);
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">end</span><span style="color:Black">&nbsp;</span><span style="color:Blue">catch
end
</span><span style="color:Black">go</span>
</pre>
<p>To test our asynchronous execution infrastructure we create a test procedure and invoke it asynchronously. I will create two test procedures, one that simply waits for 5 seconds to simulate a &#8216;long&#8217; running procedure and one that produces intentionally a primary key violation, to simulate a fault in the asynchronously executed procedure:</p>
<pre>
<span style="color: Black"></span><span style="color:Blue">create</span><span style="color:Black">&nbsp;</span><span style="color:Blue">procedure</span><span style="color:Black">&nbsp;[usp_MyLongRunningProcedure]
</span><span style="color:Blue">as
begin
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">waitfor</span><span style="color:Black">&nbsp;</span><span style="color:Blue">delay</span><span style="color:Black">&nbsp;</span><span style="color:Red">'00:00:05'</span><span style="color:Gray">;
</span><span style="color:Blue">end
</span><span style="color:Black">go

</span><span style="color:Blue">create</span><span style="color:Black">&nbsp;</span><span style="color:Blue">procedure</span><span style="color:Black">&nbsp;[usp_MyFaultyProcedure]
</span><span style="color:Blue">as
begin
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">set</span><span style="color:Black">&nbsp;</span><span style="color:Blue">nocount</span><span style="color:Black">&nbsp;</span><span style="color:Blue">on</span><span style="color:Gray">;
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">declare</span><span style="color:Black">&nbsp;@t&nbsp;</span><span style="color:Blue">table</span><span style="color:Black">&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">id&nbsp;</span><span style="color:Blue">int</span><span style="color:Black">&nbsp;</span><span style="color:Blue">primary</span><span style="color:Black">&nbsp;</span><span style="color:Blue">key</span><span style="color:Gray">);
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">insert</span><span style="color:Black">&nbsp;</span><span style="color:Blue">into</span><span style="color:Black">&nbsp;@t&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">id</span><span style="color:Gray">)</span><span style="color:Black">&nbsp;</span><span style="color:Blue">values</span><span style="color:Black">&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">1</span><span style="color:Gray">);
</span><span style="color:Black">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color:Blue">insert</span><span style="color:Black">&nbsp;</span><span style="color:Blue">into</span><span style="color:Black">&nbsp;@t&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">id</span><span style="color:Gray">)</span><span style="color:Black">&nbsp;</span><span style="color:Blue">values</span><span style="color:Black">&nbsp;</span><span style="color:Gray">(</span><span style="color:Black">1</span><span style="color:Gray">);
</span><span style="color:Blue">end
</span><span style="color:Black">go


</span><span style="color:Blue">declare</span><span style="color:Black">&nbsp;@token&nbsp;</span><span style="color:Blue">uniqueidentifier</span><span style="color:Gray">;
</span><span style="color:Blue">exec</span><span style="color:Black">&nbsp;usp_AsyncExecInvoke&nbsp;N</span><span style="color:Red">'usp_MyLongRunningProcedure'</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@token&nbsp;</span><span style="color:Blue">output</span><span style="color:Gray">;
</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;</span><span style="color:Gray">*</span><span style="color:Black">&nbsp;</span><span style="color:Blue">from</span><span style="color:Black">&nbsp;[AsyncExecResults]&nbsp;</span><span style="color:Blue">where</span><span style="color:Black">&nbsp;[token]&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;@token</span><span style="color:Gray">;
</span><span style="color:Black">go

</span><span style="color:Blue">declare</span><span style="color:Black">&nbsp;@token&nbsp;</span><span style="color:Blue">uniqueidentifier</span><span style="color:Gray">;
</span><span style="color:Blue">exec</span><span style="color:Black">&nbsp;usp_AsyncExecInvoke&nbsp;N</span><span style="color:Red">'usp_MyFaultyProcedure'</span><span style="color:Gray">,</span><span style="color:Black">&nbsp;@token&nbsp;</span><span style="color:Blue">output</span><span style="color:Gray">;
</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;</span><span style="color:Gray">*</span><span style="color:Black">&nbsp;</span><span style="color:Blue">from</span><span style="color:Black">&nbsp;[AsyncExecResults]&nbsp;</span><span style="color:Blue">where</span><span style="color:Black">&nbsp;[token]&nbsp;</span><span style="color:Gray">=</span><span style="color:Black">&nbsp;@token</span><span style="color:Gray">;
</span><span style="color:Black">go

</span><span style="color:Blue">waitfor</span><span style="color:Black">&nbsp;</span><span style="color:Blue">delay</span><span style="color:Black">&nbsp;</span><span style="color:Red">'00:00:10'</span><span style="color:Gray">;
</span><span style="color:Blue">select</span><span style="color:Black">&nbsp;</span><span style="color:Gray">*</span><span style="color:Black">&nbsp;</span><span style="color:Blue">from</span><span style="color:Black">&nbsp;[AsyncExecResults]</span><span style="color:Gray">;
</span><span style="color:Black">go</span>
</pre>
<h3>Activation Context</h3>
<p>If you check the start time of the second asynchronosuly executed procedure you will notice that it started right after the first one finished. This is because we declare a <tt>max_queue_readers</tt> value of 1 when we set up activation on the queue. This restricts that at most one activated procedure to run at any time, effectively serializing all the asynchronously executed procedures. Whether this is desired or not depends a lot on the actual usage scenario. The limit can be increased as necessary.</p>
<p>If you start playing around with this method of invoking procedures asynchronously you will notice that sometimes the asynchrnously executed procedure is misteriously denied access to other databases or to server scoped objects. When the same procedure is run manually from a query window in SSMS, it executes fine. This is caused by the EXECUTE AS context under which activation occurs. the details are explained in MSDN&#8217;s <a href="http://msdn.microsoft.com/en-us/library/ms188304.aspx" target="_blank">Extending Database Impersonation by Using EXECUTE AS</a> and myself I had covered this subject repeatedly in this blog. The best solution is to simply turn the trustworthy bit on on the database where the activated procedure runs. When this is not desired, or not allowed by your hosting environment, the solution is to code sign the activated procedure: <a href="http://rusanu.com/2006/03/01/signing-an-activated-procedure/">Signing an activated procedure</a>.</p>
<p>Using Service Broker Activation to invoke procedures asynchronously may look daunting at beginning. It sure is significantly more complex than just calling BeginExecuteNonQuery. But what needs to be understood is that this is a <strong>reliable</strong> way to invoke the procedure. The client is free to disconnect as soon as it commited the call to <tt>usp_AsyncExecInvoke</tt>. The procedure invoked <i>will</i> run, even if the server is stopped and restarted, even if a mirroring or clustering failover occurs. The server may even crash and be completely rebuilt. As soon as the database is back online, that queue will activate and invoke the asynchronous execution. Such level of reliability is difficult, if not impossible, to guarantee by using a client process.</p>
]]></content:encoded>
			<wfw:commentRss>http://rusanu.com/2009/08/05/asynchronous-procedure-execution/feed/</wfw:commentRss>
		</item>
		<item>
		<title>MySpace Uses SQL Server Service Broker to Protect Integrity of 1 Petabyte of Data</title>
		<link>http://rusanu.com/2009/07/26/myspace-uses-sql-server-service-broker-to-protect-integrity-of-1-petabyte-of-data/</link>
		<comments>http://rusanu.com/2009/07/26/myspace-uses-sql-server-service-broker-to-protect-integrity-of-1-petabyte-of-data/#comments</comments>
		<pubDate>Sun, 26 Jul 2009 07:42:27 +0000</pubDate>
		<dc:creator>remus</dc:creator>
		
		<category><![CDATA[Announcements]]></category>

		<category><![CDATA[myspace]]></category>

		<category><![CDATA[perfromance]]></category>

		<category><![CDATA[scalability]]></category>

		<category><![CDATA[service broker]]></category>

		<category><![CDATA[white paper]]></category>

		<guid isPermaLink="false">http://rusanu.com/?p=497</guid>
		<description><![CDATA[Copyright Remus Rusanu 2010. Visit the original article at http://rusanu.com/2009/07/26/myspace-uses-sql-server-service-broker-to-protect-integrity-of-1-petabyte-of-data/&#160;&#160;I just found that Microsoft has published a use case about the way MySpace is using Service Broker on their service as the core message delivery system for the Service Dispatcher. We&#8217;re talking here 440 SQL Server instances and over 1000 databases. Quote from the use [...]]]></description>
			<content:encoded><![CDATA[<p>Copyright Remus Rusanu 2010. Visit the original article at <a href="http://rusanu.com/2009/07/26/myspace-uses-sql-server-service-broker-to-protect-integrity-of-1-petabyte-of-data/">http://rusanu.com/2009/07/26/myspace-uses-sql-server-service-broker-to-protect-integrity-of-1-petabyte-of-data/</a></p>&nbsp;&nbsp;<br><p>I just found that Microsoft has published <a href="http://www.microsoft.com/casestudies/Case_Study_Detail.aspx?CaseStudyID=4000004532" target="_blank">a use case about the way MySpace is using Service Broker</a> on their service as the core message delivery system for the <i>Service Dispatcher</i>. We&#8217;re talking here 440 SQL Server instances and over 1000 databases. Quote from the use case:</p>
<p><em>Service Broker has enabled MySpace to perform foreign key management across its 440 database servers, activating and deactivating accounts for its millions of users, with one-touch asynchronous efficiency. MySpace also uses Service Broker administratively to distribute new stored procedures and other updates across all 440 database servers through the Service Dispatcher infrastructure.</em>
<p>That is pretty impressive. I knew about the MySpace SSB adoption since the days when I was with the Service Broker team. You probably all know my mantra I repeat all the time &#8220;don&#8217;t use <a href="http://rusanu.com/2006/04/06/fire-and-forget-good-for-the-military-but-not-for-service-broker-conversations/">fire and forget</a>, is a bad message exchange pattern and there are scenarios when the database may be taken offline&#8221;? Guess how I found out those &#8217;scenarios&#8217;&#8230; Anyway, I&#8217;m really glad that they also made public some performance numbers. Until now I could only quote the 5000 message per second I can push in my own test test environment. Well, looks like MySpace has some beefier hardware:</p>
<p><em>Stelzmuller: “When we went to the lab we brought our own workloads to ensure the quality of the testing. We needed to see if Service Broker could handle loads of 4,000 messages per second. Our testing found it could handle more than <strong>18,000 messages a second</strong>.&#8221;</em></p>
]]></content:encoded>
			<wfw:commentRss>http://rusanu.com/2009/07/26/myspace-uses-sql-server-service-broker-to-protect-integrity-of-1-petabyte-of-data/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
