sys.dm_exec_describe_first_result_set仅解析单查询元数据,不追踪跨对象引用,对视图依赖无效;查真实依赖应使用sys.sql_expression_dependencies,它准确记录显式引用关系,并支持递归展开。

SQL Server 中用 sys.dm_exec_describe_first_result_set 查依赖不准
这个函数只解析单个查询的元数据,不追踪跨对象引用,对视图依赖关系基本无效。它可能返回 NULL 或错误列名,尤其遇到嵌套视图、动态 SQL 或权限不足时。真正要查“哪些表/视图被某个视图用到了”,得换更底层的系统视图。
用 sys.sql_expression_dependencies 查直接依赖最可靠
这是 SQL Server 2008+ 提供的专用依赖跟踪视图,记录了对象间显式引用关系(如 SELECT * FROM dbo.Customers)。它比旧的 sysdepends 更准确,且不受绑定延迟影响。
查所有用户视图及其依赖对象的典型写法:
SELECT v.name AS view_name, d.referenced_entity_name AS referenced_name, d.referenced_schema_name AS referenced_schema, d.referenced_class_desc AS referenced_type FROM sys.views v INNER JOIN sys.sql_expression_dependencies d ON d.referencing_id = v.object_id WHERE d.referenced_class IN (1, 2) -- 1=object, 2=type;排除参数、XML schema 等干扰项 AND d.is_selected = 1; -- 只取 SELECT 中实际用到的引用(非 WHERE/JOIN 条件里隐含的)
注意点:
-
is_selected = 1很关键,否则会把JOIN条件中未出现在SELECT列表里的列也计入,造成误报 - 该视图不包含间接依赖(比如 View A → View B → Table C,它只返回 A→B 和 B→C,不会自动展开 A→C)
- 若目标对象被重命名或删除,
referenced_id为NULL,但名称仍保留在referenced_entity_name中
递归查询能跑出完整依赖链,但要注意性能和循环引用
用 CTE 递归展开依赖时,必须限制层级(如 MAXRECURSION 10),否则遇到视图互相引用(A→B→A)会死循环。示例:
WITH deps AS (
SELECT
v.object_id,
v.name AS view_name,
d.referenced_id,
d.referenced_entity_name,
d.referenced_schema_name,
1 AS level
FROM sys.views v
INNER JOIN sys.sql_expression_dependencies d
ON d.referencing_id = v.object_id
WHERE d.referenced_class = 1
<p>UNION ALL</p><p>SELECT
d2.referencing_id,
OBJECT_NAME(d2.referencing_id),
d2.referenced_id,
d2.referenced_entity_name,
d2.referenced_schema_name,
d.level + 1
FROM sys.sql_expression_dependencies d2
INNER JOIN deps d ON d2.referencing_id = d.referenced_id
WHERE d2.referenced_class = 1
AND d.level < 10
)
SELECT DISTINCT * FROM deps
OPTION (MAXRECURSION 10);这种写法容易漏掉跨数据库引用(referenced_database_name 非空时需额外处理),也查不到通过 EXEC 或 sp_executesql 调用的动态对象。
PostgreSQL 或 MySQL 用户别套用这套逻辑
PostgreSQL 没有等价的 sql_expression_dependencies,得靠 pg_depend + pg_rewrite 解析规则树,复杂度高很多;MySQL 8.0+ 的 INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS 只管外键,视图依赖得从 INFORMATION_SCHEMA.VIEWS 的 VIEW_DEFINITION 字段里正则提取表名——不可靠,且无法识别别名或带 schema 的引用。
依赖分析这事,SQL Server 做得最实,但也只覆盖静态、显式、已解析过的引用。真要 100% 掌握影响范围,还是得结合代码扫描 + 实际执行计划验证。

















