sys.dm_sql_referenced_entities用于查“我依赖谁”,需传入'schema_name.object_name'和'object',否则报错或返回空;它实时解析函数体,支持未存在对象的引用记录,但对动态sql、加密视图和跨库未三段式引用无效。

直接用 sys.dm_sql_referenced_entities 查视图依赖关系是可行的,但必须传对参数,否则返回空或报错 —— 这是最常踩的坑。
调用 sys.dm_sql_referenced_entities 的正确方式
这个函数不是查“谁依赖我”,而是查“我依赖谁”。所以你要把目标视图作为输入,它才返回该视图引用的所有对象(表、函数、其他视图等)。
关键点:
- 第一个参数必须是
'schema_name.object_name'格式的字符串,不能只写'object_name',否则报错"Invalid object name" - 第二个参数固定为
'OBJECT',表示你查的是数据库对象(不是列、类型等) - 不能直接在 SELECT 中写
OBJECT_ID('view_name')代替第一参数 —— 它要的是名字字符串,不是 ID
示例(查 dbo.v_customer_orders 依赖哪些对象):
SELECT
referenced_schema_name,
referenced_entity_name,
referenced_minor_name, -- 列名(如果是 SELECT * 或引用了具体列)
referenced_class_desc
FROM sys.dm_sql_referenced_entities('dbo.v_customer_orders', 'OBJECT');
为什么有时返回空结果?常见原因
空结果不等于没依赖,大概率是调用姿势不对或对象状态异常:
- 视图定义里用了
EXEC()或动态 SQL(如sp_executesql),这类依赖不会被系统捕获 - 视图被加密(
WITH ENCRYPTION),元数据不可读,函数无法解析引用 - 视图引用了跨库对象但没用三段式名称(如
otherdb.dbo.table),而你当前查的是本地库,referenced_database_name字段会非空,容易被 WHERE 过滤掉 - 视图本身语法错误或未成功创建(
is_ms_shipped = 1或OBJECTPROPERTY(OBJECT_ID(...), 'IsView') = 0时函数可能不返回有效数据)
sys.dm_sql_referenced_entities 和 sys.sql_expression_dependencies 怎么选?
两者都可用,但行为和覆盖范围不同:
-
sys.dm_sql_referenced_entities是实时解析函数体,更“激进”——哪怕依赖对象当前不存在(比如表被删了但视图还没重编译),它仍能返回历史引用记录 -
sys.sql_expression_dependencies是编译时快照,依赖信息只在对象创建/修改时写入,如果视图很久没改过,而底层表已被重命名,这里可能还存着旧名 - 若需知道“这个视图现在实际访问哪些对象”,优先用
sys.dm_sql_referenced_entities;若要审计变更影响(比如准备删一张表,看哪些视图会崩),两个都查更稳妥
绑定到架构(SCHEMABINDING)对依赖查询的影响
加了 WITH SCHEMABINDING 的视图,其依赖关系会被强制登记且不可绕过:
-
sys.dm_sql_referenced_entities一定能查到它引用的表/列,且is_schema_bound_reference列为 1 - 这种视图不允许删除或改名被引用对象,所以依赖结果更“可靠”
- 但注意:如果视图里引用了函数,而该函数自己没加
SCHEMABINDING,那函数内部的进一步依赖(比如函数查了另一张表)就不会出现在当前视图的查询结果里
真正容易被忽略的是:依赖关系是否跨数据库、是否含动态 SQL、以及视图是否加密 —— 这三类情况会让任何依赖查询工具都“失明”,只能靠人工审代码或运行时跟踪。










