我必须维护一个没有文档的旧项目,并且有一个包含大量表和函数以及存储过程的数据库。我想在表和存储过程之间构建一个依赖关系树,例如,这个过程执行这些过程并使用这些表。
是否有任何可以帮助我的工具
如果没有,这些算法的起点是什么?我的意思是我可以从数据库中获取所有过程的源代码,然后解析所有'exec#','update#','insert into#'等等。在这种情况下,解决这个问题的最佳方法是什么(可能是正则表达式,还是一些特殊的算法......)?
答案 0 :(得分:10)
Higarian,你的代码对我非常有用。我稍微改进了一下,以删除循环依赖,包括表引用,并按ObjectPath排序。
;with ObjectHierarchy ( Base_Object_Id , Base_Cchema_Id , Base_Object_Name , Base_Object_Type, object_id , Schema_Id , Name , Type_Desc , Level , Obj_Path)
as
( select so.object_id as Base_Object_Id
, so.schema_id as Base_Cchema_Id
, so.name as Base_Object_Name
, so.type_desc as Base_Object_Type
, so.object_id as object_id
, so.schema_id as Schema_Id
, so.name
, so.type_desc
, 0 as Level
, convert ( nvarchar ( 1000 ) , N'/' + so.name ) as Obj_Path
from sys.objects so
left join sys.sql_expression_dependencies ed on ed.referenced_id = so.object_id
left join sys.objects rso on rso.object_id = ed.referencing_id
where rso.type is null
and so.type in ( 'P', 'V', 'IF', 'FN', 'TF' )
union all
select cp.Base_Object_Id as Base_Object_Id
, cp.Base_Cchema_Id
, cp.Base_Object_Name
, cp.Base_Object_Type
, so.object_id as object_id
, so.schema_id as ID_Schema
, so.name
, so.type_desc
, Level + 1 as Level
, convert ( nvarchar ( 1000 ) , cp.Obj_Path + N'/' + so.name ) as Obj_Path
from sys.objects so
inner join sys.sql_expression_dependencies ed on ed.referenced_id = so.object_id
inner join sys.objects rso on rso.object_id = ed.referencing_id
inner join ObjectHierarchy as cp on rso.object_id = cp.object_id and rso.object_id <> so.object_id
where so.type in ( 'P', 'V', 'IF', 'FN', 'TF', 'U')
and ( rso.type is null or rso.type in ( 'P', 'V', 'IF', 'FN', 'TF', 'U' ) )
and cp.Obj_Path not like '%/' + so.name + '/%' ) -- prevent cycles n hierarcy
select Base_Object_Name
, Base_Object_Type
, REPLICATE ( ' ' , Level ) + Name as Indented_Name
, SCHEMA_NAME ( Schema_Id ) + '.' + Name as object_id
, Type_Desc as Object_Type
, Level
, Obj_Path
from ObjectHierarchy as p
order by Obj_Path
答案 1 :(得分:6)
有像redgate这样的付费工具,但如果你愿意,你可以随时右键单击一个对象并选择“查看依赖项”。
答案 2 :(得分:6)
此处,max(级别)应解决您的问题而无需外部工具
;WITH cte ( [ID] ,IDSchema,Nome,Tipo,level, SortCol)
AS (SELECT [so].[object_id] AS ID
,so.[schema_id],so.[name],so.[type]
,0 AS [Level]
,CAST ([so].[object_id] AS VARBINARY (MAX)) AS SortCol
FROM [sys].[objects] so
LEFT JOIN sys.sql_expression_dependencies ed ON [ed].[referenced_id]=[so].[object_id]
LEFT JOIN [sys].[objects] rso ON rso.[object_id]=[ed].referencing_id
--in my database, if i insert tables on the search, it gets more tham 100 levels of recursivity, and that is bad
WHERE [rso].[type] IS NULL AND [so].[type] IN ('V','IF','FN','TF','P')
UNION ALL
SELECT [so].[object_id] AS ID
,so.[schema_id],so.[name],so.[type]
,Level + 1
,CAST (SortCol + CAST ([so].[object_id] AS BINARY (4)) AS VARBINARY (MAX))
FROM [sys].[objects] so
INNER JOIN sys.sql_expression_dependencies ed ON [ed].[referenced_id]=[so].[object_id]
INNER JOIN [sys].[objects] rso ON rso.[object_id]=[ed].referencing_id
INNER JOIN cte AS cp ON rso.[object_id] = [cp].[ID]
WHERE [so].[type] IN ('V','IF','FN','TF','P')
AND ([rso].[type] IS NULL OR [rso].[type] IN ('V','IF','FN','TF','P'))
)
--CTE
SELECT ID, IDSchema,
REPLICATE(' ',level)+nome AS Nome,'['+SCHEMA_NAME(IDSchema)+'].['+nome+']' AS Object,Tipo,Level,SortCol
FROM cte AS p
ORDER BY sortcol
答案 3 :(得分:5)
您可以使用如下所示的sys.dm_sql_referenced_entities来获取任何对象的所有依赖项
SELECT
*
FROM
sys.dm_sql_referenced_entities('dbo.myStoredProcedure', 'OBJECT')
答案 4 :(得分:0)
有人提到了Redgate的付费插件。 ApexSQL是另一家为SQL Server制作附加组件的公司。其中一些花钱,但其他一些是免费的,但仍然非常有用。
ApexSQL Search 是免费的。它的两个主要特点是:
安装后,只需右键单击对象或数据库,然后单击View dependencies
(靠近底部,旁边有一个图标)。不要将它混淆为View Dependencies
(靠近顶部,旁边没有图标),这是SQL Server内置的。我发现层次图布局最有用。
<强>链接:强>