简体   繁体   English

Java的SQL解析器库 - 检索SQL语句中存在的表名列表

[英]SQL parser library for Java - Retrieve the list of table names present in a SQL statement

I am looking for a SQL Library that will parse an SQL statement and return some sort of Object representation of the SQL statement. 我正在寻找一个SQL库,它将解析SQL语句并返回SQL语句的某种Object表示形式。 My main objective is actually to be able to parse the SQL statement and retrieve the list of table names present in the SQL statement (including subqueries, joins and unions). 我的主要目标实际上是能够解析SQL语句并检索SQL语句中存在的表名列表(包括子查询,联接和联合)。

I am looking for a free library with a license business friendly (eg Apache license). 我正在寻找一个商业友好的许可证库(例如Apache许可证)。 I am looking for a library and not for an SQL Grammar. 我正在寻找一个库而不是SQL语法。 I do not want to build my own parser. 我不想构建自己的解析器。

The best I could find so far was JSQLParser , and the example they give is actually pretty close to what I am looking for. 到目前为止我能找到的最好的是JSQLParser ,他们给出的例子实际上非常接近我正在寻找的东西。 However it fails parsing too many good queries (DB2 Database) and I'm hoping to find a more reliable library. 然而,它无法解析太多好的查询(DB2数据库),我希望找到一个更可靠的库。

I doubt you'll find anything prewritten that you can just use. 我怀疑你会找到任何可以使用的预先写好的东西。 The problem is that ISO/ANSI SQL is a very complicated grammar — something like more than 600 production rules IIRC. 问题是ISO / ANSI SQL是一个非常复杂的语法 - 类似于超过600个生产规则IIRC。

Terence Parr's ANTLR parser generator (Java, but can generate parsers in any one of a number of target languages) has several SQL grammars available, including a couple for PL/SQL, one for a SQL Server SELECT statement, one for mySQL, and one for ISO SQL. Terence Parr的ANTLR解析器生成器 (Java,但可以使用多种目标语言中的任何一种生成解析器)有几种可用的SQL语法,包括一对用于PL / SQL,一种用于SQL Server SELECT语句,一种用于mySQL,以及一种对于ISO SQL。

No idea how complete/correct/up-to-date they are. 不知道他们是多么完整/正确/最新。

http://www.antlr.org/grammar/list http://www.antlr.org/grammar/list

You needn't reinvent the wheel, there is already such a reliable SQL parser library there, (it's commerical, not free), and this article shows how to retrieve the list of table names present in the SQL statement (including subqueries, joins and unions) that is exactly what you are looking for. 你不需要重新发明轮子,那里已经存在这样一个可靠的SQL解析器库(它是商业的,而不是免费的),本文展示了如何检索SQL语句中存在的表名列表(包括子查询,联接和工会)这正是你要找的。

http://www.dpriver.com/blog/list-of-demos-illustrate-how-to-use-general-sql-parser/get-columns-and-tables-in-sql-script/ http://www.dpriver.com/blog/list-of-demos-illustrate-how-to-use-general-sql-parser/get-columns-and-tables-in-sql-script/

This SQL parser library supports Oracle, SQL Server, DB2, MySQL, Teradata and ACCESS. 此SQL解析器库支持Oracle,SQL Server,DB2,MySQL,Teradata和ACCESS。

You need the ultra light, ultra fast library to extract table names from SQL (Disclaimer: I am the owner) 您需要超轻,超快的库从SQL中提取表名(免责声明:我是所有者)

Just add the following in your pom 只需在您的pom中添加以下内容即可

<dependency>
 <groupId>com.github.mnadeem</groupId>
 <artifactId>sql-table-name-parser</artifactId>
 <version>0.0.1</version>

And do the following 并执行以下操作

new TableNameParser(sql).tables()

For more details, refer the project 有关更多详细信息,请参阅该项目

Old question, but I think this project contains what you need: 老问题,但我认为这个项目包含你需要的东西:

Data Tools Project - SQL Development Tools 数据工具项目 - SQL开发工具

Here's the documentation for the SQL Query Parser . 这是SQL Query Parser的文档。

Also, here's a small sample program. 另外,这是一个小样本程序。 I'm no Java programmer so use with care. 我不是Java程序员所以要小心使用。

package org.lala;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.List;

import org.eclipse.datatools.modelbase.sql.query.QuerySelectStatement;
import org.eclipse.datatools.modelbase.sql.query.QueryStatement;
import org.eclipse.datatools.modelbase.sql.query.TableReference;
import org.eclipse.datatools.modelbase.sql.query.ValueExpressionColumn;
import org.eclipse.datatools.modelbase.sql.query.helper.StatementHelper;
import org.eclipse.datatools.sqltools.parsers.sql.SQLParseErrorInfo;
import org.eclipse.datatools.sqltools.parsers.sql.SQLParserException;
import org.eclipse.datatools.sqltools.parsers.sql.SQLParserInternalException;
import org.eclipse.datatools.sqltools.parsers.sql.query.SQLQueryParseResult;
import org.eclipse.datatools.sqltools.parsers.sql.query.SQLQueryParserManager;
import org.eclipse.datatools.sqltools.parsers.sql.query.SQLQueryParserManagerProvider;

public class SQLTest {

    private static String readFile(String path) throws IOException {
        FileInputStream stream = new FileInputStream(new File(path));
        try {
            FileChannel fc = stream.getChannel();
            MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0,
                    fc.size());
            /* Instead of using default, pass in a decoder. */
            return Charset.defaultCharset().decode(bb).toString();
        } finally {
            stream.close();
        }
    }

    /**
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        try {
            // Create an instance the Parser Manager
            // SQLQueryParserManagerProvider.getInstance().getParserManager
            // returns the best compliant SQLQueryParserManager
            // supporting the SQL dialect of the database described by the given
            // database product information. In the code below null is passed
            // for both the database and version
            // in which case a generic parser is returned

            SQLQueryParserManager parserManager = SQLQueryParserManagerProvider
                    .getInstance().getParserManager("DB2 UDB", "v9.1");
            // Sample query
            String sql = readFile("c:\\test.sql");
            // Parse
            SQLQueryParseResult parseResult = parserManager.parseQuery(sql);
            // Get the Query Model object from the result
            QueryStatement resultObject = parseResult.getQueryStatement();
            // Get the SQL text
            String parsedSQL = resultObject.getSQL();
            System.out.println(parsedSQL);

            // Here we have the SQL code parsed!
            QuerySelectStatement querySelect = (QuerySelectStatement) parseResult
                    .getSQLStatement();
            List columnExprList = StatementHelper
                    .getEffectiveResultColumns(querySelect);
            Iterator columnIt = columnExprList.iterator();
            while (columnIt.hasNext()) {
                ValueExpressionColumn colExpr = (ValueExpressionColumn) columnIt
                        .next();
                // DataType dataType = colExpr.getDataType();
                System.out.println("effective result column: "
                        + colExpr.getName());// + " with data type: " +
                                                // dataType.getName());
            }
            List tableList = StatementHelper.getTablesForStatement(resultObject);
            // List tableList = StatementHelper.getTablesForStatement(querySelect);
            for (Object obj : tableList) {
                TableReference t = (TableReference) obj;
                System.out.println(t.getName());
            }
        } catch (SQLParserException spe) {
            // handle the syntax error
            System.out.println(spe.getMessage());
            @SuppressWarnings("unchecked")
            List<SQLParseErrorInfo> syntacticErrors = spe.getErrorInfoList();
            Iterator<SQLParseErrorInfo> itr = syntacticErrors.iterator();
            while (itr.hasNext()) {
                SQLParseErrorInfo errorInfo = (SQLParseErrorInfo) itr.next();
                // Example usage of the SQLParseErrorInfo object
                // the error message
                String errorMessage = errorInfo.getParserErrorMessage();
                String expectedText = errorInfo.getExpectedText();
                String errorSourceText = errorInfo.getErrorSourceText();
                // the line numbers of error
                int errorLine = errorInfo.getLineNumberStart();
                int errorColumn = errorInfo.getColumnNumberStart();
                System.err.println("Error in line " + errorLine + ", column "
                        + errorColumn + ": " + expectedText + " "
                        + errorMessage + " " + errorSourceText);
            }
        } catch (SQLParserInternalException spie) {
            // handle the exception
            System.out.println(spie.getMessage());
        }
        System.exit(0);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM