Find Column dependency
Try this query, it will get you some results that i think you are looking for.
To filter, search for the value in the c1.name or c2.name column.
To look for all the references to a certain column, use the c2.name for the column name and the OBJECT_NAME(k.referenced_object_id) as the table which holds the c2 column :)
Good Luck!
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'
@NoFuchsGavin's script usually works great but has some limitations due to issues with sysdepends
(see this blog post by Pinal Dave for an example where this gives incorrect results).
Microsoft also suggest that you avoid using sysdepends
in new development work.
We can therefore use sys.dm_sql_referencing_entities
and sys.dm_sql_referenced_entities
as suggested here.
However I've noticed that this sometimes excludes column references due to referenced_minor_name
being NULL. I've therefore added another condition which can introduce false positives but ensures that column references are not omitted from the result set.
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 'SP' THEN 'Security policy'
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
Above script is based on @NoFuchsGavin's answer and this blog post.
I'm interested to know if anyone has managed to find a better way which does not introduce false negatives or positives.