【问题标题】:Getting WHERE clause after Update statement在 Update 语句之后获取 WHERE 子句
【发布时间】:2019-11-01 12:54:06
【问题描述】:

我需要在更新语句之后获取 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. 检查 where 单词是否在 ' ' 或 " " 之间(例如 bio = "This is where my bio is")并跳过它以移动到不在引号内的单词。这将有助于消除在 SET 值中找到的 where 词。当然,围绕字符串的 Java 引号不适用,因为它们不是字符串本身的一部分。
  2. 检查单词 where 是否夹在空格之间(例如 ... WHERE ...)。这将有助于消除在表名或列名中发现的 where 字(SQL 语法本身不能允许表名或列名单独作为保留字)。
  3. 最后,返回所需 WHERE 的索引以获取子字符串(问题的目标)。

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

【问题讨论】:

  • 您需要将查询分解为标记,其中字符串文字是单个标记。那么 WHERE 子句的 WHERE 将是一个标记,而字符串文字中的 where 则不是(因为它是更大标记的一部分)。
  • 正则表达式 "\s+WHERE\s+" 以确保 "where" 是整个单词但 Mark 的注释更合适。
  • 这样的事情需要标记化。

标签: java mysql


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    使用 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());   
    }
    

    但是,您可以通过使用正则表达式来改进 where 搜索,例如对于单词边界:

    \bwhere\b
    

    但你又是对的,这个版本也有缺陷,例如set col = ' test where test'

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-10
      • 1970-01-01
      • 1970-01-01
      • 2012-11-20
      • 2010-12-12
      • 2018-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多