【问题标题】:Tree of all dependencies in a SQL Server databaseSQL Server 数据库中所有依赖项的树
【发布时间】:2012-05-26 00:50:12
【问题描述】:

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

  1. 有什么工具可以帮到我

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

【问题讨论】:

    标签: sql-server database parsing text


    【解决方案1】:

    有像 redgate 这样的付费工具,但如果需要,您可以随时右键单击对象并选择“查看依赖项”。

    【讨论】:

    • 查看依赖项看起来很棒。并且知道我在谷歌上可以从 sys.sql_dependencies 中获得它,并使用“令人惊叹的”GUI 创建我自己的工具,只是为了好玩。非常感谢!
    【解决方案2】:

    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
    

    【讨论】:

    • 这太棒了。是否也可以检查触发器的依赖关系?
    • 应该是改变so.type in ('P', 'V', 'IF', 'FN', 'TF', 'U') and (rso.type is null 或 rso.type in ('P', 'V', 'IF', 'FN', 'TF', 'U') 到 where so.type in ('P', 'V', 'IF' , 'FN', 'TF', 'U', 'TR') 和 ( rso.type 为 null 或 rso.type in ('P', 'V', 'IF', 'FN', 'TF', 'U', 'TR' ) )
    【解决方案3】:

    有人提到了 Redgate 的付费插件。 ApexSQL 是另一家为 SQL Server 制作附加组件的公司。其中一些需要花钱,但其他一些是免费的,仍然非常有用。

    ApexSQL 搜索 是免费的搜索之一。它的两个主要特点是:

    1. 允许您在数据库的数据或结构中搜索特定文本。
    2. 可以为一个或多个对象(您想要的)构建依赖关系的图形树。

    安装后,只需右键单击一个对象或数据库,然后单击View dependencies(靠近底部,旁边有一个图标)。不要将它与View Dependencies(靠近顶部,旁边没有图标)混淆,它是 SQL Server 中内置的。我发现层次图布局是最有用的。

    链接:

    【讨论】:

    • 很高兴尝试这个,但似乎依赖项查看器功能自 2018 年 7 月版本起现已停用。
    • 不幸的是,他们已将这些功能移至非免费工具ApexSQL Analyze
    【解决方案4】:

    这里,max(level) 应该可以解决您的问题而无需外部工具

    ;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
    

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

        猜你喜欢
        • 2021-01-27
        • 2010-09-22
        • 1970-01-01
        • 2014-03-27
        • 1970-01-01
        • 2012-03-27
        • 1970-01-01
        • 2018-06-19
        • 1970-01-01
        相关资源
        最近更新 更多