<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www2.sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Adam Machanic : SQL Server 2005</title><link>http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/SQL+Server+2005/default.aspx</link><description>Tags: SQL Server 2005</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>[New England] Kalen Delaney Internals and Query Tuning - in the Boston area October 12-16</title><link>http://www2.sqlblog.com/blogs/adam_machanic/archive/2009/07/23/new-england-kalen-delaney-internals-and-query-tuning-in-the-boston-area-october-12-16.aspx</link><pubDate>Thu, 23 Jul 2009 14:16:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:15439</guid><dc:creator>Adam Machanic</dc:creator><slash:comments>1</slash:comments><comments>http://www2.sqlblog.com/blogs/adam_machanic/comments/15439.aspx</comments><wfw:commentRss>http://www2.sqlblog.com/blogs/adam_machanic/commentrss.aspx?PostID=15439</wfw:commentRss><description>In case you missed Kalen's post , we're excited to announce that she will be joining us here on the East Coast in October to deliver her SQL Server 2005/2008 Internals and Query Tuning seminar. This is, to my knowledge, the most advanced public SQL Server...(&lt;a href="http://www2.sqlblog.com/blogs/adam_machanic/archive/2009/07/23/new-england-kalen-delaney-internals-and-query-tuning-in-the-boston-area-october-12-16.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://www2.sqlblog.com/aggbug.aspx?PostID=15439" width="1" height="1"&gt;</description><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/Query+Tuning/default.aspx">Query Tuning</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/sql+server+2008/default.aspx">sql server 2008</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/New+England/default.aspx">New England</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/boston/default.aspx">boston</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/training/default.aspx">training</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/kalen+delaney/default.aspx">kalen delaney</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/internals/default.aspx">internals</category></item><item><title>Replacing xp_execresultset in SQL Server 2005</title><link>http://www2.sqlblog.com/blogs/adam_machanic/archive/2006/10/19/replacing-xp-execresultset-in-sql-server-2005.aspx</link><pubDate>Thu, 19 Oct 2006 14:13:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:314</guid><dc:creator>Adam Machanic</dc:creator><slash:comments>8</slash:comments><comments>http://www2.sqlblog.com/blogs/adam_machanic/comments/314.aspx</comments><wfw:commentRss>http://www2.sqlblog.com/blogs/adam_machanic/commentrss.aspx?PostID=314</wfw:commentRss><description>SQL Server 2000 included a very useful extended stored procedure called &lt;i&gt;xp_execresultset&lt;/i&gt;. This XP had two parameters: &lt;i&gt;@cmd&lt;/i&gt; and &lt;i&gt;@dbname&lt;/i&gt;.
@cmd was expected to be a SELECT statement that would produce a single
column of output, each row of which would produce a valid query.
@dbname was used to specify the database that both the initial query
and the resultant queries would be executed in.&lt;br&gt;&lt;br&gt;For example:&lt;br&gt;&lt;br&gt;&lt;pre class="code"&gt;EXEC xp_execresultset &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @cmd=N'SELECT ''SELECT 1''', &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @dbname=N'tempdb'&lt;/pre&gt;&lt;br&gt;&lt;br&gt;In
this case, tempdb would be used to execute the statement SELECT
''SELECT 1''. This statement produces a single row with the value
SELECT 1, which is then executed in tempdb. The final output is a
single result set containing the value 1.&lt;br&gt;&lt;br&gt;Multi-row statements are also allowed:&lt;br&gt;&lt;br&gt;&lt;pre class="code"&gt;EXEC xp_execresultset &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @cmd=N'SELECT ''SELECT 1'' UNION ALL SELECT ''SELECT 2''', &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @dbname=N'tempdb'&lt;/pre&gt;&lt;br&gt;
&lt;br&gt;In this case, the initial SELECT produces two rows, each with its
own statement. Then each row is processed as an individual query,
thereby producing two single-row result sets, one with the value 1, and
one with the value 2.&lt;br&gt;&lt;br&gt;We can verify that the first statement is run in the specified database by using the DB_ID() function in the outer query:&lt;br&gt;&lt;br&gt;&lt;pre class="code"&gt;USE master&lt;br&gt;&lt;br&gt;EXEC xp_execresultset &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @cmd=N'SELECT ''SELECT ''+CONVERT(NVARCHAR, DB_ID())', &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @dbname=N'tempdb'&lt;/pre&gt;&lt;br&gt;&lt;br&gt;In this case the end result is 2, indicating that the outer query was run in tempdb rather than master.&lt;br&gt;&lt;br&gt;So
now that I've covered xp_execresultset's usage in SQL Server 2000, the
bad news: this XP, although quite useful in many cases, has been
removed in SQL Server 2005. This was pointed out&amp;nbsp; to me by a post today
in the MSDN forums by Marko B. Simic (thanks, Marko!)&lt;br&gt;&lt;br&gt;The
solution, luckily, is pretty simple: We can re-create this XP as a
stored procedure in SQL Server 2005, using a few tricks to make the job
easier. Following is the replacement stored procedure I've come up with:&lt;br&gt;&lt;br&gt;&lt;pre class="code"&gt;CREATE PROC ExecResultSet&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @cmd NVARCHAR(MAX),&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @dbname NVARCHAR(255)&lt;br&gt;AS&lt;br&gt;BEGIN&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SET NOCOUNT ON&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DECLARE @x TABLE&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; sql NVARCHAR(MAX),&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; num INT IDENTITY(1,1)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DECLARE @input_sql NVARCHAR(355)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SET @input_sql = N'EXEC ' + @dbname + '..sp_executesql @stmt=@cmd'&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; INSERT @x (sql)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; EXEC sp_executesql &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; @input_sql, &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; N'@cmd NVARCHAR(MAX)', &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; @cmd&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DECLARE @sql NVARCHAR(MAX)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT @sql =&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT sql + ';' AS [data()]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; FROM @x&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ORDER BY num&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; FOR XML PATH('')&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; EXEC sp_executesql &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; @input_sql, &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; N'@cmd NVARCHAR(MAX)', &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; @sql&lt;br&gt;END&lt;br&gt;GO&lt;/pre&gt;&lt;br&gt;&lt;br&gt;Note
that I've tried to faithfully reproduce the original functionality of
xp_execresultset. This means that the resultant rows are concatenated
and executed as a single batch. This can be good in some cases -- for
instance, your first row can contain some variable declarations that
will be used by later rows. However, this can also cause problems if
you need to declare a variable on a per-row basis.&lt;br&gt;&lt;br&gt;This stored
procedure is fairly simple: It executes the input @cmd, concatenates
the resultant rows, and finally executes everything as a single batch.
Its syntax is identical to the original XP. Modifying this stored
procedure to make it a bit more flexible and execute each row as its
own batch is a simple matter of using a cursor to take each row
individually, rather than employing the FOR XML PATH concatenation
trick. However, I'm going to leave it as-is for now so that it can be
used directly in places where you would have used xp_executesql
previously.&lt;br&gt;&lt;img src="http://www2.sqlblog.com/aggbug.aspx?PostID=314" width="1" height="1"&gt;</description><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/Scripts/default.aspx">Scripts</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category></item></channel></rss>