如何获取SQL Server及Netezza中查询所用的所有表列表?
针对你提到的两个问题,我来分享一下实用的解决方法:
一、SQL Server中提取任意查询用到的所有表列表
要搞定不管是关联查询还是子查询里的所有表,这两个方法亲测好用:
1. 用sys.dm_exec_describe_first_result_set快速解析
这个系统函数能直接解析你的SQL语句,返回结果集的元数据,我们只要关联系统视图就能拿到表名:
DECLARE @TargetSQL NVARCHAR(MAX) = N'select A.*, B.col1, B.col2 from table1 A inner join table2 B on A.abc=b.abc'; SELECT DISTINCT OBJECT_NAME(referenced_id) AS 所用表列表 FROM sys.dm_exec_describe_first_result_set(@TargetSQL, NULL, 0) WHERE referenced_id IS NOT NULL;
它会自动识别别名对应的真实表,返回去重后的表名,不管嵌套多少层子查询都能搞定。
2. 借助查询计划(适合已执行过的查询)
如果你的查询已经跑过了,还可以从缓存的查询计划里提取表:
DECLARE @TargetSQL NVARCHAR(MAX) = N'select A.*, B.col1, B.col2 from table1 A inner join table2 B on A.abc=b.abc'; EXEC sp_executesql @TargetSQL; SELECT DISTINCT OBJECT_NAME(objectid) AS 所用表列表 FROM sys.dm_exec_query_plan((SELECT sql_handle FROM sys.dm_exec_requests WHERE sql_text = @TargetSQL)) CROSS APPLY query_plan.nodes('//Object[@Table]') AS qp(obj) WHERE objectid IS NOT NULL;
不过这个得确保查询计划还在缓存里,适合事后排查的场景。
二、Netezza中的等效实现方案
Netezza确实没有和SQL Server的sys.dm_exec_describe_first_result_set完全对应的系统函数,但这几个方法能达到同样的效果:
1. 用EXPLAIN命令解析执行计划
Netezza的EXPLAIN会输出查询的详细执行计划,里面明确列出了所有用到的表:
EXPLAIN select A.*, B.col1, B.col2 from table1 A inner join table2 B on A.abc=b.abc;
执行后你能在输出里找到类似TABLE TABLE1、TABLE TABLE2的行,直接提取表名就行。如果要自动化处理,可以写个简单的脚本(比如Python或者Shell)来解析这个输出。
2. 关联系统视图查询历史查询
如果查询已经执行过,能通过_V_QUERY_HISTORY和_V_TABLE这两个系统视图来关联查找:
SELECT DISTINCT t.TABLENAME AS 所用表列表 FROM _V_QUERY_HISTORY qh JOIN _V_TABLE t ON qh.QUERYTEXT LIKE '%' || t.TABLENAME || '%' WHERE qh.QUERYTEXT = 'select A.*, B.col1, B.col2 from table1 A inner join table2 B on A.abc=b.abc';
注意这个方法是基于文本匹配的,如果表名刚好出现在字符串常量里可能会误判,但常规查询下足够好用。
3. 用SQL Parser API做精准解析(进阶)
如果需要100%准确的解析,可以用Netezza提供的SQL Parser API,它能解析SQL的抽象语法树(AST),精准提取所有表引用。这个需要写点代码(比如用NZPLSQL或者外部程序调用),但准确性最高。
内容的提问来源于stack exchange,提问作者RDP
相关产品推荐
相关产品推荐

