代码之家  ›  专栏  ›  技术社区  ›  Elie

参数化查询mysql with`in`子句

  •  6
  • Elie  · 技术社区  · 15 年前

    我正在将几个查询转换为参数化查询,这些查询是硬编码到应用程序中并动态构建的。我有一个特定的问题,它有一个 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注入攻击?

    6 回复  |  直到 9 年前
        1
  •  4
  •   Rowland Shaw    15 年前

    您可以基于(可能的)参数的变量数“即时”构建参数化查询,并对其进行迭代以传递它们。

    所以,有点像:

    List foo; // assuming you have a List of items, in reality, it may be a List<int> or a List<myObject> 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(...));
    }
    
        2
  •  5
  •   Andrey Shchekin    15 年前

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

    另一种方法是传递逗号分隔的字符串并对其进行分析。

        3
  •  2
  •   Frederik Gheysels    15 年前

    不能为IN子句使用参数。

        4
  •  2
  •   Community Neeleshkumar S    7 年前

    老问题,但如果有人通过谷歌看到这一点,我使用的是:

    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_是一个特定于mysql的函数。

    信用证,信用证到期的地方:见本问题: Add List<int> to a mysql parameter

        5
  •  0
  •   Ian Nelson    15 年前

    循环您的整数列表并执行单个更新。

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

        6
  •  -1
  •   CodeMonkey1313    15 年前

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