查视图依赖基表应优先使用sys.sql_expression_dependencies,它记录创建/修改时的解析快照,不受对象存在性、跨库或架构前缀影响;字段级依赖需用sys.dm_sql_referenced_entities,严格按三段式名称调用;ssms“查看依赖关系”和sys.dm_exec_describe_first_result_set不可靠,动态sql引用只能扫描sys.sql_modules.definition。

查视图依赖的基表:用 sys.sql_expression_dependencies 读编译快照
直接查 sys.sql_expression_dependencies 是唯一可靠起点,它记录的是视图创建/修改时 SQL Server 实际解析出的依赖快照,不依赖对象是否还存在、是否跨库、是否带架构前缀。
关键点:
-
referencing_id是视图的OBJECT_ID('YourViewName'),referenced_id对应基表(或视图、函数)的 object_id - 若
referenced_id为 NULL 或 0,说明引用未解析成功——常见于跨库(如OtherDB.dbo.TableX)、表名拼接、或被引用对象已被删 - 此时必须看
referenced_database_name、referenced_schema_name、referenced_entity_name这三个字段,它们保留了原始定义里的四部分名信息 - 修改视图后,该视图不会自动刷新;必须手动执行
sp_refreshsqlmodule 'YourViewName'或重建视图,否则依赖关系滞后
查视图字段来自哪些基表列:用 sys.dm_sql_referenced_entities
sys.sql_expression_dependencies 只到对象粒度,无法告诉你 ViewColA 是从 TableB.ColX 还是 TableC.ColY 来的。这时必须用 sys.dm_sql_referenced_entities,它会实际解析表达式树。
调用方式很严格:
- 第一个参数必须是三段式名称:
'dbo.YourViewName',不能只写'YourViewName',也不能加数据库名 - 第二个参数固定为字符串字面量
'OBJECT',大小写不敏感但不能是变量 - 结果中
is_ambiguous = 1是危险信号——比如同名列在多个 JOIN 表里都存在,SQL Server 无法唯一确定来源 - 它能处理
SELECT *、CTE、窗口函数、计算列等现代语法,但对动态 SQL(EXEC('SELECT * FROM ' + @t))仍无能为力
别信 SSMS “查看依赖关系” 和 sys.dm_exec_describe_first_result_set
SSMS 右键菜单里的“查看依赖关系”底层调用的是过时逻辑,遇到以下情况基本失效:
- 视图用了
SELECT *,它可能漏掉新增字段对应的基表列 - 有同义词、跨库引用、非架构绑定视图,它常返回空或错误分类
- 动态 SQL 或
IF分支逻辑,它只推导某一分支,且不报错提示
sys.dm_exec_describe_first_result_set 和它的变体 sys.dm_exec_describe_first_result_set_for_object 完全不是为查依赖设计的——它们只描述结果集结构,不解析源对象。遇到 Msg 11522(引用不存在对象)、条件分支、动态拼接时,要么报错,要么返回片面结果。
字符串拼接类引用只能扫 sys.sql_modules.definition
如果视图里写了 EXEC('SELECT * FROM ' + @tbl) 或 sp_executesql 动态拼表名,所有系统视图都抓不到。这时候只能人工扫描:
- 查
sys.sql_modules中该视图的definition字段 - 用
CHARINDEX或正则(SQL Server 2016+ 支持STRING_SPLIT配合模式匹配)提取疑似表名 - 注意区分真实引用和字符串字面量(比如
WHERE name = 'OrderView'不是引用视图) - 这类引用永远无法被系统自动跟踪,必须靠代码规范或额外工具(如静态分析脚本)补位
真正麻烦的不是查不到,而是查到的依赖关系本身不可靠——比如 sys.sql_expression_dependencies 记录了 A → B → C,但 B 已被改名或删掉,而你没跑 sp_refreshsqlmodule,那看到的仍是旧快照。生产环境改视图前,先刷新再查,不是可选项。











