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

从多选ListBox构建SQL IN语句查询无结果且无报错问题排查

问题分析与解决方案

先帮你拆解下代码里的问题,以及可能导致无数据返回的原因:

1. 冗余的变量定义

你连续写了两次StringBuilder sb = new StringBuilder("SELECT ... WHERE ");,这会直接覆盖第一个实例的内容,虽然这次逻辑上没影响结果,但属于无效冗余代码,建议删掉重复的那行。

2. 直接拼接SQL字符串的隐患

你直接把ListBox选中项的文本用单引号包裹后拼进IN语句,这里有两个核心问题:

  • SQL注入风险:如果员工姓名里包含单引号(比如O'Conner),会直接导致SQL语法错误;就算当前没遇到这种情况,这也是严重的安全漏洞。
  • 匹配精度问题:如果ListBox的Text和数据库中Emp_Name的内容存在大小写差异、首尾空格(比如ListBox显示张三,数据库里是张三),会直接导致匹配失败,查不到数据。

3. 边界情况未处理

如果ListBox没有选中任何项,InPartQuery会是空字符串,最终SQL会变成WHERE Emp_Attend.Emp_Name IN (),这是非法的SQL语法——虽然你说没有报错,但可能你的场景里默认有选中项,但这个逻辑漏洞必须修复。


修正后的参数化查询代码

我给你改成参数化查询的写法,既解决上述问题,又能保证安全和稳定性:

// 修复重复定义问题,用多行字符串让SQL更易读
StringBuilder sb = new StringBuilder(@"
    SELECT * 
    FROM Emp_Attend 
    LEFT JOIN Employees ON Emp_Attend.Emp_ID = Employees.EmpID 
    WHERE 1=1 "); // 用1=1简化后续条件拼接逻辑

using (SqlCommand cmdSQL = new SqlCommand())
{
    // 提取选中的项文本
    var selectedNames = ListBox1.Items
        .Cast<ListItem>()
        .Where(t => t.Selected)
        .Select(r => r.Text)
        .ToList();

    if (selectedNames.Any())
    {
        // 构建参数化的IN语句
        var parameters = new List<SqlParameter>();
        sb.Append("AND Emp_Attend.Emp_Name IN (");
        for (int i = 0; i < selectedNames.Count; i++)
        {
            var paramName = $"@EmpName{i}";
            sb.Append(i == 0 ? paramName : $", {paramName}");
            parameters.Add(new SqlParameter(paramName, selectedNames[i]));
        }
        sb.Append(")");
    }
    // 没有选中项时,可以根据需求调整:比如返回所有数据,或者加提示

    cmdSQL.CommandText = sb.ToString();
    cmdSQL.Connection = sqlcon;
    cmdSQL.Parameters.AddRange(parameters.ToArray());

    SqlDataAdapter da = new SqlDataAdapter(cmdSQL);
    DataTable dtbl = new DataTable();
    da.Fill(dtbl);

    // 不需要手动关闭连接:da.Fill会自动处理连接状态(关闭时打开,执行后关闭;已打开则保持打开)
    // sqlcon.Close(); 

    gvEmployees.DataSource = dtbl;
    gvEmployees.DataBind();
}

额外排查点(如果调整后仍无数据)

  • 把生成的SQL语句复制到SQL Server Management Studio中执行,确认数据库本身是否存在符合条件的数据。
  • 检查ListBox的Text与数据库Emp_Attend.Emp_Name的实际值是否完全一致(包括大小写、空格),可以考虑用LTRIM(RTRIM(Emp_Attend.Emp_Name))去除空格后匹配,或者在ListBox绑定阶段就统一文本格式。
  • 确认关联条件Emp_Attend.Emp_ID = Employees.EmpID是否正确,有没有因为关联错误导致数据被过滤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:28:46