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

ADO.NET查询无返回结果:存在匹配数据却无输出问题排查

问题原因

你遇到的问题核心在于错误地将多个ID拼接成单个字符串参数传递给IN子句。从SQL Profiler捕获的语句能看到,@list被当作一个完整的字符串值'50','23','100'传入,SQL Server会把这个整体当成单一匹配项和Id字段对比——而你的Employees表里显然没有等于这个完整字符串的Id,所以不会返回任何结果。

解决方法

下面提供几种安全且有效的解决方式:

方法1:使用表值参数(推荐,避免SQL注入)

这是SQL Server 2008及以上版本的规范做法:

  1. 先在SQL Server中创建用户定义表类型:
CREATE TYPE dbo.IdList AS TABLE (Id VARCHAR(50))
  1. 修改C#代码,将列表数据传入表值参数:
public List<string> GetRecords(List<string> itemList)
{
    itemList.Add("100");
    List<string> employeeList = new List<string>();

    using (var tvp = new DataTable())
    {
        tvp.Columns.Add("Id", typeof(string));
        foreach (var id in itemList)
        {
            tvp.Rows.Add(id);
        }

        string query = @"SELECT Id FROM Employees WHERE Id IN (SELECT Id FROM @list)";
        using (SqlCommand sqlCommand = new SqlCommand(query, connection))
        {
            sqlCommand.Parameters.Add(new SqlParameter("@list", SqlDbType.Structured)
            {
                TypeName = "dbo.IdList",
                Value = tvp
            });

            using (var sqlDataReader = sqlCommand.ExecuteReader())
            {
                while (sqlDataReader.Read())
                {
                    employeeList.Add(Convert.ToString(database.Sanitise(sqlDataReader, "Id")));
                }
            }
        }
    }
    return employeeList;
}

方法2:逐个添加参数(适合小批量ID)

如果不想创建表类型,可以为每个ID单独添加参数:

public List<string> GetRecords(List<string> itemList)
{
    itemList.Add("100");
    List<string> employeeList = new List<string>();
    List<SqlParameter> parameters = new List<SqlParameter>();

    string placeholders = string.Join(", ", itemList.Select((_, index) => $"@id{index}"));
    string query = $"SELECT Id FROM Employees WHERE Id IN ({placeholders})";

    using (SqlCommand sqlCommand = new SqlCommand(query, connection))
    {
        for (int i = 0; i < itemList.Count; i++)
        {
            var param = new SqlParameter($"@id{i}", SqlDbType.VarChar);
            param.Value = itemList[i];
            sqlCommand.Parameters.Add(param);
        }

        using (var sqlDataReader = sqlCommand.ExecuteReader())
        {
            while (sqlDataReader.Read())
            {
                employeeList.Add(Convert.ToString(database.Sanitise(sqlDataReader, "Id")));
            }
        }
    }
    return employeeList;
}

方法3:使用STRING_SPLIT(SQL Server 2016+)

如果你的SQL Server版本支持STRING_SPLIT函数,可以将ID列表作为无引号字符串传入后拆分:

public List<string> GetRecords(List<string> itemList)
{
    itemList.Add("100");
    List<string> employeeList = new List<string>();
    string idList = string.Join(",", itemList);

    string query = @"SELECT Id FROM Employees WHERE Id IN (SELECT value FROM STRING_SPLIT(@list, ','))";
    using (SqlCommand sqlCommand = new SqlCommand(query, connection))
    {
        sqlCommand.Parameters.AddWithValue("@list", idList);
        using (var sqlDataReader = sqlCommand.ExecuteReader())
        {
            while (sqlDataReader.Read())
            {
                employeeList.Add(Convert.ToString(database.Sanitise(sqlDataReader, "Id")));
            }
        }
    }
    return employeeList;
}

注意:若Id是数值类型,需在拆分后转换类型,比如SELECT CAST(value AS INT) FROM STRING_SPLIT(...)。

额外注意事项
  • 确保connection对象在使用前已调用connection.Open()打开
  • 确保employeeList在方法内正确初始化,避免空引用
  • 始终避免直接拼接SQL字符串,防止SQL注入风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 18:54:24