postgresql查视图依赖表应使用pg_depend系统目录,通过视图oid反向查找refobjid对应的基础表名;mysql 8.0.24+用information_schema.view_table_usage;sql server应避免sys.dm_exec_describe_first_result_set,推荐解析sys.sql_modules.definition或使用sys.dm_exec_describe_first_result_set_for_object。

PostgreSQL 中查视图依赖的原始表名用 pg_depend
PostgreSQL 不在 pg_views 里存源表信息,得从系统目录里反向追踪。核心是把视图 OID 当作“被依赖对象”,找它所依赖的“源对象”(即基础表)。
常见错误是直接查 pg_views.definition 字段——里面是格式化后的 SQL 字符串,解析不可靠(比如有子查询、CTE、别名嵌套时,正则根本抓不准真实表名)。
-
pg_depend的objid指向视图 OID,refobjid指向被引用的对象 OID(通常是表) - 配合
pg_class查refobjid对应的表名,再用pg_namespace拼出 schema 名 - 注意过滤
deptype = 'n'(normal dependency),排除由规则系统自动生成的依赖
SELECT n.nspname AS schema_name, c.relname AS table_name FROM pg_depend d JOIN pg_class c ON d.refobjid = c.oid JOIN pg_namespace n ON c.relnamespace = n.oid WHERE d.objid = 'my_view'::regclass AND d.classid = 'pg_class'::regclass AND d.refclassid = 'pg_class'::regclass AND d.deptype = 'n';
MySQL 8.0+ 用 INFORMATION_SCHEMA.VIEW_TABLE_USAGE
MySQL 8.0.24 起才支持这个视图,之前版本只能靠解析 SHOW CREATE VIEW 输出——但那是纯文本,没有语法树,遇到反引号包裹的表名、跨库引用(db.tbl)、或函数调用(如 JSON_TABLE())就容易漏判。
使用场景:需要批量检查视图是否引用了已下线的表,或做影响分析。
-
VIEW_TABLE_USAGE只返回显式出现在 FROM / JOIN 子句里的基表,不包括子查询里的表 - 字段
VIEWS.TABLE_SCHEMA和VIEWS.TABLE_NAME是视图自身信息;真正要的是VIEW_TABLE_USAGE.TABLE_SCHEMA和VIEW_TABLE_USAGE.TABLE_NAME - 权限限制:用户必须对目标视图和被引用表都有
SELECT权限,否则行不会出现
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.VIEW_TABLE_USAGE WHERE VIEW_SCHEMA = 'mydb' AND VIEW_NAME = 'my_view';
SQL Server 用 sys.dm_exec_describe_first_result_set 不靠谱
这个 DMF 返回的是“执行后第一结果集的元数据”,不是视图定义本身依赖关系。它会实际展开视图、跑一遍逻辑(哪怕加了 WITH RECOMPILE),如果视图里有参数化查询、临时表、或依赖不存在的对象,就会报错或返回空。
真正稳定的方式是解析 sys.sql_modules.definition,但得小心处理:
- 用
sys.dm_exec_describe_first_result_set得加NUL参数防执行,但它仍可能因权限或对象不存在而失败 - 正则匹配
FROM/JOIN后的标识符时,必须支持括号嵌套(如(SELECT ...))和别名(AS t),否则会把子查询里的表当主表 - 推荐用
sys.dm_exec_describe_first_result_set_for_object(只接受 object_id),比字符串解析稍稳,但仍非 100%
跨数据库统一思路:别信定义字段,优先走系统目录
所有主流数据库都提供某种形式的“对象依赖图”,比字符串解析可靠得多。难点在于各系统目录结构差异大,且默认不暴露完整依赖链(比如 PostgreSQL 的物化视图依赖、SQL Server 的跨库引用)。
容易被忽略的点:视图可能依赖另一个视图,而那个视图又依赖表——这时候你要递归查,不能只停在第一层。另外,权限控制常导致元数据查询返回空结果,不是没依赖,而是你没权限看。










