【问题标题】:Search SQL database with multiple filters使用多个过滤器搜索 SQL 数据库
【发布时间】:2022-01-06 04:34:38
【问题描述】:

我有以下代码:

List<string> L1 = new List<string>();
int Id = 1;

using (SqlConnection conn = new SqlConnection())
{               
    conn.ConnectionString = "...";
    SqlCommand cmd = conn.CreateCommand();

    cmd.CommandText = "SELECT * FROM categories WHERE category_id = @Id";
    cmd.Parameters.Add(new SqlParameter("@Id", Id));
                                
    conn.Open();
                                
    SqlDataReader reader = cmd.ExecuteReader();
    while (reader.Read())
    {
        category = reader.GetString(1);
        L1.Add(category);
    }
}

这给了我 "category_id" 等于 1 的行。

我现在希望 SELECT 语句返回“category_id”等于我给它的值之一的行。

所以一个简单的 SELECT 语句看起来像这样

SELECT * FROM categories WHERE category_id = 1 or category_id = 2
//returns all rows where "category_id" is equal to 1 or 2

问题是我在设置 SELECT 语句时不知道要搜索的值。 我会将值放在字符串、列表或类似的东西中。

我尝试使用 foreach 循环来更改“Id”的值

cmd.Parameters.Add(new SqlParameter("@Id", typeof(int)));
foreach (int val in Values)
{
    cmd.Parameters["@Id"].Value = val;
}

但这只是返回“category_id”等于数组“Values”中最后一个值的行。

我曾尝试使用 IN 运算符,但出现错误

cmd.CommandText = "SELECT * FROM categories WHERE category_id IN (@Id)";
cmd.Parameters.Add(new SqlParameter("@Id", Values));
                

我的最后一个想法是使用循环从值中创建一个字符串。

string ValueString = "0";
foreach (int val in Values)
{
    ValueString += ",";
    ValueString += Convert.ToString(val);
}

我还没有尝试过这个,但我希望它会给出一个错误,因为列是“category_id”的数据类型是“int”。

有没有办法以数组/列表作为参数来搜索 SQL 数据库,所以它会给出与数组/列表中的一个值相等的每一行。

【问题讨论】:

标签: c# sql .net parameters ado.net


【解决方案1】:

您可以在命令中使用“IN”关键字:

SELECT * FROM categories WHERE category_id IN (1,2)

您的 CommandText 需要如下所示:

 cmd.CommandText = "SELECT * FROM categories WHERE IN (@Id)";

您可以像这样设置参数@ID:

cmd.Parameters.Add(new SqlParameter("@Id", string.Join(",", L1)));

在运行它之前,您只需将“1”和“2”添加到您的 L1-List 即可。

【讨论】:

  • 使用此方法会出现以下错误:“将 nvarchar 值 '1,2,3' 转换为数据类型 int 时转换失败。”。我能够找到解决方案。使用 string.Join() 并使命令文本成为格式化字符串。然后将 string.Join() 放在 { } 之间。
  • 还有一个不知道 SQL 参数是如何工作的。这样会发生什么,它将@Id 作为一个值。你想这样做,你需要每个值一个参数。
【解决方案2】:

cmd.CommandText = "SELECT * FROM categories WHERE IN (@Id)";

cmd.Parameters.Add(new SqlParameter("@Id", string.Join(",", L1)));

【讨论】:

  • 这不是参数的工作方式。无论您在@Id 中拥有什么,它都会将其视为一个值。
  • 这会导致转换错误,因为参数是 nvarchar 而列是 int
【解决方案3】:

您需要将其作为 DataTable 创建的 SqlParameter 传递。这并不难,但有点复杂。

那里有描述:

https://stackoverflow.com/a/43128585/11648657

但是 imo,最简单的方法是 Dapper。 查看答案:

https://stackoverflow.com/a/8388333/11648657

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
  • “您需要将其作为 DataTable 创建的 SqlParameter 传递” - 不,您不需要。为此,您实际上可以在没有数据表的情况下执行 SqlParameter。半天时间实现自己的数据源。
【解决方案4】:

我发现最好的方法是使用数组/列表中的值创建一个连接字符串。

string L1Joined = string.Join(",", L1);
//(L1: name of the array/list)

然后使用“IN”关键字并将 CommandText 设置为格式化字符串。

所以 CommandText 看起来像这样:

cmd.CommandText = $"SELECT * FROM categories WHERE category_id IN ({L1Joined})";

不确定这是否是最有效的方法,但它适用于我的具体问题。

【讨论】:

    猜你喜欢
    • 2019-03-03
    • 2018-01-18
    • 2014-05-28
    • 2021-12-12
    • 2015-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-19
    相关资源
    最近更新 更多