C#参数化查询MySQL带有`in`子句

我正在将几个硬编码的查询转换为应用程序并立即构建到参数化查询。 我遇到一个特定查询的问题,它有一个in子句:

 UPDATE TABLE_1 SET STATUS = 4 WHERE ID IN (1, 14, 145, 43); 

第一个参数很简单,因为它只是一个普通的参数:

 MySqlCommand m = new MySqlCommand("UPDATE TABLE_1 SET STATUS = ? WHERE ID IN (?);"); m.Parameters.Add(new MySqlParameter("", 2)); 

但是,第二个参数是一个整数列表,表示需要更新的行的ID。 如何传递单个参数的整数列表? 或者,您将如何设置此查询,以便您不必在每次调用它时完全构建它,并且可以防止SQL注入攻击?

您可以基于(可能)可变数量的参数“在运行中”构建参数化查询,并迭代它以传递它们。

所以,像:

 List foo; // assuming you have a List of items, in reality, it may be a List or a List with an id property, etc. StringBuilder query = new StringBuilder( "UPDATE TABLE_1 SET STATUS = ? WHERE ID IN ( ?") for( int i = 1; i++; i < foo.Count ) { // Bit naive query.Append( ", ?" ); } query.Append( " );" ); MySqlCommand m = new MySqlCommand(query.ToString()); for( int i = 1; i++; i < foo.Count ) { m.Parameters.Add(new MySqlParameter(...)); } 

这在MySQL中是不可能的。 您可以创建所需数量的参数并执行UPDATE … IN(?,?,?,?)。 这可以防止注入攻击(但仍然需要您为每个参数计数重建查询)。

其他方法是传递逗号分隔的字符串并解析它。

您不能使用IN子句的参数。

老问题,但万一有人通过谷歌遇到这个问题,这就是我使用的:

 int status = 4; string ids = "1,14,145,43"; m.Parameters.AddWithValue("@Status", status); m.Parameters.AddWithValue("@IDs", ids); UPDATE TABLE_1 SET STATUS = @Status WHERE FIND_IN_SET(ID, @IDs) > 0; 

注意:FIND_IN_SET是mySQL特定的函数。

信用,到期的信用:请参阅此问题: 将List 添加到mysql参数

循环遍历整数列表并执行单个更新。

MSSQL 2008提供了表值参数来避免这个问题,我不知道MySQL中有任何类似的function。

我建议创建一个函数(假设mysql支持用户定义的函数)将参数分开以返回一个表。