Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Find Stored Procedures called within a procedure

0.00/5 (No votes)
25 Apr 2005 1  
Sometimes its tedious to find all calls made to different stored procedures within a stored procedure and generate reports in case we have large databases. This tool is aimed to script all SPs and extract SP calls made with additional information such as author name and description.

Last Updated on 26-04-'05.

Introduction

It's tedious to find all calls made to all SP from a stored procedure and generating reports in case we have large databases, this tool is aimed to script all Sp's and extracts SP calls, it also strips out additional information such as author name and description.

Image shows Application in progress...

Application in Acton , Stored Proc Call Search

Screen Shot of results

We all use stored procedures extensively to place business logic in development. Most of the time, the calling of a Stored Procedure is well defined in proper documents / other details.

Say, what if we need to find out as to how many calls a stored procedure makes to another procedure or which of the stored procedures are called by UI / other layer and not by the SQL SPs.

I tried to answer this problem by creating an application which will fetch the SQL metadata (for a given database) and will script entire SP list..

We can aim to extract information in four different phases:

  • Extract information from DataSource (enter info in UI-textbox).
  • Create formatted DataSet from the Source.
  • Extract relevant information and update DataSet.
  • Present the DataSet via XSLT.

In SQL Server, we can extract relevant information from DB via INFORMATION_SCHEMA objects.

select Routine_Name , Routine_Definition, '' as 'DESCRIPTION', 
       '' as 'AUTHOR', '' as 'AUTHOR_Class', '' as 'DESCRIPTION_Class' 
       from information_schema.routines where Routine_Type='procedure'

We can format the DataSet by creating relations and adding rows to it.

dtCol = New DataColumn("ID", System.Type.GetType("System.Int32"))
dtCol.AutoIncrement = True
dtCol.AutoIncrementSeed = 1
dtCol.AutoIncrementStep = 1
dtChild.Columns.Add(dtCol)
dtCol = New DataColumn("Calling_SP", System.Type.GetType("System.String"))
dtChild.Columns.Add(dtCol)
dtCol = New DataColumn("Called_SP", System.Type.GetType("System.String"))
dtChild.Columns.Add(dtCol)
ds.Tables.Add(dtChild)
ds.EnforceConstraints = False
Dim drRel As DataRelation
drRel = ds.Relations.Add("SP-LINK", ds.Tables(0).Columns("Routine_Name"), 
ds.Tables(1).Columns("Calling_SP"), False)
drRel.Nested = True

Extracting relevant information is parameterized, and can be placed in application configuration file for customization. This is a sample code to extract stored procedure description:

Function GetDesc(ByVal strInput As String) As String
        Dim objMatch As Match
        Dim objRegEx = New Regex( _
            strDESCRIPTIONREGEX, _
            RegexOptions.IgnoreCase _
            Or RegexOptions.Multiline _
            Or RegexOptions.Compiled _
            )
        Dim strRetVal As String = ""
        objMatch = objRegEx.Match(strInput)
        If objMatch.Success Then
            strRetVal = objMatch.Groups(0).Value.ToUpper()
            strRetVal = strRetVal.Replace("  ", " ").Trim()
        End If
        Return strRetVal
End Function

Similarly, we can remove comments for extracting calls by this code:

Function GetPureText(ByVal strInput As String) As String
  Dim objMatch As Match
  Dim strRetVal As String = ""
  strRetVal = Regex.Replace(strInput, "/\*[\w\W]*?\s*\*/", "", _
     RegexOptions.IgnoreCase Or RegexOptions.Multiline Or 
     RegexOptions.Compiled)
  Return strRetVal
End Function

Please note that the configurations (regular expressions) are stored in application configuration file. The below code shows the function snippet which strips the SP calls:

 dr("DESCRIPTION") = GetDesc(strSPText).Trim
  dr("AUTHOR") = GetAUTH(strSPText).Trim
  dr("AUTHOR_Class") = IIf(Convert.ToString(dr("AUTHOR")) = "", _
           "Blank", "MyClass")
  dr("DESCRIPTION_Class") = IIf(Convert.ToString(dr("DESCRIPTION")) = "", _
           "Blank", "MyClass")
  strSPText = GetPureText(strSPText)
  '(exec[\w\W]*?)(m[\w\W]*?)(@|\s+)

  '(exec[\w\W]*?)(m|s[\w\W]*?)(@|\s+)

  strSPREGEX = strSPREGEX.Replace("@@@LETTER@@@", txtLetter.Text)
  objMatchCol = GetMatchedCollection(strSPText, strSPREGEX)
  For Each matchObj In objMatchCol

Now we have the formatted DataSet. Apply pre-defined XSLT and extract the report (Please see attached ZIP files for the same).

Code snippet:

Dim sb As StringBuilder = New StringBuilder()
Dim sw As StringWriter = New StringWriter(sb)
Dim dataDoc As XmlDataDocument = New XmlDataDocument(ds)
Dim transform As XslTransform = New XslTransform()
transform.Load(AppDomain.CurrentDomain.BaseDirectory & "transform.xslt")
transform.Transform(dataDoc, Nothing, sw)
If File.Exists(AppDomain.CurrentDomain.BaseDirectory & "MainReport.html") Then
  File.Delete(AppDomain.CurrentDomain.BaseDirectory & "MainReport.html")
End If
Dim swMain As StreamWriter
swMain = File.CreateText(AppDomain.CurrentDomain.BaseDirectory & "MainReport.html")

Please check the config file entry required for the application.

  <!-- (exec[\w\W]*?)(@@@LETTER@@@[\w\W]*?)(@|\s+) // for reference.  
  Here @@@LETTER@@@ will be the input Letter from Application 
  (this can also be ommited)  -->  
  <add key="SP_REGEX" value="(exec[\w\W]*?)(@@@LETTER@@@[\w\W]*?)(@|\s+)" />  
  <!--
  Author name Extraction, you can write ur own custom Author Extraction logic.
  -->
  <add key="AUTHOR_REGEX" value="(AUTHOR[\w\W]*?)(\n)" />
  <!--
  Description Extraction, you can write ur own custom Description Extraction logic.
  -->
  <add key="DESCRIPTION_REGEX" value="(DESCRIPTION[\w\W]*?)(\s*CHANGE HISTORY)" />

The application uses XML - XSLT to format the report, this helps in finding called stored procedures relatively and anchoring them in a nested call.

Below is an XSLT file extract:

<td valign='top' width='5%'>
     <font size="4">
      <b>
       <font size="1">SP Name: </font>
       <a>
        <xsl:attribute name="id">
         <xsl:value-of select="Routine_Name" />
        </xsl:attribute>
        <xsl:attribute name="Title">
         <xsl:value-of select="DESCRIPTION" />
        </xsl:attribute>
        <xsl:attribute name="name">
         <xsl:value-of select="Routine_Name" />
        </xsl:attribute>
        <xsl:attribute name="href">#<xsl:value-of select="Routine_Name" />
        </xsl:attribute>
        <xsl:value-of select="Routine_Name" />
       </a>
      </b>
     </font>
    </td>

The code here is of Visual Studio 2002.

You can get the formatted, relative-anchor based report for all stored proc in the selected database. Check out Brip Blog for more .NET / SQL Server kicks...... Join Our Group.

Recent Updates

  • Fixed size bug and now data is extracted from System tables instead of Information_schema.
  • Fixed XSLT bug.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here