Как я могу проверить зависимости sql сервера 'views' - PullRequest
6 голосов
/ 02 апреля 2010

Есть ли способ узнать, какие базовые таблицы используются представлениями с помощью пользовательского запроса или хранимой процедуры?

Ответы [ 5 ]

9 голосов
/ 16 июня 2014

Вы можете использовать функцию sys.dm_sql_referenced_entities, чтобы найти объекты, на которые ссылается указанное представление:

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

enter image description here

Также существует системное представление 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'

enter image description here

Чтобы избежать «ручной» работы, вы также можете использовать ApexSQL Clean , инструмент SQL Server, который может найти все внутренние и внешние зависимости. В области результатов выберите объект и просмотрите все объекты, которые зависят от выбранного объекта, а также объекты, от которых зависит выбранный объект:

enter image description here

Вы также можете фильтровать объекты и визуализировать зависимости:

enter image description here

Отказ от ответственности: я работаю в ApexSQL в качестве инженера службы поддержки

Надеюсь, это поможет

7 голосов
/ 02 апреля 2010

Вы можете использовать sql_dependencies view:

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 , его зависимости не будут обновлены.

2 голосов
/ 02 апреля 2010

Если это то, что вы будете делать часто, Red Gate SQL Dependency Tracker (нет, я не работаю для них) - отличный инструмент. Я думаю, у них есть пробный период, если вы хотите попробовать.

1 голос
/ 02 апреля 2010
0 голосов
/ 07 октября 2014

Вы можете сделать это, используя sys.sql_expression_dependencies в SQL-Server> = 2008 (R1 +)
Примечание. Это займет 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) 
...