5

是否有从字符串中提取 SQL 查询的正则表达式?我对验证任何 SQL 语法感兴趣,而只是提取 SQL 命令的选择。这以灵活的方式解析给定的 SQL 文件/字符串。

给出以下 SQL 文件/字符串示例:

SELECT
    *
FROM
    test_table
WHERE
    test_row = 'Testing ; semicolon';

SELECT * FROM another_test_table;

INSERT INTO 
    table_name 
VALUES 
    (value1,'value which contains semicolon ;;;;',value3,...);

一些伪代码示例是:^(UPDATE|SELECT|INSERT INTO)(.*)(;)$. 将来我希望用所有(可能的)命令来扩展它。

  • 寻找与以下之一的起始匹配: (UPDATE|SELECT|INSERT|INTO)
  • 零个或多个any character(包括空格和换行符)
  • 停止于;,用于分隔 SQL 查询。

只要通过正则表达式可以做到这一点,以下 java 代码就能够提取所有 SQL 命令:

final String regex = "LOOKING_FOR_THIS_ONE";
final Pattern p = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = p.matcher(content);

while (matcher.find()) {
  // matcher.group() now contains the full SQL command
}

提前致谢!

4

5 回答 5

2

我首先要说这不是一个好方法,并强烈敦促您找到另一种方法,最好在声明的地方正确标记它,这样您就不会陷入这种情况.

话虽如此,SQL 要求它以下列之一开始;DELETE, SELECT,或. WITH_ 它还要求输入以.UPDATEINSERT INTO;

我们可以使用它来获取与 SQL 匹配的所有序列,如下所示:

final String regex = "^(INSERT INTO|UPDATE|SELECT|WITH|DELETE)(?:[^;']|(?:'[^']+'))+;\\s*$";
final Pattern p = Pattern.compile(regex, Pattern.MULTILINE | Pattern.DOTALL);

组 1 现在包含操作字,以防您希望在UPDATE或上过滤有效 SQL SELECT

请参阅实际的正则表达式,以及此处的警告:

https://regex101.com/r/dt9XTK/2

于 2013-05-21T15:04:38.003 回答
1

只要分号是该行的最后一个非空白字符,您就可以“正确”匹配它。

final String regex = ^(SELECT|UPDATE|INSERT)[\s\S]+?\;\s*?$

final Pattern p = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = p.matcher(content);
于 2013-05-21T14:46:58.533 回答
0

(?m)^(UPDATE|SELECT|INSERT INTO).*;$应该管用。这将扩展模式以匹配换行符。它应该能够遍历并找到您的所有 SQL。

查看您提供的示例,它将匹配您的命令,直到;. 您可以在此处查看用于测试的示例。

于 2013-05-21T14:36:24.190 回答
0

如果您正在处理一种语言,请创建一个词法分析器来标记您的字符串。使用JFlex,它是一个词法分析器生成器。它生成一个 Java 类,该类根据特殊文件中指定的语法将字符串拆分为标记。从这个文件中获取相关的语法规则。

解析是与标记化(或词法分析)不同的过程。如果词法分析还不够,您可能希望在词法分析之后使用解析器生成器。

于 2013-05-21T14:36:45.453 回答
0

SQL 非常复杂,以至于您需要上下文来查找所有语句,这意味着您不能使用正则表达式来执行此操作。

例如:

SELECT Model FROM Product
WHERE ManufacturerID IN (SELECT ManufacturerID FROM Manufacturer 
WHERE Manufacturer = 'Dell')

(示例来自http://www.sql-tutorial.com/sql-nested-queries-sql-tutorial/)。嵌套查询可以嵌套多次,从不同的值开始,等等。如果您可以为您感兴趣的子集编写一个正则表达式,它将是不可读的。

ANTLR有一个可用的SQL 2003 语法(我没试过)。

于 2013-05-21T17:24:35.527 回答