java - 列出已解析的 SQL SELECT 语句的所有表/列
问题描述
我正在尝试使用 JSqlParser 从 SQL SELECT 语句中提取表/列列表。SELECT 包含一个计算和一个嵌套的 SELECT:
SELECT col1 AS a, (col2 - col21) AS b, col3 AS c FROM table1
where col1 in (select col4 from table4)
这应该返回:
col1 table1
col2 table1
col21 table1
col3 table1
col4 table4
如果我用 解析它CCJSqlParserUtil
,我会得到不同的东西:
Select stmt = (Select) CCJSqlParserUtil.parse("SELECT col1 AS a, col2 AS b, col3 AS c "
+ "FROM table1 WHERE where col1 in (select col4 from table4)");
Map<String, Expression> map = new HashMap<>();
for (SelectItem selectItem : ((PlainSelect)stmt.getSelectBody()).getSelectItems()) {
selectItem.accept(new SelectItemVisitorAdapter() {
@Override
public void visit(SelectExpressionItem item) {
map.put(item.getAlias().getName(), item.getExpression());
}
});
}
System.out.println("map " + map);
印刷:
map {a=col1, b=col2, c=col3}
这不是我要找的。SELECT 语句甚至可以更复杂,带有嵌套和子嵌套的 SELECT;有没有办法获取所有列/表的列表?
解决方案
要提取所有表名(模拟列名),您可以使用TableNamesFinder:
Statement statement = CCJSqlParserUtil.parse("SELECT * FROM MY_TABLE1");
Select selectStatement = (Select) statement;
TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();
List<String> tableList = tablesNamesFinder.getTableList(selectStatement);
您使用的代码(我假设来自 JSQLParsers wiki)用于:
这里的任务是构建一个映射,其中别名是键,该别名的表达式是一个映射条目的值。
因此完全不同的东西。
此外,您应该检查:Parsing table and column names from SQL/HQL Java。
请记住,JSqlParser只是一个 parser。要将列映射到表,您必须检查数据库模式并在 sql 中引入某种块或可见性检查。以下是一些有问题的星座:
select a from tab1, tab2
select a, (select a from tab2) b from tab1
...
推荐阅读
- azure-data-factory-2 - 如何获取上次注册自托管集成运行时密钥的信息是什么时候?
- iis - 从我的网址中删除两个参数(随机顺序)
- javascript - 将 ods 转换为 Google 表格
- c# - 当导航属性是数组而不是 C# 中的列表时迁移失败 - 实体框架标准
- .net - 使用 SQL Azure 数据库时不会触发 TransactionManager.DistributedTransactionStarted 事件
- javascript - 当用户关闭窗口(或导航离开它)时执行 JS 会发生什么?
- azure-sql-database - Azure SQL 表在一段时间未查询时变慢
- sql - 为什么我在尝试创建此触发器时会收到 ORA-00922?
- html - 如何在使用 JSOUP 解析 HTML 时保留 CSS 格式并打印到 Thymeleaf PDF 以适应页面而不截断数据
- bash - bash 中唯一原始的条件问题