在Update语句之后获取WHERE子句

时间:2019-11-01 12:54:06

标签: java mysql

我需要在更新语句之后获取where子句,例如

UPDATE user_accounts SET bio='This is my bio' WHERE user_id = 1 OR name = 'Alex';

目前,我可以使用以下代码在where子句之后获取所有内容:

String query = "UPDATE user_accounts SET bio='This is my bio' WHERE user_id = 1 OR name = 'Alex'";
int index = query.toUpperCase().indexOf("WHERE");
if (index != -1) {
     System.out.println(query.substring(index));
}

但是后来我发现这是一个严重的缺陷,因为这些示例查询将失败:

UPDATE user_accounts SET bio='This is where my bio is' WHERE user_id = 1 OR name = 'Alex';
UPDATE user_accounts SET whereColumn='' WHERE user_id = 1 OR name = 'Alex'
UPDATE user_whereabouts SET columnName='' WHERE user_id = 1 OR name = 'Alex'

本质上,如果表名或SET下的任何列名或列值包含单词“ where”(不区分大小写),此操作将失败。

目前,我的想法一直与执行以下操作的正则表达式类似:

  1. 检查“'”或“”之间的单词(例如bio =“这是我的简历所在的位置”),并跳过该单词,将其移至引号之外的单词。这将有助于消除SET值中的 where 单词。当然,围绕字符串的Java引号不适用,因为它们不是字符串本身的一部分。
  2. 检查单词where被夹在空格之间(例如... WHERE ...)。这将有助于消除在表名或列名中找到的 where 词(SQL语法本身不允许表名或列名仅作为保留词)。
  3. 最后,返回所需WHERE的索引以获取子字符串(问题的目标)。

我不太熟悉正则表达式,因此,我需要帮助。请注意,任何其他实现目标的方式也将受到高度赞赏。

2 个答案:

答案 0 :(得分:0)

您需要某种SQL解析器,因为正则表达式在许多情况下会失败(例如,如果where子句具有子选择呢?)

我从未尝试过,但是JSQLParser似乎是一个很好的解决方案

答案 1 :(得分:0)

使用 JSqlParser 如下所示:

List<String> sqls = Arrays.asList("UPDATE user_accounts SET bio='This is my bio' WHERE user_id = 1 OR name = 'Alex';",
    "UPDATE user_accounts SET whereColumn='' WHERE user_id = 1 OR name = 'Alex'",
    "UPDATE user_whereabouts SET columnName='' WHERE user_id = 1 OR name = 'Alex'");

for (String sql : sqls) {
    Statement stmt = CCJSqlParserUtil.parse(sql);
    Update update = (Update)stmt;

    System.out.println("sql=" + stmt.toString());
    System.out.println("   where=" + update.getWhere());   
}

不过,您可以使用正则表达式来改善位置搜索。对于单词词缀:

\bwhere\b

但是同样,这个版本也存在缺陷,例如set col = ' test where test'

正确的方法是通过解析器(https://github.com/JSQLParser/JSqlParser)解析整个sql。