<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://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>Search results matching tags 'Tools' and 'Scripting'</title><link>http://sqlblog.com/search/SearchResults.aspx?o=DateDescending&amp;tag=Tools,Scripting&amp;orTags=0</link><description>Search results matching tags 'Tools' and 'Scripting'</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Find the complete call tree for a stored procedure</title><link>http://sqlblog.com/blogs/linchi_shea/archive/2009/10/22/find-the-complete-call-tree-for-a-stored-procedure.aspx</link><pubDate>Fri, 23 Oct 2009 03:11:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:18173</guid><dc:creator>Linchi Shea</dc:creator><description>&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;Would it be nice to print out the complete call tree of a stored procedure? By &lt;I style="mso-bidi-font-style:normal;"&gt;complete call tree&lt;/I&gt;, I mean the following:&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt 0.5in;TEXT-INDENT:-27pt;tab-stops:.5in;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-FAMILY:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;At the very top level, the call tree should identify all the procedures that are called directly.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt 0.5in;TEXT-INDENT:-27pt;tab-stops:.5in;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-FAMILY:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;For any given level, the next level of the call tree should identify all the procedures called by the procedures at the current level.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt 0.5in;TEXT-INDENT:-27pt;tab-stops:.5in;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-FAMILY:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;If a procedure calls another procedure on a different server via a linked server, that call should be identified on the call tree.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt 0.5in;TEXT-INDENT:-27pt;tab-stops:.5in;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-FAMILY:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol;"&gt;&lt;SPAN style="mso-list:Ignore;"&gt;&lt;FONT size=3&gt;·&lt;/FONT&gt;&lt;SPAN style="FONT:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;The leaf level identifies the procedures that do not call any other procedure.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;In other words, the procedure call tree should recursively identify all the dependent procedures that are called either directly or indirectly regardless whether they are on the same instance or a different instance.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;I don’t know whether there is any tool out there that would print out such a procedure call tree. But this is not a trivial task if you want to be 100% complete. For instance, if another procedure is called through a piece of dynamic SQL, all bets are off. In that case, what is called will not be known until the run time when the dynamic SQL is executed. That is beyond the reach of any static code analysis.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;Another difficulty is that there is no rigorous T-SQL parser that is publicly available you can use to shred the code of a stored procedure to find all the stored procedure calls. Using a rigorous and efficient T-SQL parser would have been the ideal way to accomplish this task.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;Fortunately, as long as we are not talking about looking for all the dependencies including called procedures, views, tables, and so on, we can manage to get the procedure call tree with a little bit of regular expressions on the fact a stored procedure is always called with an EXECUTE statement. Although there are syntactic variations, it is rather straightforward to single out all the EXECUTE statements in a piece of T-SQL code, and then parse for the stored procedure names being called.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;The attached Perl script does exactly that. If you want to find out what are being called by a procedure, say, p_MyGreatProc in database myDB on server NYSQL, you can run the Perl script as follows:&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;cmd&amp;gt;perl spCallTree.pl NYSQL.myDB.myOwner.p_Foo &amp;gt; callTree.log&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;Yes, the script is written to demand a four-part procedure name on the command line on purpose so as to remove any ambiguity, and all the stored procedures in the output are presented in the four-part format for the same reason. &lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;An example of the logged output callTree.log may look like the following:&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;NYSQL.myDB.myOwner.p_Foo =&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;'NYSQL.db1.dbo.p_Foo1' =&amp;gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;'NYSQL.db2.dbo.p_Foo2' =&amp;gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;'PASQL.db1.dbo.p_Foo3' =&amp;gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;'CASQL.db2.dbo.sp_executesql' =&amp;gt; undef&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;},&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;'NJSQL.db3.dbo.sp_executesql' =&amp;gt; undef&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;},&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;'NYSQL.db.dbo.sp_executesql' =&amp;gt; undef&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;},&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;'NYSQL.db1.dbo.p_Foo4' =&amp;gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;'NYSQL.db2.dbo.p_Foo5' =&amp;gt; undef,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;'NJSQL.db2.dbo.p_Foo6' =&amp;gt; undef&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND:#e6e6e6;MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11pt;FONT-FAMILY:'Courier New';"&gt;};&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;In this example, p_Foo calls several procedures directly or indirectly across a bunch of servers, including NYSQL, NJSQL, PASQL, and CASQL, and &lt;I style="mso-bidi-font-style:normal;"&gt;undef&lt;/I&gt; signifies that the procedure does not call any other procedure. So for instance, in the above output, NYSQL.myDB.myOwner.p_Foo calls NYSQL.db1.dbo.p_Foo1, which in turn calls NYSQL.db2.dbo.p_Foo2, which in turn calls PASQL.db1.dbo.p_Foo3, which in turns calls CASQL.db2.dbo.sp_executesql.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;In the case of sp_executesql, more procedures may be called inside the dynamic SQL string executed by sp_executesql. But since we can’t evaluate the string, the script does not look further, and simply points it to undef. In case of EXECUTE on a dynamic SQL string variable, the output will simply identify the variable just in case you want to examine it further. &lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;The Perl script callTree.pl finds out the call tree by scanning the code of the top most procedure for any EXECUTE statement after it has removed all the comments and quoted strings. Well, you would not want to include any reference to EXECUTE mentioned in a comment block, right? For each EXECUTE statement, it parses for the name of the procedure being called, including all the four parts (if necessary). It calls sp_helptext to get the code for the called procedure, and then scans the code for any EXECUTE statement. And this continues recursively until no more procedures are called.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT face="Times New Roman" size=3&gt;I wrote this script fairly quickly as a throw-away script, but have used it many times. I can’t claim that it’s bug free, but so far has worked fine. You do need to have Perl on your machine to run the script. I’ve been using it with Perl v5.10.0, binary release 1003. You can download the latest release of ActivePerl from &lt;/FONT&gt;&lt;A href="http://www.activestate.com/activeperl/"&gt;&lt;FONT face="Times New Roman" color=#606420 size=3&gt;ActiveState&lt;/FONT&gt;&lt;/A&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;. &lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;If you need to debug a production issue that involves a procedure makes nested procedure calls with some of the calls going across liked servers, you would appreciate the need to see the complete call tree, and therefore, the utility of this little Perl script.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;I have seen a fair amount of cross-server nested procedure calls, and they are simply nasty. I definitely have better things to do than manually find out which calls which and where. I’m sure you too. So hopefully you’ll find this little script useful.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;And if you have a better or a different way&amp;nbsp;of printing out the complete call tree for a procedure, let me know.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoList3 style="MARGIN:0in 0in 0pt;TEXT-INDENT:0in;tab-stops:.5in;mso-list:none;"&gt;&lt;SPAN style="FONT-WEIGHT:normal;"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;</description></item></channel></rss>