我有一个SQL查询,我正在ASP.NET页中运行。 最终解析的SQL需要包含WHERE [columnname] IN [values]格式的字符串值列表。 例如,最终查询可能看起来像这样:

SELECT PRODUCTNAME FROM PRODUCT WHERE PRODUCTCODE IN ('ABC','DEF','GHI','JKL', /* etc */);

但是,WHERE子句中的字符串值必须是动态的。 通常,我使用参数化查询来使我的代码更加方便和安全,因此从概念上讲,我想执行以下操作:

String[] productCodes = { "ABC", "DEF", "GHI", "JKL" };
SqlCommand cmd = "SELECT PRODUCTNAME FROM PRODUCT WHERE PRODUCTCODE IN (@ProductCodes)";
cmd.Parameters.Add("@ProductCodes", productCodes);

但是,.NET中似乎不存在这种功能。 我应该如何实施呢? 我可以在数组上使用foreach循环,并使用单个值作为每个值的参数运行查询,但是数组中可能存在一百多个左右的不同值,看来分别查询它们效率很低。

我读过另一个问题,有人建议为强类型的int参数提供解决方案 ,但是当与String值一起使用时,该方法会让我对SQL注入感到不安,尤其是因为客户端很可能能够影响输入值。

您将如何实现此查询功能?

使用数据库详细信息进行编辑

该数据库是SQL Server2005。很抱歉忘记提及这一点。

#1楼 票数:2 已采纳

创建基本sql语句为格式,并动态添加参数,然后在循环中设置值。

String[] productCodes = { "ABC", "DEF", "GHI", "JKL" };
string sqlFormat = "SELECT PRODUCTNAME FROM PRODUCT WHERE PRODUCTCODE IN ({0})";
var @params = productCodes.Select((id, index) => String.Format("@id{0}", index)).ToArray();
var sql = String.Format(sqlFormat, string.Join(",", @params));

using(var cmd = new DbCommand(sql))
{
    for (int i = 0; i < productCodes.Length; i++)
        cmd.Parameters.Add(new Parameter(@params[i], DbType.String, productCodes[i]));
    // execute query
}

#2楼 票数:1

只是一个想法:

String[] productCodes = { "ABC", "DEF", "GHI", "JKL" };
SqlCommand cmd = "SELECT PRODUCTNAME FROM PRODUCT WHERE PRODUCTCODE IN ("; 

for (int i=0;i<productCodes.Length;i++) {
  cmd.CommandText += "@" + productCodes[i] + ",";
  cmd.Parameters.Add("@" + productCodes[i], productCodes[i]);
}
cmd.CommandText = cmd.CommandText.SubString(0, cmd.CommandText.Length-1);
cmd.CommandText += ");"

可能不是最好的方法,但是我想这就是我会尝试的方法。

#3楼 票数:0

您正在寻找表值参数。 但是,直到asp.net被广泛采用之后,这些功能才可用于sql server,因此对asp.net的支持受到限制。

相反,我建议您将其视为构建购物车。 用户将项目添加到购物车,并且在某些时候您想要显示购物车中的所有项目。 在这种情况下,自然的解决方案是购物车本身位于数据库表中。 与其将卡中包含的项作为“ IN(?)”指令的一部分拉下来,您不如将其构建为指令的子查询:“ WHERE X IN (SELECT X FROM ShoppingCart WHERE UserID= @UserID AND SessionKey= @SessionKey) “。 即使您添加了数百个项目,用户也是如此之快,并且每个插入的负载相当均匀地分布。

当然,您可能正在构建购物车以外的东西,但是尽管如此,您的查询几乎总是属于以下三类之一:

  1. 列表中的项目由用户手动选择,在这种情况下,您仍然可以使每个选择结果都在新的数据库记录中,该记录又可以在子查询中使用
  2. 它是数据库中已经可用的数据,在这种情况下,您仍然应该可以使用子查询(如果不能,则可能是时候在某个地方添加“类别”列,以便可以使用了)。
  3. 这些数据已硬编码到您的应用中,在这种情况下,您也可以将其编码到查询中

罕见的例外是查询是由另一台机器源触发的,或者您可能还拥有很多不愿意重新编写代码以使之成为可能的代码。
因此,如果由于某种原因,这种方法不能为您解决问题,可以在以下位置找到有关sql server的标准文章(包括一些替代方法):
http://www.sommarskog.se/arrays-in-sql.html

本文确实是该主题的标准文章,非常值得您花时间。

#4楼 票数:0

作为记录,“不单独”查询数组中的一百个左右的值也可能效率不高(尽管不如往返SQL Server的一百个左右那样低效率)。 但是,参数化查询会有所帮助,因为您可以准备相同的查询并执行多次。 存储过程可能会更好。

您有机会可以使用Linq,还是您是.NET-3.5之前的版本?

如果您不能使用Linq,并且绝对必须使用此路线,请尝试以下操作:

SqlCommand cmd = "SELECT PRODUCTNAME FROM PRODUCT WHERE PRODUCTCODE = @ProductCode";
cmd.Prepare();
List<string> results;
foreach (string code in productCodes)
{
    cmd.Parameters.Clear();
    cmd.Parameters.Add("@ProductCodes", DbType.VarChar).Value = code;
    cmd.ExecuteQuery();
    // Add code here to add the returned values to the results list.  It's been
    // a while since I've used ADO.NET, and I don't have time to look it up
    // at the moment...
}

然后,您有结果列表。

  ask by Joshua Carmody translate from so

未解决问题?本站智能推荐:

1回复

如何在asp.net中参数化查询?

我了解到字符串连接很容易进行SQL注入,但不幸的是,我已经将其应用于大多数代码了。 我正在尝试合并参数化查询,但是不知何故,在线示例无法解决我的问题。 我看到的大多数示例是这样的: 但是,如果我有这样的sql语句怎么办: 另外,我在文本框中获取字符串品牌的价值,该价值将传递给
1回复

在 ASP.NET 中进行参数绑定后检查原始数据库查询

我正在使用 SqlConnection 和 SqlCommand 使用 ASP.NET 进行查询。 我正在使用 AddWithValue 方法向查询添加参数,以避免 SQL 注入。 我想在包含参数后检查结果查询,以进行调试。 如果我有“WHERE name = @myName”,我想在@myNam
1回复

使用参数化查询将自动生成的ID插入ForeignKey列

不确定如何使用SQL参数化查询来解决此问题。 我目前可以将数据(在这种情况下为客户)插入SQL表中,并让数据库生成和处理主键ID,而不是手动将ID与其余属性一起插入。 我的问题是,如何使用参数化查询将此自动生成的ID插入与其相关的外键列的另一个表中? 例如,如果第二张表用于预订,并且它
1回复

参数化查询问题

我有自己的DLL(用于数据访问层)。 我使用转义字符技术来避免用户输入错误,但是最近我决定通过使用参数化查询来防止所有可能的错误来增强类。 修改容易还是困难? 如何将查询转换为使用参数化查询? 请给我看一些示例代码来阐明这个想法。
1回复

ASP.NET C#中的参数化顶部子句查询

我想在C#中使用top子句查询 我正在将对象引用未设置为在线的对象实例 谢谢,
1回复

如何在IN子句sql informix中使用参数

如何在IN子句sql informix中使用参数 我不知道如何处理传递参数到camp IN (,,,,)//Set of numbers
2回复

如果查询没有参数化,如何在查询中传递对象(字节数组)?

我有这个查询要运行: 在上面的代码中,如何将值x, y, z etc传递给查询本身? x, y, z etc不是int或string而是字节数组。 在我的代码中,它们是.net Guid字段,但我将它作为二进制值保存在db中,方法是将其转换为字节数组。 我可以通过参数化方式实现
2回复

如何在sqltransaction中读取未提交的事务?

在.net Framework 2.0 C#代码中使用SQLTransaction时遇到问题 这是我的代码: 我无法从成员表中获取ID,用于将另一个记录插入到另一个表中。 还有其他解决方案吗?