Reputation: 61
I'm new to a company that makes heavy use of stored procedures (500+). To help learn the system, I was hoping there was an easy way to build a tree type list that shows all stored procedures in the system and which stored procedures they themselves call...thus creating a map of the stored procedures that could be executed. Is there an easy way to do this via a query in SQL Server? Is there a tool/utility that can do this?
For example, I want to see the following type of list without having to painstakingly try and follow the logic in each procedure and manually make a list.
build_house
-->pour_foundation
-->order_cement_truck
-->frame_house
-->hire_workers
-->buy_nails_and_hammers
-->wire_house
-->hire_electricians
-->check_certifications
-->test_wiring
The only thing I've found searching so far is:
http://www.codeproject.com/Articles/10019/Find-Stored-Procedures-called-within-a-procedure
To be clear, I'm looking to pass in / select a stored procedure name and have returned to me all of the stored procedures that it calls/uses.
@JackLock, I downloaded and installed SQL Search, but I don't see how this solves my problem. This tool aids in searching for stored procedures by name, or searching for text in stored procedures, but how does it help me automatically list out all stored procedures that are called from within a particular stored procedure? Maybe I'm missing something? For example, in my example above, I want the ability to run a system query or tool that returns me a list of the stored procedures that are called by whatever stored procedure name I pass it. So in the example, if I give the query or tool "build_house" it returns me the results in the example.
EDIT/UPDATE:
OK, I'd like to try and solve this with a query but need some help. I "think" what I want to do is query the sys.procedures to get the name of all the stored procedures in my system. Once I have them, I want to then pass them into the following query to determine how many stored procedures get called from it:
SELECT referenced_entity_name
FROM sys.dm_sql_referenced_entities (@ProcName, 'OBJECT')
Where @ProcName would get passed in for each row returned by the call to sys.procedures.
What is the most efficient way to do this in t-sql (2008)?
Thanks in advance, Michael
Upvotes: 5
Views: 31694
Reputation: 580
I know it's being along time since the question, however I think I found a workaround for this purpose and I want to share it, I've used an Aaron's Bertrand function to find a pattern within a text and this way of sorting,
Function :
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
);
Final query:
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
;
Feel free to use it as you wish.
Upvotes: 0
Reputation: 543
You can Enter the particular Procedure name in the below code and check, you will get the particular procedure used in others or not
SELECT OBJECT_NAME(id)
FROM syscomments
WHERE [text] LIKE '% procedure_or_function_name %'
GROUP BY OBJECT_NAME(id)
Upvotes: 8
Reputation: 1168
You have not mentioned which version of SQL Server you are working on. But there is a free utility (actually SSMS addin) by RedGate called SQL Search. I have it working on SSMS 2005,2008,R2 and 2012
It should solve your problem.
Upvotes: 1