SQL Server 视图依赖必须用 sys.sql_expression_dependencies 和 sys.dm_sql_referenced_entities 手动查;前者覆盖跨库、非架构绑定场景且记录不可解析引用,后者支持列级依赖和动态SQL解析,而SSMS“查看依赖关系”在动态SQL、同义词、SELECT *等场景严重漏报。

SQL Server 中视图的依赖关系不能靠猜,也不能只靠 SSMS 右键“查看依赖关系”——那个功能在跨库、非架构绑定、动态 SQL 场景下经常漏报或报空。真实生产环境里,必须结合 sys.sql_expression_dependencies 和 sys.dm_sql_referenced_entities 手动查,否则改表时删掉一个字段,下游十几个视图全挂,连谁在用都不知道。
为什么 sys.sql_expression_dependencies 是首选起点
它是系统级元数据视图,记录所有按名称引用的显式依赖(无论是否 WITH SCHEMABINDING),且包含跨数据库、跨服务器线索。关键点在于它不依赖对象是否可解析——哪怕被引用的表已被删,只要定义里写过 SELECT * FROM OtherDB.dbo.TableA,这条记录还在。
-
referencing_id和referenced_id是对象 ID,用OBJECT_ID('ViewName')查;但注意:若referenced_id = 0,说明被引用对象不存在或名字未解析(比如跨库未加四部分名) -
referenced_server_name和referenced_database_name为空时,代表依赖在当前数据库;非空则必须检查对应库是否存在、用户是否有权限 - 该视图不返回列级依赖,只到对象粒度;想查“视图 A 的某列是否来自表 B 的 C 列”,得用
sys.dm_sql_referenced_entities
什么时候必须切到 sys.dm_sql_referenced_entities
当你需要确认列级映射、或处理非架构绑定对象(如没加 WITH SCHEMABINDING 的视图、存储过程里拼接的表名)时,sys.dm_sql_referenced_entities 是唯一可靠选择。它会实际解析 SQL 表达式,哪怕对象当前不可用也能推导出意图。
- 调用方式固定:
SELECT * FROM sys.dm_sql_referenced_entities('dbo.MyView', 'OBJECT');第二个参数必须是字符串字面量'OBJECT',不能变量传入 - 结果中
is_ambiguous = 1是危险信号——表示该引用可能被解析为多个对象(比如同名的临时表和永久表共存,或 schema 搜索路径混乱) - 它不返回跨服务器依赖,
referenced_server_name永远为 NULL;跨库依赖也只能返回库名,不保证对象存在
SSMS “查看依赖关系” 功能的实际局限
右键菜单那个功能看着方便,但底层调用的是旧版依赖跟踪逻辑,对现代 SQL 场景覆盖严重不足:
- 完全忽略字符串拼接 SQL(
EXEC('SELECT * FROM ' + @table))和sp_executesql中的依赖 - 不识别
OPENQUERY、链接服务器查询里的远程对象 - 若视图定义里用了
SELECT *且基表结构已变,它仍显示“依赖正常”,但运行时报列不存在 - 对同义词(
Synonym)只展开一层,不会继续追踪同义词指向的真实对象
分析依赖时最容易被跳过的三个细节
真正影响架构可控性的不是“能不能查”,而是查完后是否注意到这些隐性风险点:
- 检查
sys.sql_expression_dependencies中is_schema_bound_reference = 0的记录——这类依赖随时可能因基表改名/删列而失效,但系统不会阻止你操作基表 - 发现
referenced_entity_name是单部分名(如'Orders'而非'dbo.Orders')时,立刻查调用方的SCHEMA_NAME()和默认 schema,否则部署到新环境极易解析错表 - 任何依赖链中出现
VIEW→FUNCTION→TABLE这类多跳路径,都应人工验证中间函数是否含条件分支(如 IF @mode = 'A' SELECT FROM T1 ELSE SELECT FROM T2),否则依赖关系图会误导你

















