Найти зависимость столбца

Как найти объекты, которые зависят от конкретного столбца таблицы.

Пример:

Таблица: SomeTable

Cols: col1 pk, col2, col3

Я хочу найти все объекты, которые зависят от col1 (Pk)

Ответ 1

Попробуйте этот запрос, он даст вам некоторые результаты, которые, я думаю, вы ищете.
Чтобы фильтровать, выполните поиск значения в столбце c1.name или c2.name.
Чтобы найти все ссылки на определенный столбец, используйте имя c2.name для имени столбца и OBJECT_NAME (k.referenced_object_id) в качестве таблицы, которая содержит столбец c2:)

Удачи!


    select  OBJECT_NAME(k.parent_object_id) as parentTable
          , c1.name as parentColumn
          , OBJECT_NAME(k.referenced_object_id) as referencedTable
          , c2.name as referencedColumn
    from    sys.foreign_keys k
            inner join sys.foreign_key_columns f
              on  f.parent_object_id = k.parent_object_id
              and f.constraint_object_id = k.object_id
            inner join sys.columns c1
              on  c1.column_id = f.parent_column_id
              and c1.object_id = k.parent_object_id
            inner join sys.columns c2
              on  c2.column_id = f.referenced_column_id
              and c2.object_id = k.referenced_object_id
    where   c2.name = 'Column'
    and     OBJECT_NAME(k.referenced_object_id) = 'Table'

Ответ 2

Это должно сработать!

        -- Search in All Objects
SELECT OBJECT_NAME(OBJECT_ID),definition
FROM sys.sql_modules
WHERE definition LIKE '%' + 'ColumnToBeSearched' + '%'
Order by 1
GO

-- Search in Stored Procedure Only
SELECT DISTINCT OBJECT_NAME(OBJECT_ID),
object_definition(OBJECT_ID)
FROM sys.Procedures
WHERE object_definition(OBJECT_ID) LIKE '%' + 'ColumnToBeSearched' + '%'
GO

Ответ 3

Просто замените {0} и {1}!

declare @tbl_nme as varchar(50)
declare @col_nme as varchar(50)
declare @level int
set @level = 1
set @tbl_nme= '{0}' --TableName 
set @col_nme= '{1}' --ColumnName 



select 
  obj.name as obj_nm
, col.name as col_nm
, depobj.name as dep_obj_nm
, CASE depobj.type
     WHEN 'C' THEN 'CHECK constraint'
     WHEN 'D' THEN 'Default'
     WHEN 'F' THEN 'FOREIGN KEY'
     WHEN 'FN' THEN 'Scalar function' 
     WHEN 'IF' THEN 'In-lined table-function'
     WHEN 'K' THEN 'PRIMARY KEY'
     WHEN 'L' THEN 'Log'
     WHEN 'P' THEN 'Stored procedure'
     WHEN 'R' THEN 'Rule'
     WHEN 'RF' THEN 'Replication filter stored procedure'
     WHEN 'S' THEN 'System table'
     WHEN 'TF' THEN 'Table function'
     WHEN 'TR' THEN 'Trigger'
     WHEN 'U' THEN 'User table' 
     WHEN 'V' THEN 'View' 
     WHEN 'X' THEN 'Extended stored procedure'
  END as dep_obj_type 
, null as dep_col_nm
, depobj.type as dep_obj_typeID
, @level as level
into #temp
from   sysobjects obj 
   join   syscolumns col on obj.id = col.id 
   left   join (sysdepends dep join sysobjects depobj on depobj.id = dep.id) 
         on obj.id = dep.depid 
        and col.colid = dep.depnumber 
where  obj.name = @tbl_nme
   and col.name = @col_nme


while (@@rowcount > 0)
begin
set @level = @level + 1
insert into #temp
select 
  obj.name as obj_nm
, col.name as col_nm
, depobj.name as dep_obj_nm
, CASE depobj.type
     WHEN 'C' THEN 'CHECK constraint'
     WHEN 'D' THEN 'Default'
     WHEN 'F' THEN 'FOREIGN KEY'
     WHEN 'FN' THEN 'Scalar function' 
     WHEN 'IF' THEN 'In-lined table-function'
     WHEN 'K' THEN 'PRIMARY KEY'
     WHEN 'L' THEN 'Log'
     WHEN 'P' THEN 'Stored procedure'
     WHEN 'R' THEN 'Rule'
     WHEN 'RF' THEN 'Replication filter stored procedure'
     WHEN 'S' THEN 'System table'
     WHEN 'TF' THEN 'Table function'
     WHEN 'TR' THEN 'Trigger'
     WHEN 'U' THEN 'User table' 
     WHEN 'V' THEN 'View' 
     WHEN 'X' THEN 'Extended stored procedure'
  END as dep_obj_type 
, null as dep_col_nm
, depobj.type as dep_obj_typeID
, @level as level
from   sysobjects obj 
   join   syscolumns col on obj.id = col.id 
   left   join (sysdepends dep join sysobjects depobj on depobj.id = dep.id) 
         on obj.id = dep.depid 
        and col.colid = dep.depnumber 
where  exists(select 1 from #temp a where obj.name = a.dep_obj_nm and 
col.name = a.dep_col_nm and level = @level - 1 and dep_col_nm is not null)
end

select 
   obj_nm AS 'TABLE',
   col_nm AS 'COLUMN',
   dep_obj_nm AS 'USAGE_OBJECT',
   dep_obj_type AS 'USAGE_OBJECTTYPE',
   dep_obj_typeID AS 'USAGE_OBJECTTYPEID'
from #temp
drop table #temp

Ответ 4

@NoFuchsGavin script обычно отлично работает, но имеет некоторые ограничения из-за проблем с sysdepends (см. этот пост в блоге Pinal Dave для примера, где это дает неверные результаты).

Microsoft также позволяют избежать использования sysdepends в новых разработках.

Поэтому мы можем использовать sys.dm_sql_referencing_entities и sys.dm_sql_referenced_entities как предложено здесь.

Однако я заметил, что это иногда исключает ссылки столбцов, поскольку referenced_minor_name имеет значение NULL. Поэтому я добавил другое условие, которое может ввести ложные срабатывания, но гарантирует, что ссылки на столбцы не будут опущены из набора результатов.

DECLARE @SchemaName sysname = '{0}';
DECLARE @TableName sysname  = '{1}';
DECLARE @ColumnName sysname = '{2}';

SELECT
    @SchemaName + '.' + @TableName                                      AS [USED_OBJECT],
    @ColumnName                                                         AS [COLUMN],
    referencing.referencing_schema_name + '.' + referencing_entity_name AS USAGE_OBJECT,
    CASE so.type
        WHEN 'C' THEN 'CHECK constraint'
        WHEN 'D' THEN 'Default'
        WHEN 'F' THEN 'FOREIGN KEY'
        WHEN 'FN' THEN 'Scalar function' 
        WHEN 'IF' THEN 'In-lined table-function'
        WHEN 'K' THEN 'PRIMARY KEY'
        WHEN 'L' THEN 'Log'
        WHEN 'P' THEN 'Stored procedure'
        WHEN 'R' THEN 'Rule'
        WHEN 'RF' THEN 'Replication filter stored procedure'
        WHEN 'S' THEN 'System table'
        WHEN 'TF' THEN 'Table function'
        WHEN 'TR' THEN 'Trigger'
        WHEN 'U' THEN 'User table' 
        WHEN 'V' THEN 'View' 
        WHEN 'X' THEN 'Extended stored procedure'
    END                                             AS USAGE_OBJECTTYPE,
    so.[type]                                       AS USAGE_OBJECTTYPEID
FROM sys.dm_sql_referencing_entities
    (
        @SchemaName + '.' + @TableName,
        'object'
    ) referencing
    INNER JOIN sys.objects so 
        ON referencing.referencing_id = so.object_id
WHERE
    EXISTS
    (
        SELECT
            *
        FROM
            sys.dm_sql_referenced_entities
            (
                referencing_schema_name + '.' + referencing_entity_name,
                'object'
            ) referenced
        WHERE
            referenced_entity_name = @TableName
            AND 
            (
                referenced.referenced_minor_name LIKE @ColumnName   
                -- referenced_minor_name is sometimes NULL
                -- therefore add below condition (can introduce False Positives)
                OR
                (
                    referenced.referenced_minor_name IS NULL 
                    AND 
                    OBJECT_DEFINITION
                    (
                         OBJECT_ID(referencing_schema_name + '.' + referencing_entity_name)
                    ) LIKE '%' + @ColumnName + '%'
                )
            )
    )
ORDER BY
    USAGE_OBJECTTYPE,
    USAGE_OBJECT

Выше script основан на ответе @NoFuchsGavin и этот пост в блоге.

Мне интересно узнать, удалось ли кому-либо найти лучший способ, который не вводит ложные негативы или положительные результаты.

Ответ 5

В sql, представленном в принятом ответе выше, должно быть добавлено дополнительное условие соединения между sys.foreign_keys и sys.foreign_key_columns. См. Строку, начинающуюся с "и" ниже:

from    sys.foreign_keys k
        inner join sys.foreign_key_columns f
          on  f.parent_object_id = k.parent_object_id
               and f.constraint_object_id = k.object_id

Для справки, здесь весь script с измененным соединением:

select  OBJECT_NAME(k.parent_object_id) as parentTable
        , c1.name as parentColumn
        , OBJECT_NAME(k.referenced_object_id) as referencedTable
        , c2.name as referencedColumn
from    sys.foreign_keys k
        inner join sys.foreign_key_columns f
            on  f.parent_object_id = k.parent_object_id
            and f.constraint_object_id = k.object_id
        inner join sys.columns c1
            on  c1.column_id = f.parent_column_id
            and c1.object_id = k.parent_object_id
        inner join sys.columns c2
            on  c2.column_id = f.referenced_column_id
            and c2.object_id = k.referenced_object_id
where   c2.name = 'GUID'
and     OBJECT_NAME(k.referenced_object_id) = 'AuthDomain'

Ответ 6

Попробуйте: Это даст все имена объектов, которые ссылаются на Pk вашей таблицы.

select  OBJECT_NAME(parent_object_id) from sys.foreign_keys where referenced_object_id = OBJECT_ID('YourTableName')

Ответ 7

Это должно сделать трюк:

SELECT OBJECT_NAME (referencing_id), referencing_id, referenced_id 
FROM  sys.sql_expression_dependencies d
WHERE OBJECT_NAME(d.referenced_id) = '<TABLE_NAME>'
      AND OBJECT_DEFINITION(referencing_id) = '<COLUMN_NAME>';

источник: http://www.mssqltips.com/sqlservertip/2999/different-ways-to-find-sql-server-object-dependencies/

или, чтобы показать все зависимости от таблицы, используйте

EXEC sp_depends <TABLE_NAME>

источник: https://msdn.microsoft.com/en-us/library/ms189487.aspx

Ответ 8

Найти определенные зависимости столбцов

SELECT OBJECT_NAME(referencing_id),
    referenced_database_name,
    referenced_schema_name,
    referenced_entity_name
FROM sys.sql_expression_dependencies
WHERE OBJECT_NAME(referenced_id) = 'table_name'
    AND OBJECT_DEFINITION(referencing_id) LIKE '%field_name%';