2

我的问题对你们中的许多人来说应该很简单假设我有以下 SQL,我想使用正则表达式获取表名:

SELECT name, age FROM table1

使用这个表达式我可以得到

Pattern p = Pattern.compile(".*FROM\\s+(.*?)($|\\s+[WHERE,JOIN,START\\s+WITH,ORDER\\s+BY,GROUP\\s+BY])", Pattern.CASE_INSENSITIVE);
        Matcher result = p.matcher(pSql);
        if (result.find()) {
            lRetorno = result.group(1);
        }

但是,如果表名包含模式名称 (xyz.table1),我的表达式会带来一切。我的问题是......我需要对此查询进行什么修改才能只返回没有架构/所有者的表名?

任何帮助都会非常感激

拉斐尔·莫伊塔

4

2 回答 2

5

也许试试这种方式

String data1="SELECT name, age FROM table1 whatever";
String data2="SELECT name, age FROM schema.table1 whatever";

Pattern p=Pattern.compile("from\\s+(?:\\w+\\.)*(\\w+)($|\\s+[WHERE,JOIN,START\\s+WITH,ORDER\\s+BY,GROUP\\s+BY])",Pattern.CASE_INSENSITIVE);

//test
Matcher m=p.matcher(data1);
while(m.find())
    System.out.println(m.group(1));
m=p.matcher(data2);
while(m.find())
    System.out.println(m.group(1));

输出:

table1 
table1 

编辑

我刚刚意识到这部分($|\\s+[WHERE,JOIN,START\\s+WITH,ORDER\\s+BY,GROUP\\s+BY])不能正常工作,因为在我的输入中,我在表名之后放置了“whatever”,并且无论如何都找到了它。

它不像你那样工作,因为你正在使用[WHERE,JOIN,START\\s+WITH,ORDER\\s+BY,GROUP\\s+BY]而不是(WHERE|JOIN|START\\s+WITH|ORDER\\s+BY|GROUP\\s+BY). 例如[abc]等于 (a|b|c) 所以它说正则表达式引擎接受该集合中的任何字符,而不是单词abc。将您的模式改进为类似

Pattern p=Pattern.compile("from\\s+(?:\\w+\\.)*(\\w+)(\\s*$|\\s+(WHERE|JOIN|START\\s+WITH|ORDER\\s+BY|GROUP\\s+BY))",Pattern.CASE_INSENSITIVE);
于 2012-07-09T19:24:26.920 回答
1

与其使用正则表达式进行解析,不如使用实际的解析器来进行解析。请参阅此相关问题需要 java API 来解析推荐Zql库的 SQL 语句。

它有它可以解析的查询示例,这些示例看起来至少与您要编写的任何正则表达式一样强大。

InputStream is = new ByteArrayInputStream(sqlQueryString.getBytes("UTF-8"));
ZqlParser parser = new ZqlParser(is);
ZQuery query = (ZQuery)parser.readStatement();
Vector tables = query.getFrom();

应该为你做。 tables是s 的一个VectorZFromItem你可以getTable()在一个没有架构组件的情况下获得它的名字。

于 2013-04-18T18:11:16.630 回答