【问题标题】:SQL Server: Find Stored Procedures called within a procedureSQL Server:查找在过程中调用的存储过程
【发布时间】:2012-09-17 18:59:05
【问题描述】:

我是一家大量使用存储过程 (500+) 的公司的新手。为了帮助学习系统,我希望有一种简单的方法来构建一个树类型列表,该列表显示系统中的所有存储过程以及它们自己调用的存储过程......从而创建一个可以执行的存储过程的映射.有没有一种简单的方法可以通过 SQL Server 中的查询来做到这一点?有没有可以做到这一点的工具/实用程序?

例如,我想看到以下类型的列表,而不必费力地尝试遵循每个过程中的逻辑并手动制作列表。

build_house
  -->pour_foundation
    -->order_cement_truck
  -->frame_house
    -->hire_workers
    -->buy_nails_and_hammers
  -->wire_house
    -->hire_electricians
      -->check_certifications
    -->test_wiring

到目前为止,我发现的唯一内容是:

http://www.codeproject.com/Articles/10019/Find-Stored-Procedures-called-within-a-procedure

明确地说,我希望传入/选择一个存储过程名称,并将它调用/使用的所有存储过程返回给我。

@JackLock,我下载并安装了 SQL Search,但我不明白这如何解决我的问题。此工具有助于按名称搜索存储过程,或搜索存储过程中的文本,但它如何帮助我自动列出从特定存储过程中调用的所有存储过程?也许我错过了什么?例如,在我上面的示例中,我希望能够运行一个系统查询或工具,它返回一个存储过程列表,这些存储过程由我传递给它的任何存储过程名称调用。因此,在示例中,如果我提供查询或工具“build_house”,它将返回示例中的结果。

编辑/更新:

好的,我想尝试通过查询来解决这个问题,但需要一些帮助。我“认为”我想要做的是查询 sys.procedures 以获取系统中所有存储过程的名称。获得它们后,我想将它们传递给以下查询,以确定从中调用了多少存储过程:

SELECT referenced_entity_name
FROM sys.dm_sql_referenced_entities (@ProcName, 'OBJECT')

@ProcName 将为调用 sys.procedures 返回的每一行传入哪里。

在 t-sql (2008) 中执行此操作的最有效方法是什么?

提前致谢, 迈克尔

【问题讨论】:

  • 这个问题解决了吗?如果是的话,你能解决这个问题吗?

标签: sql sql-server stored-procedures


【解决方案1】:

您可以在下面的代码中输入特定的过程名称并检查,您将得到其他人使用的特定过程

SELECT OBJECT_NAME(id) 
FROM syscomments 
WHERE [text] LIKE '% procedure_or_function_name %' 
GROUP BY OBJECT_NAME(id)

【讨论】:

    【解决方案2】:

    您没有提到您正在使用哪个版本的 SQL Server。但是 RedGate 有一个免费的实用程序(实际上是 SSMS 插件),名为 SQL Search。 我让它在 SSMS 2005、2008、R2 和 2012 上工作

    应该可以解决你的问题。

    【讨论】:

    • 我使用的是 SQL Server 2008。我没有意识到 RedGate 有任何免费工具。我去看看。谢谢!
    • @MichaelLeone 对不起,我误解了您的要求。我的印象是您正在寻找一种工具/脚本,该工具/脚本可让您搜索特定的 DB 对象(在您的情况下为 SP)并显示正在使用该对象的位置列表。
    • @MichaelLeone 一个快速的谷歌让我得到了这两个网站..By Linchi SheaBy Chad Miller。我希望这可以帮助你。
    【解决方案3】:

    我知道这个问题已经存在了一段时间,但是我想我找到了一个解决方法,我想分享它,我使用了 Aaron 的 Bertrand 函数在文本中查找模式以及这种@ 987654321@,

    功能:

    CREATE FUNCTION dbo.FindPatternLocation
    (
        @string NVARCHAR(MAX),
        @term   NVARCHAR(255)
    )
    RETURNS TABLE
    AS
        RETURN 
        (
          SELECT pos = Number - LEN(@term) 
          FROM 
          (
            SELECT Number, Item = LTRIM(RTRIM(SUBSTRING(@string, Number, CHARINDEX(@term, @string + @term, Number) - Number)))
            FROM (
                    SELECT ROW_NUMBER() OVER (ORDER BY [object_id])
                    FROM sys.all_columns) AS n(Number)
                WHERE Number > 1 AND Number <= CONVERT(INT, LEN(@string)+1)
            AND SUBSTRING(@term + @string, Number, LEN(@term)) = @term
            ) 
            AS y
        );
    

    最终查询:

    declare @object_name varchar(1000) = 'stored_procedure_name'
    ; 
    with cte as ( 
        SELECT o.name AS parent_object_name
        , SUBSTRING( m.definition, rs_fn.pos+4, CHARINDEX( ' ' , stuff( m.definition, 1, rs_fn.pos + 4 , '' )) ) as child_object
        , cast(row_number()over(partition by o.object_id order by o.name) as varchar(max)) as [path]
        , 0 as level
        , row_number()over(partition by o.object_id order by o.name) / power(10.0,0) as x
        FROM sys.sql_modules m 
        INNER JOIN sys.objects o ON m.object_id = o.object_id 
        cross apply ( 
            select * 
            from dbo.FindPatternLocation( m.definition, 'EXEC ' ) as res
        ) as rs_fn
        WHERE 1=1
        and o.name like @object_name
        union all 
        SELECT o.name AS parent_object_name
        , SUBSTRING( m.definition, rs_fn.pos+4, CHARINDEX( ' ' , stuff( m.definition, 1, rs_fn.pos + 4 , '' ))  ) as child_object
        , [path] +'-'+ cast(row_number()over(partition by o.object_id order by o.name) as varchar(max))
        , level+1 
        , c.x + row_number()over(partition by o.object_id order by o.name) / power(10.0,level+1)
        FROM sys.sql_modules m 
        INNER JOIN sys.objects o ON m.object_id = o.object_id 
        inner join cte c on c.child_object = o.name
        cross apply ( 
            select * 
            from dbo.FindPatternLocation( m.definition, 'EXEC ' ) as res
        ) as rs_fn
        WHERE 1=1
        -- and o.name like @object_name
    ) 
    
    select * from cte 
    order by x
    ; 
    

    随意使用它。

    【讨论】:

      猜你喜欢
      • 2010-09-13
      • 1970-01-01
      • 2011-12-19
      • 1970-01-01
      • 2012-02-10
      • 1970-01-01
      • 2018-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多