如何自动准确获取Azure SQL视图引用的所有表?VIEW_TABLE_USAGE结果不全
根因说明
INFORMATION_SCHEMA.VIEW_TABLE_USAGE返回结果不全是存在很久的通用问题,哪怕它底层基于sys.objects实现也无法避免结果不准——它读取的是对象创建时持久化存储的静态依赖记录,以下场景都会出现漏记:
- 视图创建时被引用的表还未创建,后续补建表时不会自动同步更新依赖记录
- 视图引用了跨schema、跨数据库的对象
- 视图存在多层嵌套(比如视图A调用视图B,它不会递归向下解析B依赖的基础表)
- 视图定义中包含OPENQUERY、OPENROWSET这类外部数据源引用,或是使用了复杂别名关联
所有依赖提前存储的静态元数据做依赖查询的方式都有这个缺陷,不管是INFORMATION_SCHEMA系列视图还是sys.sql_expression_dependencies视图都存在漏报可能。
准确查询方案
使用sys.dm_sql_referenced_entities动态管理函数实现查询,它会实时解析每个视图的T-SQL定义提取依赖关系,不依赖提前存储的历史元数据,准确性远高于前述静态查询方式。
执行以下脚本即可获取当前数据库内所有视图引用的表,结果同时会标注每个表是被哪个视图引用的:
SELECT DISTINCT referenced_schema_name AS table_schema, referenced_entity_name AS table_name, OBJECT_NAME(referencing_id) AS referenced_by_view FROM sys.views v CROSS APPLY sys.dm_sql_referenced_entities( CONCAT(SCHEMA_NAME(v.schema_id), '.', v.name), 'OBJECT' ) ref WHERE ref.referenced_class = 1 -- 仅筛选被引用对象为用户表的记录 AND ref.is_ambiguous = 0 -- 排除存在引用歧义、无法准确定位对象的记录 ORDER BY table_schema, table_name
如果只需要去重后的被引用表清单,去掉SELECT子句中视图相关的返回字段即可。
补充说明
- 只要当前登录账号对对应资源有访问权限,跨数据库的表引用也可以被该函数正常解析返回
- 如果视图定义中使用了动态SQL拼接表名,不存在任何静态元数据查询方式可以捕获这类引用——动态SQL的引用对象只有在实际运行时才会确定,静态解析无法获取结果
- 不要使用网上流传的直接关联sys.objects和sysdepends的旧方案,sysdepends就是存储静态依赖关系的旧系统表,和INFORMATION_SCHEMA一样存在结果不准的问题
内容的提问来源于stack exchange,提问作者bbb0777
相关产品推荐
相关产品推荐

