从查询中获取表名

时间:2012-07-09 19:13:40

标签: java regex

对于你们许多人来说,我的问题应该很简单 Supouse我有以下SQL,我想使用regexp获取表名:

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),我的表达式会带来所有内容。我的问题是......我需要修改这个查询,只返回没有架构/所有者的表名吗?

任何帮助都会非常苛刻 此致

Raphael Moita

2 个答案:

答案 0 :(得分:3)

也许这样试试

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])不能正常工作,因为在我的输入中我在表名后放了“无论什么”,无论如何都找到了它。

由于您使用的是[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);

答案 1 :(得分:1)

使用实际的解析器可能会有更好的时间,而不是使用正则表达式进行解析。请参阅推荐Need java API to parse SQL statements库的相关问题Zql

它的examples of the queries it can parse似乎至少和你要编写的任何正则表达式一样强大。

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

应该为你做。 tablesVector的{​​{1}},您可以在其中ZFromItem获取其名称而不使用架构组件。