简体   繁体   English

从JAVA中的sql语句获取表名和查询类型

[英]Get Table names and Query types from sql statement in JAVA

I am new to jsqlparser and trying to parse the sql statement to get table name and its query type (In Java). 我是jsqlparser的新手,并尝试解析sql语句以获取表名及其查询类型(在Java中)。

For eg1. 对于eg1。
INSERT INTO Customers (CustomerName, Country) SELECT SupplierName, Country FROM Suppliers WHERE Country='Germany'
From this query, I want to get the table name Suppliers and its query type SELECT . 从这个查询,我想得到表名Suppliers及其查询类型SELECT
Similarly, table name Suppliers and its query type INSERT . 同样,表名Suppliers及其查询类型为INSERT

For eg2. 对于eg2。
UPDATE CUSTOMERS SET SALARY = SALARY * 0.25 WHERE AGE IN (SELECT AGE FROM CUSTOMERS_BKP WHERE AGE >= 27 )
From this query, I want to get the table name CUSTOMERS_BKP and its query type SELECT . 从这个查询,我想得到表名CUSTOMERS_BKP及其查询类型SELECT
Similarly, table name CUSTOMERS and its query type UPDATE . 同样,表名CUSTOMERS及其查询类型UPDATE

For eg3. 对于eg3。
UPDATE CUSTOMERS SET SALARY = SALARY * 0.25 WHERE AGE IN (SELECT AGE FROM CUSTOMERS WHERE AGE >= 27 )
(I knew that this query can be simplified, but for example I have pasted here.) (我知道这个查询可以简化,但例如我已粘贴在这里。)
From this query, I want to get the table name CUSTOMERS and its query type SELECT . 从这个查询,我想得到表名CUSTOMERS和它的查询类型SELECT
Similarly, table name CUSTOMERS and its query type UPDATE . 同样,表名CUSTOMERS及其查询类型UPDATE
Note: here table names are same but different query type. 注意:此处的表名相同但查询类型不同。

Same way, I want to get the table name and its query type for any complex sql query. 同样,我想获取任何复杂的SQL查询的表名及其查询类型。

Could you please help me on this? 你能帮帮我吗?

Please comment, if you want me to provide any details. 如果您希望我提供任何详细信息,请发表评论。

The question you filed is a tricky one, because JSqlParsers API lacks some extension points for this. 您提交的问题很棘手,因为JSqlParsers API缺少一些扩展点。 To correct this, I created some issues at github. 为了纠正这个问题,我在github上创建了一些问题。 So here is a little sample to get this running. 所以这里有一个小样本来运行。 The output is: 输出是:

eg1
INSERT - Customers
SELECT - [Suppliers]
eg2
UPDATE - [CUSTOMERS]
SELECT - [CUSTOMERS_BKP]
eg3
UPDATE - [CUSTOMERS]
SELECT - [CUSTOMERS]

Your main tool here is the TablesNamesFinder of JSqlParser , that gets all table names of some SQL. 这里的主要工具是JSqlParserTablesNamesFinder ,它获取某些SQL的所有表名。 Now we have to modify it, to get all select - statement based table names in a separate way. 现在我们必须修改它,以单独的方式获取所有基于select语句的表名。 This is done using TablesNamesFinderExt , which does as well correct the subselect problem using an Insert statement. 这是使用TablesNamesFinderExt完成的,它也可以使用Insert语句纠正子选择问题。

In short the finder recognizes subselects and sets a global flag inSelect to fill the separate mySelectTableList for subsequent calls of visit(Table ...) . 总之取景器识别子选择并设置一个全局标志inSelect填写参观的后续调用单独mySelectTableList(表...)。

import java.util.ArrayList;
import java.util.List;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.select.SubSelect;
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.util.TablesNamesFinder;

public class SimpleSqlParserTableNames2 {

    public static void main(String args[]) throws JSQLParserException {
        System.out.println("eg1");
        Insert insert = (Insert)CCJSqlParserUtil.parse("INSERT INTO Customers (CustomerName, Country) SELECT SupplierName, Country FROM Suppliers WHERE Country='Germany'");
        TablesNamesFinderExt finder = new TablesNamesFinderExt();

        System.out.println("INSERT - " + insert.getTable());
        finder.getTableList(insert.getSelect());
        System.out.println("SELECT - " + finder.getSelectTableList());

        System.out.println("eg2");
        Update update = (Update)CCJSqlParserUtil.parse("UPDATE CUSTOMERS SET SALARY = SALARY * 0.25\n" +
                    "  WHERE AGE IN (SELECT AGE FROM CUSTOMERS_BKP WHERE AGE >= 27 )");
        finder = new TablesNamesFinderExt();
        System.out.println("UPDATE - " + update.getTables());
        finder.getTableList(update);
        System.out.println("SELECT - " + finder.getSelectTableList());

        System.out.println("eg3");
        update = (Update)CCJSqlParserUtil.parse("UPDATE CUSTOMERS SET SALARY = SALARY * 0.25\n" +
                    "WHERE AGE IN (SELECT AGE FROM CUSTOMERS WHERE AGE >= 27 )");
        finder = new TablesNamesFinderExt();
        System.out.println("UPDATE - " + update.getTables());
        finder.getTableList(update);
        System.out.println("SELECT - " + finder.getSelectTableList());
    }

    static class TablesNamesFinderExt extends TablesNamesFinder {
        List<String> mySelectTableList = new ArrayList<>();
        boolean inSelect = true;
        /**
         * To solve JSqlParsers Problem in getting tablenames from subselect using an Insert
         * statement.
         *
         * @param insert
         * @return
         */
        @Override
        public List<String> getTableList(Insert insert) {
            List<String> list = super.getTableList(insert);
            if (insert.getSelect() != null) {
                insert.getSelect().getSelectBody().accept(this);
            }
            return list;
        }

        @Override
        public void visit(SubSelect subSelect) {
            inSelect = true;
            super.visit(subSelect);
        }

        @Override
        public void visit(Table tableName) {
            super.visit(tableName); 
            if (inSelect && !mySelectTableList.contains(tableName.getFullyQualifiedName()))
                mySelectTableList.add(tableName.getFullyQualifiedName());
        }

        public List<String> getSelectTableList() {
            return mySelectTableList;
        }

    }
}

If you just need table names form SQLs, you need an ultra light, ultra fast libray (full SQL parser would be over kill) 如果你只需要表格形式的SQL,你需要一个超轻,超快的libray(完整的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>
</dependency>

And use the following instruction 并使用以下说明

new TableNameParser(sql).tables()

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

Disclaimer : I am the owner 免责声明:我是所有者

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

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