ssms右键“查看依赖关系”不可靠,应使用sys.sql_modules查视图定义、sys.sql_expression_dependencies查表级依赖、sys.dm_sql_referenced_entities查列级依赖,并注意动态sql、select*、未刷新等场景的失效问题。

不能只靠 SSMS 右键“查看依赖关系”——它在跨库、动态 SQL、SELECT * 场景下大概率漏报,甚至返回空结果。
查所有视图的定义:用 sys.sql_modules 而不是 sys.views
视图定义存在 sys.sql_modules 里,sys.views 只存元数据(比如创建时间、schema),不存 SQL 文本。直接查 sys.sql_modules 最稳:
-
sys.sql_modules的object_id对应视图 ID,definition字段就是原始 CREATE VIEW 语句 - 必须 JOIN
sys.objects过滤type = 'V',否则会混入存储过程、函数等其他模块 - 如果视图被加密(
is_encrypted = 1),definition为 NULL,此时只能用sp_helptext 'dbo.MyView'尝试解密(权限足够时)
查所有视图的表级依赖:过滤 sys.sql_expression_dependencies
这个视图记录编译时快照,覆盖跨库、非架构绑定场景,是查“谁用了谁”的第一手依据:
- WHERE 条件必须写
d.referencing_class = 1 AND d.referenced_class IN (1, 2):前者限定引用方是对象(视图/SP),后者限定被引用的是对象或数据库 -
referenced_id = 0不代表没依赖,而是说明被引用对象当前不可解析(比如跨库没写四部分名、表已被删),得看referenced_database_name和referenced_entity_name - 不要 JOIN
sys.objects去反查referenced_id—— 很多时候它根本不存在,JOIN 会丢掉这些关键线索
查列级依赖必须配对调用 sys.dm_sql_referenced_entities
单靠 sys.sql_expression_dependencies 只能知道“视图用了表 A”,但不知道“视图的列 X 是来自表 A 的 Y 字段”。列级映射必须走这个函数:
- 调用格式固定:
SELECT * FROM sys.dm_sql_referenced_entities('dbo.MyView', 'OBJECT')—— 第二个参数必须是字符串字面量'OBJECT',不能拼接变量,否则报错 - 结果中
is_ambiguous = 1是高危信号,表示该列引用可能匹配多个同名对象(比如临时表和永久表共存),需人工核对上下文 - 它不支持跨服务器依赖,
referenced_server_name永远为 NULL;跨库依赖也只能返回库名,不验证对象是否存在
别踩这些坑:常见失效场景和绕过方式
以下情况系统视图全失效,得换思路:
- 动态 SQL(
EXEC('SELECT * FROM ' + @tbl)或sp_executesql):两个依赖视图都看不到,只能扫sys.sql_modules.definition用正则匹配表名字符串 -
SELECT *且没加WITH SCHEMABINDING:列级映射丢失,sys.dm_sql_referenced_entities返回的列来源不可信,必须结合目标表实际结构手动比对 - 视图定义改过但没刷新:
sys.sql_expression_dependencies不自动更新,要执行sp_refreshsqlmodule 'YourViewName'或重建视图才能同步 - Oracle/MySQL 用户注意:SQL Server 这套不通用。Oracle 用
ALL_DEPENDENCIES,MySQL 则只能重建视图触发校验
真正麻烦的不是查不到,而是查到的依赖关系滞后于代码变更——尤其是团队协作中没人记得执行 sp_refreshsqlmodule,或者改了底层表字段却没通知下游视图负责人。这种断链往往等到报表跑崩才暴露。











