使用正则表达式匹配SQL查询

时间:2017-02-01 23:09:38

标签: c# sql regex

我希望匹配可能具有不同参数的相同类型的SQL查询。例如

SELECT Name 
FROM Production.Product 
WHERE Name = 'Bearing Ball' and ProductNumber = 'BA-8327'

SELECT Name 
FROM Production.Product 
WHERE Name = 'Cycle' and ProductNumber = 'CY-1234'

是具有不同参数的相同类型的查询。基本上任何东西都可以代替第一个例子中的“Bearing Ball”和“BA-8327”。参数可以是字符串,数字或日期,包含或不包含空格。我尝试了以下表达式:

var result = new Regex("SELECT Name FROM Production.Product WHERE Name = '*' and ProductNumber = '*'").IsMatch(query)

它没有按预期工作。请给我一个解决方案。

3 个答案:

答案 0 :(得分:2)

*不是通配符。我将其替换为('([^']|'')*'|\d+),其匹配单引号字符串,其中包含'以外的字符或顺序''(转义单引号)0次或更多次。或者,它匹配一个或多个连续数字。

之前的帖子(已删除)提到转义.通配符。这是一个很好的建议,我已经更新了我的答案以反映这一点。

var result = new Regex(@"SELECT Name FROM Production\.Product WHERE Name = ('([^']|'')*'|\d+) and ProductNumber = ('([^']|'')*'|\d+)").IsMatch(query);

答案 1 :(得分:1)

这是一个在正则表达式解析后将所有重要数据转换为动态实体的系统。这样您就可以确定操作是否相同。否则,您可以查看模式并向您添加内容以正确读取数据,例如使用\x27([^\x27]+)\x27匹配'Bearing Ball',以满足您的模式需求。

string pattern = @"
^                     # Start of the line
select\s              # Anything not in brackets do not capture.
(?<What>[^\s]+)       # Capture a name most likely
\sfrom\s
(?<Table>[^\s]+)      # Capture Table name
\swhere\s
\1                    # Name(?) the what, must be used again
\s*=\s*
\x27                  # \x27 is a single quote '
(?<Name>[^\x27]+)     # Read up to the next quote for the what.
\x27
\s+and\s+ProductNumber\s*=\s*
\x27
(?<ProdNumber>[^\x27]+)  # Read up to the next quote for the product number.
";

string data = @"
SELECT Name FROM Production.Product WHERE Name = 'Bearing Ball' and ProductNumber = 'BA-8327'
SELECT Name FROM Production.Product WHERE Name = 'Cycle' and ProductNumber = 'CY-1234'
";

// IgnorePatternWhitespace lets us space out and comment the pattern code only. Does not affect regex processing.
Regex.Matches(data, pattern, RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline)
     .OfType<Match>()
     .Select(mat => new
     {
        Table = mat.Groups["Table"].Value,
        What = mat.Groups["What"].Value,
        Name  = mat.Groups["Name"].Value,
        ProductNumber = mat.Groups["ProdNumber"].Value
     });

2个动态实体的结果

enter image description here

答案 2 :(得分:0)

看看Arvind Shyamsundar在MSDN上发布的博客,这正是您正在寻找的,可以进行更多调整。它使用ScriptDom类,Microsoft自己的T-SQL解析器和生成器代码,这似乎比尝试自己解析像T-SQL这样复杂的语言要好得多。 Normalizing T-SQL text using the transactsql scriptdom classes

要知道一组名为ScriptDom的类存在于两个不同的命名空间中。您应该使用的那个随SQL Server一起提供SQL Server 2012,其名称空间为Microsoft.SqlServer.TransactSql.ScriptDom。名称空间为Microsoft.Data.Schema.ScriptDom的版本是较旧的,效力较低的版本,曾经随Visual Studio一起提供。你不应该在任何新项目中使用后者。