65.9K
CodeProject 正在变化。 阅读更多。
Home

查找存储过程内调用的存储过程

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (10投票s)

2005年4月5日

CPOL

2分钟阅读

viewsIcon

73077

downloadIcon

394

有时,在存储过程中查找对不同存储过程的所有调用,并在我们拥有大型数据库的情况下生成报告是一件繁琐的事情。 该工具旨在编写所有 SP 的脚本,并提取 SP 调用以及其他信息,例如作者姓名和描述。

上次更新于 2005 年 4 月 26 日。

引言

从存储过程查找对所有 SP 的所有调用并生成报告是一件繁琐的事情,尤其是在我们拥有大型数据库的情况下,该工具旨在编写所有 Sp 的脚本并提取 SP 调用,它还会删除其他信息,例如作者姓名和描述。

图像显示应用程序正在进行中...

Application in Acton , Stored Proc Call Search

Screen Shot of results

我们都广泛使用存储过程将业务逻辑置于开发中。 大多数情况下,存储过程的调用在正确的文档/其他详细信息中都有明确的定义。

假设,如果我们需要找出存储过程对另一个过程进行了多少次调用,或者 UI/其他层而不是 SQL SP 调用了哪些存储过程,该怎么办。

我尝试通过创建一个应用程序来回答这个问题,该应用程序将获取 SQL 元数据(对于给定的数据库)并编写整个 SP 列表的脚本。

我们可以致力于在四个不同的阶段提取信息

  • 从数据源提取信息(在 UI 文本框中输入信息)。
  • 从源创建格式化的 DataSet
  • 提取相关信息并更新 DataSet
  • 通过 XSLT 呈现 DataSet

在 SQL Server 中,我们可以通过 INFORMATION_SCHEMA 对象从 DB 提取相关信息。

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

我们可以通过创建关系并向其添加行来格式化 DataSet

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

提取相关信息是参数化的,可以放置在应用程序配置文件中进行自定义。 这是提取存储过程描述的示例代码

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

同样,我们可以通过此代码删除注释以提取调用

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

请注意,配置(正则表达式)存储在应用程序配置文件中。 下面的代码显示了去除 SP 调用的函数片段

 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

现在我们有了格式化的 DataSet。 应用预定义的 XSLT 并提取报告(请参阅附加的 ZIP 文件)。

代码片段

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

请检查应用程序所需的config文件条目。

  <!-- (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)" />

该应用程序使用 XML - XSLT 来格式化报告,这有助于相对地查找调用的存储过程并将它们锚定在嵌套调用中。

下面是一个 XSLT 文件提取

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

这里的代码是 Visual Studio 2002 的。

您可以获得所选数据库中所有存储过程的格式化、基于相对锚点的报告。 查看Brip Blog 了解更多 .NET / SQL Server 信息...... 加入 我们的群组

最新更新

  • 修复了大小错误,现在数据是从系统表而不是 Information_schema 中提取的。
  • 修复了 XSLT 错误。
© . All rights reserved.