拆分SQL语句

时间:2009-03-17 15:29:33

标签: sql mysql regex

我正在编写一个后端应用程序,它需要能够向MySQL服务器发送多个SQL命令。   MySQL> = 5.x支持多个语句,但不幸的是我们正在与MySQL 4.x接口。

我试图找到一种方法(提示:正则表达式)用分号分割SQL语句,但它应该忽略单引号和双引号字符串中的分号。

http://www.dev-explorer.com/articles/multiple-mysql-queries有一个非常好的正则表达式,但不支持双引号。

我很高兴听到你的建议。

5 个答案:

答案 0 :(得分:2)

无法使用正则表达式,它解析SQL的功能不够强大。可能有一个可用于您的语言的SQL解析器 - 它是什么? - 但解析SQL非常困难,特别是考虑到可用的不同语法范围。即使在MySQL中,服务器和连接级别上也有许多SQL_MODE标志可以影响基本字符串和注释的解析方式,使语句的行为完全不同。

dev-explorer的例子有趣地试图处理转义的撇号和尾随字符串,但是对于它们的许多有效组合仍然会失败,更不用说双引号,反引号,各种注释语法,或者ANSI SQL_MODE。

答案 1 :(得分:1)

正如bobince所说,正则表达式可能不会足够强大。他们肯定不会有足够的力量以任何中途优雅的方式去做。提供的第二个链接cdonner也没有解决这个问题;大多数答案都试图与提问者谈论没有分号;如果他已经接受了一般性的建议,那么他就会在你所在的地方结束。

我认为解决这个问题的最快捷途径是使用字符串扫描程序功能,它会按顺序检查字符串的每个字符,并根据存储的状态做出反应。粗糙的伪代码:

  1. 读入角色
  2. 如果角色不是特殊,则继续
  3. 如果角色被转义(检查这可能需要检查前一个角色),CONTINUE
  4. 如果字符会启动一个新字符串或结束现有字符串,则切换一个标志IN_STRING(您可能需要多个标志用于不同的字符串类型...我老实说尝试并成功地不知道SQL引用的细节/转义)和CONTINUE
  5. 如果字符是分号并且我们当前不在字符串中,我们找到了一个查询!输出它并继续扫描直到字符串结束。
  6. 语言解析不是我的任何经验领域,因此您需要仔细考虑这种方法;尽管如此,它会很快(使用C风格的字符串,这些步骤都不是很昂贵,可能除了OUTPUT,取决于你的上下文中“输出”的意思),我认为它应该完成工作。

答案 2 :(得分:1)

可能使用以下Java Regex?检查测试...

@Test
public void testRegexp() {
    String s = //
        "SELECT 'hello;world' \n" + //
        "FROM DUAL; \n" + //
        "\n" + //
        "SELECT 'hello;world' \n" + //
        "FROM DUAL; \n" + //
        "\n";

    String regexp = "([^;]*?('.*?')?)*?;\\s*";

    assertEquals("<statement><statement>", s.replaceAll(regexp, "<statement>"));
}

答案 3 :(得分:0)

我建议您查看是否可以重新定义问题空间,因此不需要发送仅由其终结符分隔的多个查询。

答案 4 :(得分:0)

试试这个。刚刚用'和'取代了第一''它似乎适用于'和' ; +(=([^ \“| ^ \\ '] [' | \\ '] [^' | ^ \\ '] [' | \\']) [^ '| ^ \\'] [^ '| ^ \\'] $)