如何用Java从PostgreSQL查询语句中提取表名与函数名?
用JSqlParser同时提取SQL中的表名与函数名
JSqlParser本身支持通过自定义AST Visitor遍历SQL语法树,同时捕获表名和函数名,不用局限于它自带的工具类。下面是具体实现方案:
1. 自定义Visitor捕获目标节点
继承ASTVisitorAdapter,维护两个集合分别存储提取到的表名和函数名,重写对应节点的visit方法来捕获信息:
import net.sf.jsqlparser.expression.Function; import net.sf.jsqlparser.statement.select.Table; import net.sf.jsqlparser.util.deparser.ASTVisitorAdapter; import java.util.ArrayList; import java.util.List; public class SqlElementExtractor extends ASTVisitorAdapter { private final List<String> tableNames = new ArrayList<>(); private final List<String> functionNames = new ArrayList<>(); @Override public void visit(Table table) { // 提取表的全限定名,若不需要schema可直接用 getName().getPlainName() tableNames.add(table.getName().getFullyQualifiedName()); super.visit(table); } @Override public void visit(Function function) { // 提取函数名,支持带schema的函数 functionNames.add(function.getName().getFullyQualifiedName()); super.visit(function); } // 获取结果的方法 public List<String> getTableNames() { return tableNames; } public List<String> getFunctionNames() { return functionNames; } }
2. 解析SQL并提取信息
使用CCJSqlParserUtil.parseStatements解析多语句脚本,遍历每个Statement并传入自定义Visitor:
import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.util.CCJSqlParserUtil; import java.util.List; public class Main { public static void main(String[] args) throws JSQLParserException { // 测试示例1:提取表名 String sql1 = "Select * from Users;"; extractElements(sql1); System.out.println("---"); // 测试示例2:提取函数名 String sql2 = "Select 1 from pg_sleep(1);\nSelect current_user;"; extractElements(sql2); } private static void extractElements(String sql) throws JSQLParserException { SqlElementExtractor extractor = new SqlElementExtractor(); List<Statement> statements = CCJSqlParserUtil.parseStatements(sql); for (Statement stmt : statements) { stmt.accept(extractor); } System.out.println("提取到的表名:" + extractor.getTableNames()); System.out.println("提取到的函数名:" + extractor.getFunctionNames()); } }
运行结果
- 示例1输出:
提取到的表名:[Users] 提取到的函数名:[]
- 示例2输出:
提取到的表名:[] 提取到的函数名:[pg_sleep, current_user]
注意事项
- 支持嵌套函数、带Schema的表/函数名提取,会递归遍历整个语法树;
- 若SQL中存在表别名或函数别名,上述代码提取的是原对象名称,若需处理别名可在
visit方法中额外调用getAlias(); - 对于PostgreSQL这类数据库的内置函数(如
current_user),JSqlParser会正确解析为Function节点,无需额外处理。
内容的提问来源于stack exchange,提问作者Sakthis
相关产品推荐
相关产品推荐

