1

我正在尝试使用以下方法解析 SQL 查询:

SqlDataReader reader = command.ExecuteReader(CommandBehavior.KeyInfo);
DataTable schemaTable = reader.GetSchemaTable();

我得到基表名称,但我还需要找到表别名。

示例查询:

select AuthorId, a.Name as [AuthorName], c.Name as City, s.Name as [State] from Author a
inner join Zipcode zc on zc.ZipCodeId = a.ZipCodeId
inner join City c on c.CityId = zc.CityId
inner join [State] s on s.StateId = c.StateId

我检查了正则表达式解决方案,但无法弄清楚如何提取“Author a”、“ZipCode cd”、“City c”、“[State] s”

4

1 回答 1

0

使用 Regex 类型语法时必须考虑的定义。

元字符

元字符指定用户可以在相应位置输入的字符。

特点 描述
. 任何单个字符。
[aeiou] 指定字符集中的任何单个字符。
[^aeiou] 任何不属于指定字符集的单个字符。
[0-9a-fA-F] 指定字符范围内的任何单个字符。
\w 任何单个字母数字字符。一样[a-zA-Z_0-9]
\W 任何单个非字母数字字符。一样[^a-zA-Z_0-9]
\d 任何单个数字字符。一样[0-9]
\D 任何单个非数字字符。一样[^0-9]
量词

量词跟在元字符后面,并指定该字符应重复多少次。下表列出了可用的限定符。

量词 描述 例子
* 零个或多个匹配。一样{0,} [a-zA-Z],\w
+ 一场或多场比赛。一样{1,} [a-zA-Z]+,\w+
? 零个或一个匹配。一样{0,1} [a-zA-Z]?,\w?
{n} 正好 n 匹配。 [0-9]{2}
{n,} 至少 n 次匹配。 [0-9]{2,}
{n,m} 至少 n 个,但不超过 m 个匹配项。 [0-9]{2,7}

可以提供帮助的解决方案。

1. 使用 Regex 从 SQL 语句中提取表名

正则表达式

/(from|join|into)\s+([`]*\w*.*\w[`]|(\[)*\w*.*(\])|\w*\.*\w*)/g
2.使用Regex从SQL语句中提取表名和别名

正则表达式

(from|join|into)\s+([`]*\w*.*\w[`] *\w*|(\[)*\w*.*(\]) *\w*|\w*\.*\w* *\w*)
3. 使用 Regex 从 SQL 语句中提取列名

正则表达式

/(\w*\.*\w+|`\w*.*\w`|(\[)\w*.*(\]))+(,|\s+,|\s+FROM|\s+from)/g

为 C# 生成的代码

public static class QueryExtension
    {
        public static List<string> GetTables(this string query)
        {
            List<string> tables = new List<string>();
            string pattern = @"(from|join|into)\s+([`]*\w*.*\w[`]|(\[)*\w*.*(\])|\w*\.*\w*)";            
            
            foreach (Match m in Regex.Matches(query, pattern))
            {                
                string name = m.Groups[2].Value;                                
                tables.Add(name);
            }

            return tables;
        }
        public static List<string> GetTablesWithAliases(this string query)
        {
            List<string> tables = new List<string>();
            string pattern = @"(from|join|into)\s+([`]*\w*.*\w[`] *\w*|(\[)*\w*.*(\]) *\w*|\w*\.*\w* *\w*)";

            foreach (Match m in Regex.Matches(query, pattern))
            {
                string name = m.Groups[2].Value;
                tables.Add(name);
            }

            return tables;
        }
        public static List<string> GetColumns(this string query)
        {
            List<string> columns = new List<string>();
            string pattern = @"(\w*\.*\w+|`\w*.*\w`|(\[)\w*.*(\]))+(,|\s+,|\s+FROM|\s+from)";

            foreach (Match m in Regex.Matches(query, pattern))
            {
                string name = m.Groups[1].Value;
                columns.Add(name);
            }

            return columns;
        }
        public static string Join(this IEnumerable<string> values, string separator) {
            return string.Join(separator, values);
        }
    }

测试字符串

-------------------------------------------------------
select AuthorId, a.Name as [AuthorName], c.Name as City, s.Name as [State] from Author a
inner join `dbo`.`otherTable` ot on ot.col1 = a.Name
inner join Zipcode zc on zc.ZipCodeId = a.ZipCodeId
inner join City c on c.CityId = zc.CityId
inner join [State] s on s.StateId = c.StateId
-------------------------------------------------------

输出

//-------GetTables------
Author
`dbo`.`otherTable`
Zipcode
City
[State]
//-------GetTablesWithAliases------
Author a
`dbo`.`otherTable` ot
Zipcode zc
City c
[State] s

C# 的更多代码示例(此处)
https://stackoverflow.com/a/68889908/16731336

参考

使用 Regex 正则表达式语言从 SQL 语句中提取表名
- 快速参考
简化正则表达式

于 2021-08-23T14:40:37.803 回答