咨询区
Tom Ritter
.NET 中的参数化查询我一直都像下面这样写。
SqlCommand comm = new SqlCommand(@"SELECT * FROM Products WHERE Category_ID = @categoryid
", conn);
comm.Parameters.Add("@categoryid", SqlDbType.Int);
comm.Parameters["@categoryid"].Value = CategoryID;
但我现在遇到了一个困难,参考如下代码:
SqlCommand comm = new SqlCommand(@"SELECT * FROM Products WHERE Category_ID IN (@categoryids) OR name LIKE '%@name%'
", conn);
comm.Parameters.Add("@categoryids", SqlDbType.Int);
comm.Parameters["@categoryids"].Value = CategoryIDs;
comm.Parameters.Add("@name", SqlDbType.NVarChar);
comm.Parameters["@name"].Value = Name;
where条件中:
CategoryIDs
是一个以逗号隔开的字符串123,456,789
。Name
是一个字符串,也有可能是包含了特殊字符。
目前的参数化无法查询,请问正确的语法如何写?
回答区
Paul Turner
这里我逐一回答下你的问题。
1. CategoryIds
这里我假定 CategoryIds
是一个 int 类型的数组,正确的做法是将 int 数组中的所有元素打散,然后逐一 参数化
,比如可以在循环中构建一个 @p0 - @pN-1
的有序参数,这里的 N 就是 CategoryIds 数组索引,然后逐一添加到 Command.Parameters
中。
2. Name
对 Name
的模糊匹配,应该放在 Parameters
参数上,而不是 SQL 中。
参考如下代码:
string Name = "someone";
int[] categoryIDs = new int[] { 238, 1138, 1615, 1616, 1617,1618, 1619, 1620, 1951, 1952,1953, 1954, 1955, 1972, 2022 };SqlCommand comm = conn.CreateCommand();string[] parameters = new string[categoryIDs.Length];for(int i=0;i<categoryIDs.Length;i++)
{parameters[i] = "@p"+i;comm.Parameters.AddWithValue(parameters[i], categoryIDs[i]);
}
comm.Parameters.AddWithValue("@name",$"%{Name}%");
comm.CommandText = "SELECT * FROM Products WHERE Category_ID IN (";
comm.CommandText += string.Join(",", parameters) + ")";
comm.CommandText += " OR name LIKE @name";
点评区
这是初学者在用 sql 参数化查询时经常遇到的问题,有必要摘出来和大家分享下,如果有条件,建议看看 Dapper 的源码,别人是如何处理此类场景的。