跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

如何在SQL Server中查看视图与其底层表的依赖关系_利用系统视图查询关联性

应使用 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 分支逻辑。

相关文章