5

我是一家大量使用存储过程(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')

调用 sys.procedures 返回的每一行都会传入@ProcName。

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

在此先感谢,迈克尔

4

3 回答 3

8

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

SELECT OBJECT_NAME(id) 
FROM syscomments 
WHERE [text] LIKE '% procedure_or_function_name %' 
GROUP BY OBJECT_NAME(id)
于 2014-09-23T09:15:14.350 回答
1

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

它应该可以解决您的问题。

于 2012-09-17T19:04:10.263 回答
0

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

功能 :

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
; 

随意使用它。

于 2020-06-26T01:00:07.043 回答