查列级依赖必须用sys.dm_sql_referenced_entities而非sys.sql_expression_dependencies,因后者仅支持对象级依赖;调用时需指定'object'参数、带schema的完整对象名,且referenced_minor_id>0才表示列级引用。

查列级依赖不能只靠 sys.sql_expression_dependencies
这个视图只记录对象级依赖(比如“视图用了哪张表”),不存字段级信息。即使视图里写了 SELECT col_a, col_b FROM t1,sys.sql_expression_dependencies 也只会告诉你它依赖 t1,不会说具体用了 col_a。直接查它,字段名一概为空或不准确。
必须用 sys.dm_sql_referenced_entities 查字段引用
这是 SQL Server 唯一能精确到列的系统函数。它会解析视图定义,返回每一处被引用的表、列、甚至别名位置。关键点:
- 调用时第二个参数必须是
'OBJECT',不是'VIEW'或空字符串 - 第一个参数要带 schema,比如
'dbo.MyView',否则可能找不到 - 结果中
referenced_minor_id > 0才表示这是列级引用(0是表级) -
referenced_entity_name是列名,referenced_schema_name+referenced_entity_name是完整表名
示例:查所有引用了 customer_name 字段的视图
SELECT DISTINCT OBJECT_SCHEMA_NAME(d.referencing_id) AS view_schema, OBJECT_NAME(d.referencing_id) AS view_name FROM sys.sql_expression_dependencies d CROSS APPLY sys.dm_sql_referenced_entities( QUOTENAME(OBJECT_SCHEMA_NAME(d.referencing_id)) + '.' + QUOTENAME(OBJECT_NAME(d.referencing_id)), 'OBJECT' ) r WHERE d.referenced_class = 1 -- 表或视图 AND d.is_selected = 1 -- 确实出现在 SELECT 列表里(排除 WHERE/JOIN 中仅用于条件的列) AND r.referenced_minor_id > 0 AND r.referenced_entity_name = 'customer_name';
注意 SELECT * 和未绑定视图的陷阱
如果视图用了 SELECT * 或没加 WITH SCHEMABINDING,sys.dm_sql_referenced_entities 可能返回空或不全 —— 因为 SQL Server 在编译时无法静态确定列名。这种情况下,字段依赖其实是运行时才决定的,元数据层面根本不可靠。
- 有
WITH SCHEMABINDING的视图才能保证列级依赖可查 - 含
SELECT *的视图,得先用sp_helptext或OBJECT_DEFINITION()提取定义,再人工或正则扫描字段名(但要注意别名、子查询嵌套、注释干扰) - 系统函数对临时表、表变量、CTE 中的字段不返回任何记录
权限和执行上下文容易被忽略
sys.dm_sql_referenced_entities 要求对目标视图有 VIEW DEFINITION 权限;如果视图引用了其他数据库的对象,还得在那个库也有同等级权限。否则函数静默返回空结果,而不是报错 —— 这是最常被误判为“没依赖”的原因。
另外,该函数不支持跨数据库直接传三段式名称(如 db2.dbo.v1),必须切换到目标数据库上下文再查,或用动态 SQL 拼接 USE [db2]; SELECT ...。










