【问题标题】:How can i check sql server 'views' dependencies我如何检查 sql server 'views' 依赖项
【发布时间】:2011-02-03 17:48:32
【问题描述】:

有没有一种方法可以让我使用自定义查询或存储过程找出视图正在使用哪些基表?

【问题讨论】:

  • 这与.net无关,仅与SQL server有关。标签有点误导:)

标签: sql-server tsql sql-server-2005 views


【解决方案1】:

您可以在 SQL-Server >= 2008 (R1+) 中使用 sys.sql_expression_dependencies 来做到这一点
注意:这需要 30 秒或更长时间。

如果您想要视图,删除标量 + 表值函数(“FN”和“IF”)。

表值函数可以是视图的依赖项,反之亦然,另外,视图/tvf 可能依赖于标量函数。

;WITH TFV_Dependencies AS 
(
    SELECT 
         --OBJECT_SCHEMA_NAME(sysdep.referencing_id) AS Referencing_Schema 
         ReferencingO.object_id AS ReferencingObject_Id 
        ,sysschema.name AS Referencing_Schema 
        ,ReferencingO.name AS Referencing_Object_Name 
        ,sysdep.referenced_schema_name AS Referenced_Schema 
        ,sysdep.referenced_entity_name AS Referenced_Object_Name 
        --,ReferencingO.type
        ,ReferencedO.name AS RefName 
        --,ReferencedO.type AS RefType
    FROM sys.objects as ReferencingO 

    LEFT JOIN sys.schemas AS sysschema 
        ON sysschema.schema_id = ReferencingO.schema_id 

    LEFT JOIN sys.sql_expression_dependencies AS sysdep 
    LEFT JOIN sys.objects as ReferencedO 
        ON ReferencedO.name = sysdep.referenced_entity_name 
        ON sysdep.referencing_id = ReferencingO.object_id 
        AND ReferencingO.name <> sysdep.referenced_entity_name 
        --AND ReferencedO.type <> 'U' 
        AND ReferencedO.type IN ( 'IF', 'FN', 'V' ) 

    WHERE (1=1) 
    --AND ReferencingO.type NOT IN ('PK','F','UQ','SQ','D','IT', 'S')
    --AND ReferencingO.type IN ( 'U', 'V', 'FN', 'IF', 'P') 
    AND ReferencingO.type IN ( 'IF', 'FN', 'V' ) 
    AND ReferencingO.name NOT IN 
    (
         'dt_adduserobject'
        ,'dt_droppropertiesbyid'
        ,'dt_dropuserobjectbyid'
        ,'dt_generateansiname'
        ,'dt_getobjwithprop'
        ,'dt_getobjwithprop_u'
        ,'dt_getpropertiesbyid'
        ,'dt_getpropertiesbyid_u'
        ,'dt_setpropertybyid'
        ,'dt_setpropertybyid_u'
        ,'dt_verstamp006'
        ,'dt_verstamp007'

        ,'sp_helpdiagrams'
        ,'sp_creatediagram'
        ,'sp_alterdiagram'
        ,'sp_renamediagram'
        ,'sp_dropdiagram'

        ,'sp_helpdiagramdefinition'
        ,'fn_diagramobjects'
    ) 

) 

,DependencyGroup AS 
( 
    -- base case 
    SELECT 
         ReferencingObject_Id AS ObjectId 
        ,Referencing_Object_Name AS ObjectName  
        ,Referencing_Schema AS ObjectSchema 
        ,1 AS Lvl 
    FROM TFV_Dependencies 
    WHERE 1=1 
    AND Referenced_Object_Name IS NULL 

    -- recursive case
    UNION ALL 

   SELECT 
         d.ReferencingObject_Id AS ObjectId 
        ,d.Referencing_Object_Name AS ObjectName 
        ,d.Referencing_Schema AS ObjectSchema 
        ,r.Lvl + 1 AS Lvl 
    FROM TFV_Dependencies AS d 
    INNER JOIN DependencyGroup AS r 
        ON r.ObjectName = d.Referenced_Object_Name 
) 
,
CTE AS 
(
    SELECT TOP 999999999999999999 
         MAX(Lvl) AS Lvl 
        ,ObjectId 
        ,ObjectSchema
        ,ObjectName 
        --,'DELETE FROM [' + REPLACE(ObjectName, '''', '''''') + ']; ' AS DeleteCmd 
    FROM DependencyGroup 

    GROUP BY ObjectId, ObjectSchema, ObjectName 
)

SELECT 
     CTE.Lvl
    ,CTE.ObjectSchema AS SPECIFIC_SCHEMA 
    ,CTE.ObjectName AS SPECIFIC_NAME 
    ,sysSqlModules.definition AS ROUTINE_DEFINITION 
FROM CTE 

LEFT JOIN sys.sql_modules AS sysSqlModules 
    ON sysSqlModules.object_id = CTE.ObjectId 

ORDER BY Lvl, ObjectSchema, ObjectName 

OPTION (MAXRECURSION 0) 

【讨论】:

    【解决方案2】:

    您可以使用 sys.dm_sql_referenced_entities 函数来查找指定视图引用的对象:

    SELECT DISTINCT 
    referenced_schema_name , 
    referenced_entity_name 
    FROM sys.dm_sql_referenced_entities ('Sales.vSalesPersonSalesByFiscalYears', 'OBJECT');
    

    此外,还有 sys.sql_expression_dependencies 系统视图,您可以在其中指定表名和引用对象的类型:

    SELECT 
    referencing_object_name = o.name, 
    referencing_object_type_desc = o.type_desc 
    FROM sys.sql_expression_dependencies se 
    INNER JOIN sys.objects o 
    ON se.referencing_id = o.[object_id] 
    WHERE referenced_entity_name = 'Person' AND o.type_desc = 'View'
    

    为避免“手动”工作,您还可以使用ApexSQL Clean,这是一个可以查找所有内部和外部依赖项的 SQL Server 工具。在结果窗格中选择一个对象并查看依赖于所选对象的所有对象,以及所选对象所依赖的对象:

    您还可以过滤对象并可视化依赖关系:

    免责声明:我作为支持工程师在 ApexSQL 工作

    希望对你有帮助

    【讨论】:

      【解决方案3】:

      如果这是您经常做的事情,Red Gate SQL Dependency Tracker(不,我不为他们工作)是一个很棒的工具。如果您想尝试,我认为他们有试用期。

      【讨论】:

        【解决方案4】:

        您可以使用sql_dependencies 视图:

        select OBJECT_NAME(referenced_major_id) as DependantObject
        from sys.sql_dependencies
        where object_id = object_id('YourViewName')
        

        递归检索依赖项(例如,如果您从一个视图中选择,这将找到另一个视图引用的表):

        with deps (child, parent) as (
            select d.object_id, d.referenced_major_id
            from sys.sql_dependencies d
            where d.object_id = object_id('YourViewName')
            union all
            select d.object_id, d.referenced_major_id
            from sys.sql_dependencies d
            inner join deps on deps.parent = d.object_id
        )
        select OBJECT_NAME(parent)
        from deps
        

        此方法并非万无一失。例如,如果您使用 sp_rename 重命名对象,则不会更新其依赖关系。

        【讨论】:

        • 我运行这个时没有得到任何结果
        • 在我的机器上运行良好。也许您可以发布视图的定义?
        • 是的,它仅适用于我创建的视图,但对于其他开发人员创建的其他视图(我有权访问)我得到 0 条记录。
        • 如果其他开发人员创建的视图在另一个模式中,请尝试限定视图名称,如where d.object_id = object_id('OtherDevSchema.OtherDevView')
        • 仔细检查一下,你知道模式和数据库之间的区别吗?语法为database.schema.object,例如MyDb.MySchema.MyView
        【解决方案5】:

        【讨论】:

        • 创建并运行该 sp 时没有得到任何结果
        猜你喜欢
        • 1970-01-01
        • 2010-09-22
        • 2010-10-29
        • 1970-01-01
        • 2011-11-30
        • 2012-10-21
        • 1970-01-01
        • 2014-03-27
        • 2013-11-26
        相关资源
        最近更新 更多