我需要以下查询:
createList(string commaSeparatedElements) {
...
SqlCommand query = new SqlCommand("SELECT * FROM table WHERE id IN ("+commaSeparatedElements+")");
...
}
我想使用参数化查询来编写它,因此检查字符串中的每个元素以防止进行Sql注入。
的伪代码:
createList(string commaSeparatedElements) {
...
SqlParameterList elements = new SqlParameterList("@elements", SqlDbType.Int);
SqlParameterList.Values = commaSeparatedElements.split(new Char[1] {','});
SqlCommand query = new SqlCommand("SELECT * FROM table WHERE id IN (@elements)");
query.Parameters.Add(elements);
...
}
C#中是否存在类似的内容,或者我必须自己编写?
编辑:感谢所有答案。当我尽量不使用代码时,我不理解(在过去的日子里有太多不好的经历),精巧和表值参数,即使它们可能完全满足我的需求,也是禁止的。我刚做了一个循环。
string[] elements = commaSeparatedElements.split(new Char[1] {','});
StringList idParamList = new StringList();
for(int i=0;i<elements.Count;i++) {
query.Parameters.AddWithValue("@element"+i,Convert.ToInt32(elements[i]));
idParamList.Add("@element" + i);
}
SqlCommand query = new SqlCommand("SELECT * FROM table WHERE id IN ("+String.Join(",",idParamList)+")");
答案 0 :(得分:8)
"dapper"有一些伏都教:
var ids = new List<int> {1,2,3,4,5};
var rows = conn.Query<SomeType>("select * from table where id in @ids",
new { ids }).ToList();
您会注意到in
用法中缺少括号; “dapper”发现了这一点,并自动执行参数扩展。此外,它还会为您处理所有命令详细信息,包括将数据映射回SomeType
个实例。
在上面的示例中,它将扩展为等于(大约):
int ids0 = 1, ids1 = 2, ids2 = 3, ids3 = 4, ids4 = 5;
var rows = conn.Query<SomeType>(
"select * from table where id in (@ids0,@ids1,@ids2,@ids3,@ids4)",
new { ids0, ids1, ids2, ids3, ids4 }).ToList();
答案 1 :(得分:3)
SQL Server有一个数据结构,非常适合保存相同“类型”的多个值 - 这是一个表。
值得庆幸的是,近年来,他们引入了Table-Valued Parameters,以便您可以在客户端代码中构建一个表,并以自然的方式将其传递给SQL Server,例如:
// Assumes connection is an open SqlConnection.
using (connection)
{
// Create a DataTable with the modified rows.
DataTable addedCategories = CategoriesDataTable.GetChanges(
DataRowState.Added);
// Define the INSERT-SELECT statement.
string sqlInsert =
"INSERT INTO dbo.Categories (CategoryID, CategoryName)"
+ " SELECT nc.CategoryID, nc.CategoryName"
+ " FROM @tvpNewCategories AS nc;"
// Configure the command and parameter.
SqlCommand insertCommand = new SqlCommand(
sqlInsert, connection);
SqlParameter tvpParam = insertCommand.Parameters.AddWithValue(
"@tvpNewCategories", addedCategories);
tvpParam.SqlDbType = SqlDbType.Structured;
tvpParam.TypeName = "dbo.CategoryTableType";
// Execute the command.
insertCommand.ExecuteNonQuery();
}
答案 2 :(得分:2)
如果您声明
List<int> Ids = new List<int>();
并添加您想要的ID。可以很容易地将它转换为逗号分隔列表,如下所示
string listOfIds = string.Join(",", Ids.Select(Id => Id.ToString()).ToArray());
然后将此字符串作为参数传递给参数化查询。
答案 3 :(得分:1)
您使用的是哪个版本的sql server? 如果您使用的是sql server 2008或更高版本,则应该尝试使用表值参数
检查http://www.codeproject.com/Articles/39161/C-and-Table-Value-Parameters
答案 4 :(得分:1)
我使用像这样的辅助方法
/// <summary>
/// Adds a sequence of parameters to an existing parameter collection
/// </summary>
/// <typeparam name="T">Type of parameter values</typeparam>
/// <param name="parameters">Existing parameter collection</param>
/// <param name="pattern">Name pattern of parameters. Must be a valid <see langword="int"/> format string</param>
/// <param name="parameterType">Database type of parameters</param>
/// <param name="length">Length of parameter. 0 for numeric parameters</param>
/// <param name="values">Sequence of values</param>
/// <returns>Comma separated string of parameter names</returns>
public static string AddParameters<T>(SqlParameterCollection parameters,
string pattern,
SqlDbType parameterType,
int length,
IEnumerable<T> values) {
if (parameters == null)
throw new ArgumentNullException("parameters");
if (pattern == null)
throw new ArgumentNullException("pattern");
if (values == null)
throw new ArgumentNullException("values");
if (!pattern.StartsWith("@", StringComparison.CurrentCultureIgnoreCase))
throw new ArgumentException("Pattern must start with '@'");
var parameterNames = new List<string>();
foreach (var item in values) {
var parameterName = parameterNames.Count.ToString(pattern, CultureInfo.InvariantCulture);
parameterNames.Add(parameterName);
parameters.Add(parameterName, parameterType, length).Value = item;
}
return string.Join(",", parameterNames.ToArray());
}
像这样使用
string sql = "SELECT col1 " +
"FROM Table " +
"WHERE col2 IN ({@Values}) ";
var paramNames = SqlHelper.AddParameters(command.Parameters,
"@Value0",
SqlDbType.Int,
0,
listOfInts);
command.CommandText = sql.Replace("{@Values}", paramNames);
...
(结果是类似SELECT ... IN (@Value0, @Value1, @Value2)
)的查询
答案 5 :(得分:0)
这是我在一个项目中所做的:
StringBuilder sb = new StringBuilder("Id IN(");
List<SqlParameter> parameters = new List<SqlParameter>();
int i = 1;
foreach (int item in items)
{
string currentItem = "@Item" + i++.ToString();
sb.Append(currentItem + ",");
parameters.Add(new SqlParameter(currentItem , item));
}
sb.Remove(sb.Length-1, 1);
sb.Append(")");
我希望这会有所帮助
答案 6 :(得分:-1)
或者,您可以为参数设置if条件。例如:
if(commaSeparatedElements.Contains("'"))
return;
else
//Pass parameter & Execute query