<?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>Looping over routines using sp_foreachroutine</title><link>http://www2.sqlblog.com/blogs/adam_machanic/archive/2006/07/12/looping-over-routines-using-sp-foreachroutine.aspx</link><description>Of all of the undocumented stored procedures shipped with SQL Server, there are two in particular that I constantly use: sp_MSforeachtable and sp_MSforeachdb . These procedures internally loop over each non-Microsoft shipped (i.e. user-defined) table</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>re: Looping over routines using sp_foreachroutine</title><link>http://www2.sqlblog.com/blogs/adam_machanic/archive/2006/07/12/looping-over-routines-using-sp-foreachroutine.aspx#15112</link><pubDate>Mon, 06 Jul 2009 20:54:12 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:15112</guid><dc:creator>Adam Gojdas</dc:creator><description>&lt;p&gt;I have also modified the sp_MSforeach&amp;lt;db/table&amp;gt; procs a bit to be a bit safer to execute. &amp;nbsp;I felt that the global cursor used in each is a pretty dangerous way to go for these stored procs among other things that I fixed. &amp;nbsp;So I gave it the capability to create and use a local cursor dynamically. &amp;nbsp;Thus I won't see issues that will occur with the global cursor when/if the proc is run concurrently by same/different users. &amp;nbsp;It uses a global cursor most likely because it needs to create the cursor dynamically and that is the easiest way to achieve that. &amp;nbsp;It took a lot of trial and error for me to figure how to create a dynamic local cursor so I thought I might show the code of how to do that.&lt;/p&gt;
&lt;p&gt;So here is a code snippet of how to do this:&lt;/p&gt;
&lt;p&gt; &amp;nbsp; DECLARE @SQL &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;nvarchar(max);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;SET @SQL =&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; N'SET @my_cur = CURSOR FAST_FORWARD FOR ' &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; + N'SELECT ''['' + REPLACE(schema_name(syso.schema_id), N'']'', N'']]'') + '']'' + ''.'' + ''['' + REPLACE(object_name(o.id), N'']'', N'']]'') + '']'' '&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; + N' &amp;nbsp;FROM dbo.sysobjects o '&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; + N' &amp;nbsp;INNER JOIN sys.all_objects syso on o.id = syso.object_id '&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; + N' WHERE OBJECTPROPERTY(o.id, N''IsUserTable'') = 1 ' &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; + N' AND o.category &amp;amp; ' + @mscat + N' = 0 ';&lt;/p&gt;
&lt;p&gt; &amp;nbsp; IF @whereand IS NOT NULL BEGIN &amp;nbsp;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;SET @SQL = @SQL + @whereand;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; END;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; SET @SQL = @SQL + N'; OPEN @my_cur;';&lt;/p&gt;
&lt;p&gt; &amp;nbsp; DECLARE @local_cursor cursor&lt;/p&gt;
&lt;p&gt; &amp;nbsp; EXEC sp_executesql&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;@SQL&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; ,N'@my_cur cursor OUTPUT'&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; ,@my_cur = @local_cursor OUTPUT;&lt;/p&gt;
&lt;p&gt;	FETCH @local_cursor INTO @name;&lt;/p&gt;
&lt;p&gt;	WHILE (@@fetch_status &amp;gt;= 0) BEGIN&lt;/p&gt;
&lt;p&gt;	--&amp;lt;whatever other code&amp;gt;&lt;/p&gt;
&lt;p&gt;	FETCH @local_cursor INTO @name;&lt;/p&gt;
&lt;p&gt;	END /* WHILE FETCH_SUCCESS */&lt;/p&gt;
&lt;p&gt; &amp;nbsp; SET @curStatus = Cursor_Status('variable', '@local_cursor');&lt;/p&gt;
&lt;p&gt; &amp;nbsp; IF @curStatus &amp;gt;= 0 BEGIN&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;CLOSE @local_cursor;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;DEALLOCATE @local_cursor;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; END;&lt;/p&gt;
</description></item><item><title>re: Looping over routines using sp_foreachroutine</title><link>http://www2.sqlblog.com/blogs/adam_machanic/archive/2006/07/12/looping-over-routines-using-sp-foreachroutine.aspx#15117</link><pubDate>Tue, 07 Jul 2009 02:42:51 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:15117</guid><dc:creator>Adam Gojdas</dc:creator><description>&lt;p&gt;Upon looking over the code I see I never explicitly set the LOCAL option. &amp;nbsp;So maybe I just fooled myself into thinking it worked? &amp;nbsp;I will need to check the DB setting to see what it defaults to, local or global, and test what occurs when I specifically set it LOCAL.&lt;/p&gt;
&lt;p&gt;hope it works...&lt;/p&gt;
</description></item><item><title>re: Looping over routines using sp_foreachroutine</title><link>http://www2.sqlblog.com/blogs/adam_machanic/archive/2006/07/12/looping-over-routines-using-sp-foreachroutine.aspx#15118</link><pubDate>Tue, 07 Jul 2009 02:54:57 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:15118</guid><dc:creator>Adam Gojdas</dc:creator><description>&lt;p&gt;Made the change in the code to have explicitly set LOCAL:&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; N'SET @my_cur = CURSOR LOCAL FAST_FORWARD FOR ' &lt;/p&gt;
&lt;p&gt;Tested and it works. &amp;nbsp;So luckily the DB I had run this on defaulted to a local cursor when not explicitly setting this. &amp;nbsp;So as I mentioned earlier this way I think would be a safer implementation than using GLOBAL cursors.&lt;/p&gt;
</description></item><item><title>re: Looping over routines using sp_foreachroutine</title><link>http://www2.sqlblog.com/blogs/adam_machanic/archive/2006/07/12/looping-over-routines-using-sp-foreachroutine.aspx#30840</link><pubDate>Sun, 21 Nov 2010 02:47:08 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:30840</guid><dc:creator>sharif</dc:creator><description>&lt;p&gt;2 small problems, not sure if i am running the wrong version of SQL server.&lt;/p&gt;
&lt;p&gt;the sp_MSforeach_worker seem to refer to hCForEachDatabase (default) or hCForEachTable. so had to change the query to refer to the cursor as hCForEachDatabase.&lt;/p&gt;
&lt;p&gt;also got error &amp;quot;cursor operation because the set options have changed since the...&amp;quot; had to add set options as: &lt;/p&gt;
&lt;p&gt;... N' set ansi_nulls on ; set quoted_identifier off; declare hCForEachDatabase cursor global for...&lt;/p&gt;
&lt;p&gt;thanks for a very handy query&lt;/p&gt;
</description></item><item><title>re: Looping over routines using sp_foreachroutine</title><link>http://www2.sqlblog.com/blogs/adam_machanic/archive/2006/07/12/looping-over-routines-using-sp-foreachroutine.aspx#34868</link><pubDate>Wed, 13 Apr 2011 19:05:24 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:34868</guid><dc:creator>Roman</dc:creator><description>&lt;p&gt;Adam, as ever, a great article !!&lt;/p&gt;
&lt;p&gt;Roman&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_new" href="http://sqldata.blogspot.com"&gt;http://sqldata.blogspot.com&lt;/a&gt;&lt;/p&gt;
</description></item></channel></rss>