这个问题在这里已有答案:
我有一个查询,预计会返回几行,但不会返回代码中的任何结果。我有一些arraylist的价值,我用单引号和逗号包围在'in'运算符中使用。
我在这里做错了吗?
AseCommand cmd = new AseCommand("select * from Customer where ID in (@parmCustId)", conn);
cmd.Parameters.AddWithValue("@parmCustId", string.Join(",", arrList.Cast<string>().Select(x => string.Format("'{0}'", x))));
using (AseDataReader dr = cmd.ExecuteReader())
{
if (dr.HasRows)
{
//do something
}
}
在这种情况下,你真的很蠢。您必须为IN
列表中的每个值添加一个参数。
所以你的查询最终会是这样的:
SELECT * FROM Customer WHERE ID in (@parmCustId1, @parmCustId2, @parmCustId3 ... @parmCustId<N>)
然后你的代码看起来像这样:
var query = "select * from Customer where ID in (@parmCustId)";
using (AseCommand cmd = new AseCommand("", conn))
{
var replacement = "";
for (int i = 0; i < arrList.Length; i++)
{
var id = arrList[i];
var p = "@parmCustId" + i.ToString();
cmd.Parameters.AddWithValue(p, id);
replacement += p;
if (i != arrList.Length - 1)
{
replacement += ",";
}
}
cmd.CommandText = query.Replace("@parmCustId", replacement);
using (AseDataReader dr = cmd.ExecuteReader())
{
if (dr.HasRows)
{
//do something
}
}
}
还有一些图书馆会支持这一点。例如,由StackOverflow的人员撰写的Dapper将轻松支持这一点。它也是一个超快速高效的对象关系映射器(ORM),如果你放入一个对象,可以使一些DataReader逻辑更简单。你可以在NuGet上得到它。
这是你想要运行的:
SELECT * FROM table WHERE ID IN(1,2,3,4)
这是你实际运行的内容:
SELECT * FROM table WHERE ID IN ('1,2,3,4')
如果要参数化IN,则必须输入N个参数,并为每个参数赋值:
SELECT * FROM table WHERE ID IN (@p1, @p2, @p3, @p4)
//c# code here to populate 4 named parameters with an id each