我正在编写一个 c# 类库,它将允许我扫描 SQL 服务器查询并将查询中的对象提取到正确的分组中,例如:
SELECT * FROM "My Server"."Northwind"."dbo"."Product Sales for 1997" Group By CategoryID
此正则表达式将匹配上面的字符串并将“My Server”、“Northwind”、“dbo”和“Product Sales for 1997”分为四组,这正是我想要的。
(?i)\bFROM\b\s+[\["]([^\]"]*)[\]"].{1}[\["]([^\]"]*)[\]"].{1}[\["]([^\]"]*)[\]"].{1}[\["]([^\]"]*)[\]"].{1}
我正在寻找的是一个正则表达式,它可以捕获以下任何组合的服务器名称、数据库名称、模式名称和对象名称(这无论如何都不是详尽的列表):
SELECT * FROM dbo."Product Sales for 1997" // should return groups 2 & 3
SELECT * FROM Northwind."My Schema"."My view or table function" // should return groups 1, 2 & 3
SELECT * FROM "My view or table function" // should return group 3
SELECT * FROM dbo."My View 1" AS V1 JOIN "My View 1" AS V2 ON V1.ID = V2 // should return groups 2 & 3
换句话说,我想将各种组件分为以下几组:
组 0 --> 服务器名称
第 1 组 --> 数据库名称
第 2 组 --> 架构
第 3 组 --> 对象名称
我试图避免创建多个正则表达式来处理所有可能的组合,以避免我的类库变得太大和太复杂,但作为正则表达式 n00b,它被证明有点困难。
最佳答案
使用正则表达式可以做的最好的事情是将其解析为标记,然后必须确定组的实际情况(服务器数据库等)是什么。这是一个正则表达式,用于将您的数据示例放入此类标记中。请注意,我不知道 sql server 有引号,但您的示例要求它们,所以我使用 If 条件查找分别转义为\x22 和\x27 的单引号和双引号(请参阅我的博客文章 Regular Expressions and the If Conditional )。 token 被放置在提取它们的匹配捕获中。
string data =
@"SELECT * FROM dbo.""Product Sales for 1997"" // should return groups 2 & 3
SELECT * FROM Northwind.""My Schema"".""My view or table function"" // should return groups 1, 2 & 3
SELECT * FROM ""My view or table function"" // should return group 3
SELECT * FROM dbo.""My View 1"" AS V1 JOIN ""My View 1"" AS V2 ON V1.ID = V2 // should return groups 2 & 3 ";
string pattern =
@"
(?:FROM\s+) # Work from a from only
(
(?([\x27\x22]) # If a single or double quote is found
(?:[\x27\x22])
(?<Tokens>[\w\s]+) # process quoted text
(?:[\x27\x22]\.?)
| # else
(?!\s+AS|\s+WHERE) # if AS or Where is found stop the match we are done
(?:\.?)
(?<Tokens>\w+) # Process non quoted token.
(?:\.?)
)
(?![\n\r/]) # Stop on CR/LF or a comment.
){0,4} # Only do this 1 to 4 times, for it can't be more (parser hint to stop)
";
Regex.Matches(data, pattern, RegexOptions.IgnorePatternWhitespace) // Ignore is to allow commenting of the pattern only (not data processing)
.OfType<Match>()
.Select(mt => mt.Groups["Tokens"]
.Captures.OfType<Capture>()
.Select(cp => cp.Value))
.ToList() // To do the foreach below
.ForEach(tokens => Console.WriteLine(string.Join(" | ", tokens)));
/* Output
dbo | Product Sales for 1997
Northwind | My Schema | My view or table function
My view or table function
dbo | My View 1
*/
关于c# - 使用正则表达式扫描 T-SQL 的对象依赖关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8375646/