SQL查询中表列名替换及向DSL转换的正则实现技术咨询
SQL字段替换与DSL转换的正则实现方案
嘿,针对你提到的两个技术需求——替换SQL里的[TableName].[ColumnName]格式字符串,以及把SQL转成自定义DSL,用正则来实现完全可行,我给你拆解下具体的实现思路和代码示例:
核心需求回顾
- 替换SQL中
[TableName].[ColumnName]格式的字段 - 通过正则匹配不同表列(比如
Customer.RecordNumber、Customer.Forename),分别替换为$1*、$2*这类DSL标识
分步实现方案
1. 先处理带方括号的字段格式
首先得把[TableName].[ColumnName]这种带方括号的格式转换成我们好处理的TableName.ColumnName,用正则匹配最稳妥:
// 匹配[表名].[列名]格式,捕获表名和列名 var bracketRegex = new Regex(@"\[([^\]]+)\]\.\[([^\]]+)\]"); // 替换成不带括号的TableName.ColumnName sql = bracketRegex.Replace(sql, "$1.$2");
2. 动态匹配列并转换为DSL
你提到的FieldsUsed字典正好可以用来存储列名到DSL标识的映射,我们可以遍历这个字典,逐个生成正则规则来替换,这样能灵活扩展不同的列映射:
先假设你的字典已经配置好了映射关系:
Dictionary<string, string> FieldsUsed = new Dictionary<string, string> { {"Customer.RecordNumber", "$1*"}, {"Customer.Forename", "$2*"}, // 其他需要映射的列... };
然后遍历字典做替换,这里要注意单词边界和特殊字符转义,避免匹配到无关的子串或者正则语法错误:
foreach (var fieldMapping in FieldsUsed) { // 转义列名里的特殊字符(比如点号、下划线),防止正则出错 var escapedColumnName = Regex.Escape(fieldMapping.Key); // 用\b确保匹配完整的字段,不会把Customer.RecordNumber匹配成Customer.RecordNumberXXX var fieldRegex = new Regex($@"\b{escapedColumnName}\b"); sql = fieldRegex.Replace(sql, fieldMapping.Value); }
关于你提到的SQL拆分方案
你代码里用Split(' ')拆分SQL的方式不太靠谱,因为SQL里可能有带空格的字符串常量(比如WHERE Name = 'John Doe'),拆分后会把字符串拆成两半,反而会出问题,用正则匹配字段是更可靠的方式。
完整可运行的代码示例
using System; using System.Collections.Generic; using System.Text.RegularExpressions; public class SqlDslConverter { public string ConvertToDsl(string originalSql, Dictionary<string, string> fieldMappings) { // 第一步:处理带方括号的字段格式 var bracketPattern = @"\[([^\]]+)\]\.\[([^\]]+)\]"; string cleanedSql = Regex.Replace(originalSql, bracketPattern, "$1.$2"); // 第二步:替换为DSL格式 foreach (var mapping in fieldMappings) { string escapedField = Regex.Escape(mapping.Key); string replacePattern = $@"\b{escapedField}\b"; cleanedSql = Regex.Replace(cleanedSql, replacePattern, mapping.Value); } return cleanedSql; } } // 测试用例 class Program { static void Main() { var fieldMappings = new Dictionary<string, string> { {"Customer.RecordNumber", "$1*"}, {"Customer.Forename", "$2*"}, {"Order.Total", "$3*"} }; string sampleSql = @"SELECT [Customer].[RecordNumber], [Customer].[Forename], [Order].[Total] FROM [Customer] JOIN [Order] ON [Customer].[RecordNumber] = [Order].[CustomerId] WHERE [Customer].[Forename] = 'Alice'"; var converter = new SqlDslConverter(); string dslResult = converter.ConvertToDsl(sampleSql, fieldMappings); Console.WriteLine(dslResult); // 输出:SELECT $1*, $2*, $3* // FROM Customer // JOIN Order ON $1* = Order.CustomerId // WHERE $2* = 'Alice' } }
内容的提问来源于stack exchange,提问作者sanar
相关产品推荐
相关产品推荐

