SQL Server数据库中所有依赖项的树

pur*_*rum 11 database sql-server parsing text

我必须维护一个没有文档的旧项目,并且有一个包含许多表和函数以及存储过程的数据库.我想在表和存储过程之间构建一个依赖关系树,例如,此过程执行这些过程并使用这些表.

  1. 有没有什么工具可以帮助我

  2. 如果没有,这种算法的起点是什么?我的意思是我可以从数据库中获取所有过程的源代码,然后解析所有'exec#','update#','insert into#'等等.在这种情况下,解决这个问题的最佳方法是什么(正则表达式,或者一些特殊算法......)?

sql*_*ger 11

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
Run Code Online (Sandbox Code Playgroud)

  • 应该是改变 so.type in ('P', 'V', 'IF', 'FN', 'TF', 'U') 和 ( rso.type 为 null 或 rso.type in ( ' P', 'V', 'IF', 'FN', 'TF', 'U' ) ) 到 so.type in ( 'P', 'V', 'IF', 'FN', 'TF' , 'U', 'TR') 和 ( rso.type 为 null 或 rso.type in ( 'P', 'V', 'IF', 'FN', 'TF', 'U', 'TR' ) ) (2认同)

Die*_*ego 7

有像redgate这样的付费工具,但如果你愿意,你可以随时右键单击一个对象并选择"查看依赖关系".


Hig*_*ian 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
Run Code Online (Sandbox Code Playgroud)


Joh*_*020 5

您可以使用如下所示的sys.dm_sql_referenced_entities来获取任何对象的所有依赖项

SELECT * FROM sys.dm_sql_referenced_entities('dbo.myStoredProcedure', 'OBJECT')