我是一家大量使用存储过程(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搜索,但我看不出这是如何解决我的问题的。此工具有助于按名称搜索存储过程,或在存储过程中搜索文本,但它如何帮助我自动列出从特定存储过程中调用的所有存储过程?也许我错过了什么?例如,在上面的示例中,我希望能够运行系统查询或工具,它返回一个存储过程列表,该列表由我传递的任何存储过程名称调用。因此,在示例中,如果我给查询或工具“build_house”,它会返回示例中的结果。
EDIT / UPDATE:
好的,我想尝试用查询解决这个问题,但需要一些帮助。我“想”我想要做的是查询sys.procedures以获取我系统中所有存储过程的名称。一旦我拥有它们,我想将它们传递给以下查询以确定从中调用多少存储过程:
SELECT referenced_entity_name
FROM sys.dm_sql_referenced_entities (@ProcName, 'OBJECT')
对于调用sys.procedures返回的每一行,将传入@ProcName。
在t-sql(2008)中执行此操作的最有效方法是什么?
提前致谢, 迈克尔
答案 0 :(得分:8)
您可以在下面的代码中输入特定的程序名称并检查,您将获得其他人使用的特定程序
SELECT OBJECT_NAME(id)
FROM syscomments
WHERE [text] LIKE '% procedure_or_function_name %'
GROUP BY OBJECT_NAME(id)
答案 1 :(得分:1)
您还没有提到您正在使用的SQL Server版本。但RedGate有一个名为SQL Search的免费工具(实际上是SSMS插件)。 我有它在SSMS 2005,2008,R2和2012上工作
它应该可以解决你的问题。
答案 2 :(得分:0)
我知道问题提出以来已经很久了,但是我想我为此找到了一种解决方法,我想与他人分享,我使用了Aaron的Bertrand函数在文本中查找模式,并且使用{ {3}},
功能:
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
;
随意使用它。