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

C#使用CheckBoxComboBox多选时SQL出现类型转换错误如何解决?

问题根因

报错的核心原因是你将带逗号和引号的拼接字符串作为单个nvarchar类型参数传入SQL,IN子句不会把该参数内部的逗号、引号识别为值分隔符,只会将整个字符串尝试转换为int类型和workdayID字段匹配:单选时单个值可以正常转int,多选时整个字符串无法转换,就触发报错。

解决方案

方案1:使用表值参数(推荐,SQL Server 2008及以上版本支持,无注入风险)

这是最规范的多值传参方案:

  1. 先在SQL Server中创建自定义表类型:
CREATE TYPE IntList AS TABLE (Value INT);
  1. 修改查询/存储过程,调整参数类型和IN子句逻辑:
-- 存储过程参数定义改为 @workdayIDList IntList READONLY
SELECT TOP 500 npt.ID, l.name, nt.taskname,  FORMAT(npt.reportingDate, 'MMM-dd-yyy') AS [PHT Reporting Date],  FORMAT(npt.estReportingDate, 'MMM-dd-yyy') AS [EST Reporting Date], 
npt.remarks, FORMAT(npt.startDate, 'h:mm tt') AS [PHT Start Date], FORMAT(npt.endDate, 'h:mm tt') AS [PHT End Date], FORMAT(npt.estStartDate, 'h:mm tt') AS [EST Start Date], 
FORMAT(npt.estEndDate, 'h:mm tt') AS [EST End Date], npt.duration, npt.estDuration, npt.status
FROM tbl_DT_NonProcessingTime npt
    INNER JOIN tbl_DT_NPTTask nt ON nt.ID = npt.taskID
    INNER JOIN tbl_DT_Login l ON l.workdayID = npt.workdayID
WHERE npt.workdayID IN (SELECT Value FROM @workdayIDList)
    ORDER BY npt.id DESC
  1. C#侧直接读取选中项的ID构造参数,无需拼接字符串:
// 读取CheckBoxComboBox选中的所有workdayID,注意替换为你实际绑定的字段名
var selectedIds = checkBoxComboBox1.CheckedItems.Cast<DataRowView>()
    .Select(row => int.Parse(row["workdayID"].ToString()))
    .ToList();

// 构造表值参数对应的DataTable
DataTable idTable = new DataTable();
idTable.Columns.Add("Value", typeof(int));
foreach (int id in selectedIds)
{
    idTable.Rows.Add(id);
}

// 构造SQL参数
SqlParameter workdayParam = new SqlParameter("@workdayIDList", SqlDbType.Structured)
{
    TypeName = "dbo.IntList",
    Value = idTable
};

方案2:字符串拆分方案(兼容低版本SQL Server)

如果无法使用表值参数,可以在SQL侧拆分传入的逗号分隔字符串:

  1. C#侧仅传递纯数字逗号分隔字符串,无需加引号:
string split = Regex.Replace(checkBoxComboBox1.Text, "[A-Za-z ()ñ.+-]", "");
objNPTBEL.workdayidlist = split; // 最终传参值示例:415073,415072
  1. SQL侧拆分字符串后转int再匹配,SQL Server 2016及以上可以直接用内置的STRING_SPLIT函数:
WHERE npt.workdayID IN (SELECT CAST(value AS INT) FROM STRING_SPLIT(@workdayIDList, ','))

如果SQL Server版本低于2016,自行编写一个拆分字符串为表的自定义函数替换STRING_SPLIT即可。

方案3:动态拼接SQL(仅应急使用,存在SQL注入风险)

如果仅做内部工具、能确保所有选中ID都是合法数字,可以直接把ID列表拼到SQL语句中,不使用参数传递IN子句内容:

// 校验所有选中ID为int类型,避免注入风险
var selectedIds = checkBoxComboBox1.CheckedItems.Cast<DataRowView>()
    .Select(row => int.Parse(row["workdayID"].ToString()))
    .ToList();
// 直接拼接SQL
string querySql = $@"SELECT TOP 500 ... WHERE npt.workdayID IN ({string.Join(",", selectedIds)}) ORDER BY npt.id DESC";

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 20:57:06