JDBC:获取 SQL 查询中涉及的表名

Posted

技术标签:

【中文标题】JDBC:获取 SQL 查询中涉及的表名【英文标题】:JDBC: Get table names involved in a SQL query 【发布时间】:2013-05-17 18:53:10 【问题描述】:

有没有办法知道通过 JDBC 执行的 SQL 查询中涉及的表的名称?

例如:

SELECT r.roleId FROM User u, UserRole r where r.userId = u.userId and u.name = "Jonh Smith"

我不仅想要此查询的结果集,还想要实际的表名(“用户”和“角色”)。我不关心视图名称,但如果无法获取视图中使用的基础表,这不是什么大问题,但这必须与嵌套查询一起使用。

至于我为什么需要这些信息,是因为我正在创建一个平台,让其他开发人员可以在此平台上构建应用程序。在我的平台上,我让其他开发人员注册他们自己的查询并将它们存储在数据库中。我不希望开发人员不得不为实际手动注册表名以及查询本身而烦恼。所以在我执行查询时,我真的不知道该查询在做什么。

【问题讨论】:

无意冒犯,但你所描述的(“我让其他开发人员注册他们自己的查询并将它们存储在数据库中......所以在我执行查询时我真的不知道什么该查询正在执行。”)是等待发生的 SQL 注入。 @BrianRoach 好吧,我应该在这个问题上说出来,其他开发人员不会在我的服务器上运行他们的应用程序。我平台的每个“定制”都将由开发人员自己单独部署。所以我可以相信这些查询不会被利用。应用程序的普通用户将无权访问查询。 【参考方案1】:

我还没有弄清楚如何做你需要的,但无论如何我都会发布这个,因为它太长了,无法发表评论。我发现的最接近的是ResultSetMetaData。

This is a tutorial on how to get it. 但是该教程没有显示如何获取表名。执行此操作的方法称为getTableName

/**
 * Gets the designated column's table name. 
 *
 * @param column the first column is 1, the second is 2, ...
 * @return table name or "" if not applicable
 * @exception SQLException if a database access error occurs
 */
String getTableName(int column) throws SQLException;

我认为您必须遍历所有列并将表名放在Set 中。结果应该是所有使用的表,但是......问题是,如果该列未在选择中公开,那么您将无法发现该表。我一直无法找到解决这个问题的方法。

【讨论】:

嗯,当我问这个问题时,我不太希望得到解决方案,但这实际上适用于我的情况。不过,我还有另一个问题,在我的平台上,我让开发人员提供他们正在使用的 JDBC 驱动程序的 .jar。所以我不能保证他们使用的 JDBC 驱动程序与规范 100% 兼容,我可以相信这个 ResultSetMetaData 可以在所有主要驱动程序中正确实现吗? 小心,因为有些驱动程序没有实现这样的方法。例如,使用 Redshift 官方驱动时,getTableName 返回 null。 你有解决方案吗,我正在尝试创建一个框架组件,我可以在其中访问 SQL 查询和preparedStatement,(更新/删除/插入)我想知道表名。我不能使用getResultSet().getMetadata().getTableName()。在插入/更新/删除语句上。【参考方案2】:

JSQLParser 库 (LGPL V2.1) 似乎能够完全满足要求:

Extract table names from SQL

Statement statement = CCJSqlParserUtil.parse("SELECT * FROM MY_TABLE1");
Select selectStatement = (Select) statement;
TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();
List<String> tableList = tablesNamesFinder.getTableList(selectStatement);

【讨论】:

以上是关于JDBC:获取 SQL 查询中涉及的表名的主要内容,如果未能解决你的问题,请参考以下文章

SQl查询数据库表名表的列名数据类型主键

SQL Server2019数据库查询所有数据库名表名表结构表字段主键方法演示,执行sql提示对象名‘user_tab_columns‘ ‘user_cons_columns‘ 无效问题解决

SQLServer中获取所有数据库名表名字段名以及描述

MySQL数据库建库时SQL语句中数据库名表名用引号的问题以及COLLATE utf8_general_ci的含义

SQL(MySQL + PHP) 查询,查询排名,表内一个人多条数据,查出最大的那条排名,请问!

oracle 中如何查询当前用户可以看到的表名表对应的所有字段