c# - 使用正则表达式扫描 T-SQL 的对象依赖关系

标签 c# sql regex

我正在编写一个 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/

相关文章:

c# - 具有决策 "Contact Us"的类 eBay "workflow"系统的架构指南

c# - 高斯模糊C#实现(类似OpenCV)

C# Selenium 如何在不使用 pageup/pgdn 的情况下滚动可滚动的 div,而不是整个网页

mysql - SQL 逻辑不等于

Javascript 替换函数不适用于正则表达式

c# - 如何过滤二维列表?

mysql - 如何从字符串中的第一个 Y 之后获取 X 个字符

mysql - 如何使用 union 设置列名称

c++ - 使用 boost::regex 时如何指定回车符和换行符匹配?

arrays - Perl 6 中正则表达式中 <> 和匿名数组的特殊含义