应使用 sys.sql_expression_dependencies + sys.objects 查视图依赖,因其直接读取编译时记录的依赖快照;而 sys.dm_exec_describe_first_result_set 及其变体仅推导结果结构、不解析真实引用,遇 if 分支、跨库对象、动态 sql 等即失效。

不能用 sys.dm_exec_describe_first_result_set 查视图依赖的表,它只推导结果列结构,不解析真实引用关系。
为什么 sys.dm_exec_describe_first_result_set_for_object 不可靠
这个函数看似专为对象设计,但底层仍走执行计划预估路径。遇到以下情况就会失效:
- 视图里有
IF分支逻辑(比如IF @mode = 1 SELECT FROM t1 ELSE SELECT FROM t2),它只会返回某一分支的结果结构 - 引用了尚未创建的表或跨库对象(如
OtherDB.dbo.TableX),直接报错Msg 11522 - 含动态 SQL(
EXEC('SELECT * FROM ' + @tbl))时完全无法识别,返回空或错误 - 对 CTE、窗口函数、计算列等现代语法支持不稳定,依赖快照可能过期
正确做法:查 sys.sql_expression_dependencies + sys.objects
这是 SQL Server 2008+ 官方推荐路径,直接读取编译时记录的依赖快照。关键点:
-
referencing_id是视图的object_id,referenced_id是被引用表/视图的object_id - 若
referenced_id为NULL,说明对象不存在,或引用跨库——此时要查referenced_database_name、referenced_schema_name、referenced_entity_name - 修改视图定义后,
sys.sql_expression_dependencies不会自动刷新,必须手动执行sp_refreshsqlmodule 'YourViewName'或重建视图 - 不识别字符串拼接式引用(如
'SELECT * FROM ' + @t),这类只能扫sys.sql_modules.definition配合正则
常用查询示例:
SELECT
OBJECT_NAME(d.referencing_id) AS view_name,
ISNULL(OBJECT_NAME(d.referenced_id), d.referenced_entity_name) AS referenced_name,
d.referenced_class_desc,
d.referenced_database_name,
d.referenced_schema_name
FROM sys.sql_expression_dependencies d
WHERE d.referencing_id = OBJECT_ID('YourViewName')
AND d.referenced_class IN (1, 2); -- 1=object/column, 2=database
别再用 sysdepends —— 已废弃且结果不可信
sysdepends 自 SQL Server 2005 起就标记为“仅供向后兼容”,问题很多:
- 数据来自旧版编译缓存,不支持 CTE、
OFFSET-FETCH、同义词等新特性 - 对跨库引用常返回空,无法区分“直接依赖”和“间接依赖”(比如视图 A → 视图 B → 表 C,它可能把 C 直接列为 A 的依赖,跳过 B)
- 不处理
WITH SCHEMABINDING约束下的强绑定关系,容易漏掉关键约束依赖
真正要注意的是:依赖关系不是实时的,也不是静态拓扑图;它是一次性编译快照,且对动态构造、条件分支、未建对象等情况天然无感。如果你在做上线影响评估,务必结合 sp_refreshsqlmodule 主动刷新,并人工核对高风险视图里的字符串拼接和 IF 分支逻辑。










