项目中一个小需求,3个正则表达式匹配SQL表名,需要通过C#代码提取出数据访问层执行的SQL里面涉及的表名,用于记录一些日志相关的内容,因为是比较老的项目,数据访问层完全是ado.net的写法,并没有使用像ef core这种高级的ORM来辅助进行持久化。
正则表达式匹配SQL表名
如果想从数据访问层(或者持久层做的事情)里面提取出SQL,对于ef core来说则是非常方便的,本站之前就有类似的文章介绍。EF Core获取上下文SQL语句。
现在遇到的需求就是一个简单的提取各类语句,如select,update,delete,insert,简单来说就是将增删改查涉及到的SQL里面,将表名提取出来,如果用字符串截取等方式比较灯烦,这种脏活,累活就交给正则表达式来完成吧。废话不说了,直接上代码拿去用。
核心代码
/// <summary> /// 从SQL语句里面解析出写入,更新,删除的表名 /// </summary> /// <param name="sql"></param> /// <returns></returns> private static List<string> GetTables(string sql) { var insert = @"[\s\t]*INSERT [\s\t\r\n]*(INTO|)[\s\t\r\n]*[A-Za-z0-9_.""\[\]]*[\s\t\r\n]*"; var update = @"[\s\t]*UPDATE [\s\t\r\n]*(SET|)[\s\t\r\n]*[A-Za-z0-9_.""\[\]]*[\s\t\r\n]*"; var delete = @"[\s\t]*DELETE *(FROM|)[\s\t\r\n]*(WHERE|)[\s\t\r\n]*[A-Za-z0-9_.""\[\]]*[\s\t\r\n]*"; List<string> list = new List<string>(); var m = Regex.Matches(sql, insert, RegexOptions.IgnoreCase); foreach (Match item in m) { list.Add(item.Value.Trim()); } var m2 = Regex.Matches(sql, update, RegexOptions.IgnoreCase); foreach (Match item in m2) { list.Add(item.Value.Trim()); } var m3 = Regex.Matches(sql, delete, RegexOptions.IgnoreCase); foreach (Match item in m3) { list.Add(item.Value.Trim()); } return list.Select(x => { return x.Substring(x.LastIndexOf(' ')).Trim(); }).Distinct().ToList(); }
完整代码
class Program { static void Main(string[] args) { var sql = @" UPDATE jhrs.com SET [Id] = <Id, uniqueidentifier,> ,[Name] = <Name, varchar(50),> ,[xSql] = <xSql, text,> ,[Num] = <Num, int,> ,[Tag] = <Tag, varchar(50),> ,[Gec] = <Gec, text,> ,[Key] = <Key, varchar(50),> WHERE <搜索条件,,> GO INSERT znlive.net ([Id] ,[Key] ,[UserId] ,[Message] ,[ErrorUrl] VALUES ('') GO DELETE FROM [dbo].[Sys_Manage] WHERE <搜索条件,,> GO "; var list = GetTables(sql); foreach (var item in list) { Console.WriteLine(item); } } /// <summary> /// 从SQL语句里面解析出写入,更新,删除的表名 /// </summary> /// <param name="sql"></param> /// <returns></returns> private static List<string> GetTables(string sql) { var insert = @"[\s\t]*INSERT [\s\t\r\n]*(INTO|)[\s\t\r\n]*[A-Za-z0-9_.""\[\]]*[\s\t\r\n]*"; var update = @"[\s\t]*UPDATE [\s\t\r\n]*(SET|)[\s\t\r\n]*[A-Za-z0-9_.""\[\]]*[\s\t\r\n]*"; var delete = @"[\s\t]*DELETE *(FROM|)[\s\t\r\n]*(WHERE|)[\s\t\r\n]*[A-Za-z0-9_.""\[\]]*[\s\t\r\n]*"; List<string> list = new List<string>(); var m = Regex.Matches(sql, insert, RegexOptions.IgnoreCase); foreach (Match item in m) { list.Add(item.Value.Trim()); } var m2 = Regex.Matches(sql, update, RegexOptions.IgnoreCase); foreach (Match item in m2) { list.Add(item.Value.Trim()); } var m3 = Regex.Matches(sql, delete, RegexOptions.IgnoreCase); foreach (Match item in m3) { list.Add(item.Value.Trim()); } return list.Select(x => { return x.Substring(x.LastIndexOf(' ')).Trim(); }).Distinct().ToList(); } }
运行效果
经过测试,上面的代码是可以达到要求,只是如果你有更简单的写法,欢迎留言反馈。