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

ExecuteNonQuery未解析传入参数 SQL参数值未生效问题排查

问题产生原因

SQL Server 的参数绑定机制仅支持在 DML 语句(SELECT/INSERT/UPDATE/DELETE)的值传入位置、存储过程/函数的传参位置识别参数占位符,DDL 语句(包括ALTER TABLE)的语法配置项位置不支持参数绑定。
你代码里把@retentionValue参数放在了HISTORY_RETENTION_PERIOD的配置值位置,这个位置属于ALTER TABLE DDL 语法的固定选项块,数据库引擎不会把这里的@retentionValue识别为待替换的参数占位符,会直接把它当做SQL文本的一部分解析,你传入的SqlParameter集合完全没有被执行逻辑读取,自然也不会把你传入的整型值写入配置。
执行没有报错的原因是,多数数据访问层组件执行DDL时如果发现SQL文本里没有匹配到传入参数的占位符,会直接忽略未使用的参数,不会抛出参数不匹配的异常。

修复方法

这个位置无法通过传参赋值,由于你已经通过ToInt()把保留周期值转换成了强类型整型,不存在SQL注入风险,可以直接把值拼接到SQL语句中,不需要传参:

if (request.SystemSettings.Any(s => s.SettingName.Equals("HISTORYRETENTIONDAYS")))
{
    var entities = entityRepo.GetList();

    var newRetentionLimit = request.SystemSettings.Find(setting => setting.SettingName.Equals("HISTORYRETENTIONDAYS")).SettingValue.ToInt();
    var requestContext = new RequestContext();

    foreach (var entity in entities)
    {
        // 整型值直接拼接,无注入风险
        var sql = $@"ALTER TABLE [data].[t{entity.Name}] SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [hist].[t{entity.Name}], HISTORY_RETENTION_PERIOD = {newRetentionLimit} DAYS));";
        requestContext.DatabaseContext.ExecuteNonQuery(sql);
    }
}

注意:除了DDL配置项,表名、列名、排序关键字(ASC/DESC)这类属于SQL语法结构、标识符的位置,都不支持参数绑定,动态生成这类内容时必须先校验值合法性,再直接拼接到SQL文本中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:06:21