如何使用C#提取普通SQL查询的参数及数据类型并实现动态赋值
实现方案
提取SQL参数与对应数据类型
通过正则匹配SQL语句中的DECLARE声明段,即可提取参数名和对应的SQL数据类型,再映射为C#中SqlDbType枚举值,示例代码如下:
using System.Text.RegularExpressions; using System.Collections.Generic; using System.Data.SqlClient; using System.Data; // 原始SQL字符串 string rawSql = @"Declare @param1 int Declare @param2 varchar(255) Select * from tablename where col1 = @param1 and col2 = @param2"; // 匹配DECLARE参数的正则,忽略大小写 var paramRegex = new Regex(@"Declare\s+@(\w+)\s+([\w\(\)]+)", RegexOptions.IgnoreCase); var matches = paramRegex.Matches(rawSql); // 存储参数名和对应类型的字典 Dictionary<string, SqlDbType> paramTypeMap = new Dictionary<string, SqlDbType>(); foreach (Match match in matches) { string paramName = match.Groups[1].Value; string sqlTypeStr = match.Groups[2].Value.ToLower(); // 映射SQL类型到C# SqlDbType枚举,可按需补全所有用到的类型 SqlDbType dbType = sqlTypeStr switch { "int" => SqlDbType.Int, string s when s.StartsWith("varchar") => SqlDbType.VarChar, string s when s.StartsWith("nvarchar") => SqlDbType.NVarChar, "datetime" => SqlDbType.DateTime, "bit" => SqlDbType.Bit, "decimal" => SqlDbType.Decimal, _ => throw new NotSupportedException($"不支持的SQL类型:{sqlTypeStr}") }; paramTypeMap.Add($"@{paramName}", dbType); }
动态为参数赋值并执行查询
提取参数后,直接把参数添加到SqlCommand的参数集合中,根据参数名动态赋值即可,示例代码如下:
// 可选:移除SQL中的DECLARE声明段,只保留核心查询逻辑 string querySql = Regex.Replace(rawSql, @"Declare\s+@\w+\s+[\w\(\)]+\s*", "", RegexOptions.IgnoreCase).Trim(); using (SqlConnection conn = new SqlConnection("你的数据库连接字符串")) { conn.Open(); using (SqlCommand cmd = new SqlCommand(querySql, conn)) { // 遍历提取到的参数动态赋值 foreach (var paramItem in paramTypeMap) { // 可替换为实际业务中的取值逻辑,比如从用户输入、配置、业务对象中取值 object paramValue = paramItem.Key switch { "@param1" => 1001, "@param2" => "测试查询值", _ => DBNull.Value }; cmd.Parameters.Add(paramItem.Key, paramItem.Value).Value = paramValue; } // 执行查询,可按需替换为ExecuteNonQuery、ExecuteScalar等方法 using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { // 处理查询结果逻辑 } } } }
注意事项
- 若你的SQL没有显式写
DECLARE声明,可通过查询数据库系统表(如sys.columns、sys.tables)获取查询条件对应字段的数据类型,再关联匹配参数 - 请根据你实际用到的SQL数据类型补全类型映射逻辑,避免出现不支持的类型异常
- 所有参数通过
SqlParameter赋值,无需拼接SQL字符串,可完全规避SQL注入风险
内容的提问来源于stack exchange,提问作者Kamweti C
相关产品推荐
相关产品推荐

