1

我正在尝试使用WHERE … IN @xs子句创建参数化 ADO.NET 查询,其中@xs是可能不连续值的简短列表,例如(2, 3, 5, 8, 13). 这可以做到吗?如果是这样,怎么做?

这不起作用:

int[] xs = { 2, 3, 5, 8, 13 };  // I've also tried using a List<int> instead
var c = new System.Data.SqlClient.SqlCommand();
c.CommandText = "SELECT … FROM … WHERE … IN @xs";
c.Parameters.AddWithValue("@xs", xs);  // throws ArgumentException due to `values`

System.Data.SqlDbType枚举和System.Data.SqlTypes命名空间中的类型都不表明支持这种情况。我必须恢复到动态 SQL(即CommandText使用字符串操作手动编写最终 SQL)吗?

4

3 回答 3

2

您必须一次构建一个参数:

int[] xs = { 2, 3, 5, 8, 13 };
var c = new SqlCommand();
var parameters = xs.Select((x, i) => string.Concat("@xs", i)).ToList();
for (var i = 0; i < xs.Count; i++)
{
    c.Parameters.AddWithValue(parameters[i], xs[i]);
}

c.CommandText = string.Format(
    "SELECT ... FROM ... WHERE ... IN ({0})", 
    string.Join(", ", parameters)
);
于 2013-06-08T08:23:30.303 回答
1

如果您使用的是 SQL Server 2008 或更高版本,则另一种方法可能是使用“表值参数”。更多信息:SQL Server 2008 中的数组和列表使用表值参数

于 2013-06-08T14:10:18.540 回答
1

正如您已经发现的那样:不支持。

int[] xs = { 2, 3, 5, 8, 13 };
var c = new System.Data.SqlClient.SqlCommand();
// this code assumes xs has always at least one item
var s = new StringBuilder("SELECT … FROM … WHERE … IN (@xs0");
c.Parameters.AddWithValue("@xs0", xs[0]);  
for(int i = 1; i < xs.Length; i++)
{
  s.AppendFormat(",@xs{0}", i);
  c.Parameters.AddWithValue(String.Format("@xs{0}",i), xs[i]);  
}
s.Append(")");
c.CommandText = s.ToString():
于 2013-06-08T08:20:43.917 回答