You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#如何获取SQL查询声明的参数与数据类型并实现动态赋值

解决方案

提供两种可直接落地的实现思路,可根据你的场景选择:


方式1:正则匹配解析SQL文本(轻量无需额外数据库请求)

适合SQL格式规范的简单场景,不需要额外访问数据库就能直接解析参数:

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

// 你的原始SQL文本
string rawSql = @"Declare @param1 int =1
Declare @param2 varchar(255)='Admin'
SELECT * FROM tblUsers WHERE role=@param2 AND id=@param1";

// 忽略大小写匹配DECLARE声明的参数名和数据类型
Regex paramRegex = new Regex(@"DECLARE\s+@(?<paramName>\w+)\s+(?<dataType>\w+)", RegexOptions.IgnoreCase);
MatchCollection matches = paramRegex.Matches(rawSql);

// 存储解析后的参数名和对应数据类型
Dictionary<string, string> paramDict = new Dictionary<string, string>();
foreach (Match match in matches)
{
    string paramName = "@" + match.Groups["paramName"].Value;
    string dataType = match.Groups["dataType"].Value;
    paramDict.Add(paramName, dataType);
    // 可直接输出符合你要求的格式
    Console.WriteLine($"{paramName,-12} {dataType}");
}

方式2:调用SQL Server系统能力解析(100%准确无误差)

完全依赖SQL Server引擎解析,不会出现正则误匹配问题,适合SQL逻辑复杂、有嵌套/注释的场景:

using System;
using System.Collections.Generic;
using System.Data.SqlClient;

string connStr = "你的数据库连接字符串";
string rawSql = @"Declare @param1 int =1
Declare @param2 varchar(255)='Admin'
SELECT * FROM tblUsers WHERE role=@param2 AND id=@param1";

Dictionary<string, string> paramDict = new Dictionary<string, string>();

using (SqlConnection conn = new SqlConnection(connStr))
{
    conn.Open();
    // 把原始SQL包装为临时存储过程
    string createTempProcSql = $@"
CREATE PROCEDURE #TempParseParams
AS
BEGIN
    {rawSql}
END
";
    using (SqlCommand cmd = new SqlCommand(createTempProcSql, conn))
    {
        cmd.ExecuteNonQuery();
    }

    // 从系统表查询临时存储过程的参数信息
    string queryParamSql = @"
SELECT name, system_type_name
FROM tempdb.sys.parameters
WHERE object_id = OBJECT_ID('tempdb..#TempParseParams')
";
    using (SqlCommand cmd = new SqlCommand(queryParamSql, conn))
    {
        using (SqlDataReader reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                string paramName = reader.GetString(0);
                string dataType = reader.GetString(1);
                // 去掉数据类型后的长度标识,比如把varchar(255)转为varchar
                if (dataType.Contains("("))
                {
                    dataType = dataType.Split('(')[0];
                }
                paramDict.Add(paramName, dataType);
                Console.WriteLine($"{paramName,-12} {dataType}");
            }
        }
    }

    // 清理临时存储过程
    using (SqlCommand cmd = new SqlCommand("DROP PROCEDURE #TempParseParams", conn))
    {
        cmd.ExecuteNonQuery();
    }
}

动态赋值实现

拿到参数字典后,遍历字典即可动态生成文本框控件,把每个文本框的Tag属性绑定对应参数名,用户输入完成后可选两种处理方案:

  • 直接替换原始SQL中DECLARE语句的默认值为用户输入的内容,再整体执行SQL
  • 去掉原始SQL的DECLARE部分,直接用SqlParameter类给查询传参,安全性更高可避免SQL注入,示例代码如下:
// userInputDict为你收集的用户输入值,key是参数名,value是用户输入的值
string execSql = "SELECT * FROM tblUsers WHERE role=@param2 AND id=@param1";
using (SqlCommand cmd = new SqlCommand(execSql, conn))
{
    foreach (var param in paramDict)
    {
        cmd.Parameters.AddWithValue(param.Key, userInputDict[param.Key]);
    }
    // 执行查询处理结果即可
    using (var reader = cmd.ExecuteReader())
    {
        // 处理查询结果
    }
}

内容的提问来源于stack exchange,提问作者Kamweti C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 14:54:02