【问题标题】:Parameterized Query for MySQL with C#使用 C# 的 MySQL 参数化查询
【发布时间】:2010-10-13 18:29:56
【问题描述】:

我有下面的代码(我已经包含了我认为所有相关的部分):

private String readCommand = "SELECT LEVEL FROM USERS WHERE VAL_1 = ? AND VAL_@ = ?;";
public bool read(string id)
{
    level = -1;
    MySqlCommand m = new MySqlCommand(readCommand);
    m.Parameters.Add(new MySqlParameter("", val1));
    m.Parameters.Add(new MySqlParameter("", val2));
    MySqlDataReader r = m.ExecuteReader();
    if (r.HasRows)
        level = Convert.ToInt32(r.GetValue(0).ToString());
    r.Close();
    return true;
}

当我运行它时,我在添加第一个参数时得到一个 IndexOutOfBoundsException。我做错了什么?

【问题讨论】:

    标签: c# mysql


    【解决方案1】:

    试试这个:

    private String readCommand = 
                 "SELECT LEVEL FROM USERS WHERE VAL_1 = @param_val_1 AND VAL_2 = @param_val_2;";
    
    public bool read(string id)
    {
        level = -1;
        MySqlCommand m = new MySqlCommand(readCommand);
        m.Parameters.AddWithValue("@param_val_1", val1);
        m.Parameters.AddWithValue("@param_val_2", val2);
        level = Convert.ToInt32(m.ExecuteScalar());
        return true;
    }
    

    【讨论】:

    • 谢谢,我想我必须为我的参数命名。那好吧。我想可能会更糟。
    【解决方案2】:

    您需要在查询中使用命名参数。例如:

    String readCommand = "SELECT LEVEL FROM USERS WHERE VAL_1 = ?param1 AND VAL_2 = ?param2";
    

    然后,在实例化 MySqlParameter 对象时传递参数名称,如下所示:

    m.Parameters.Add(new MySqlParameter("param1", val1));
    

    【讨论】:

    • mysql 参数是否以 '?' 开头,而不是像sql server中的'@'?我以为他们会是一样的。有趣!
    • dev.mysql.com/doc/refman/5.0/en/… 中的用户评论是这样说的。
    • 当您提到语法的细节时,我会指出参数值将“自引用”。因此,您不需要在字符串数据的值周围加上引号。这个例子是正确的,但缺少引号非常微妙,所以我想我会指出来。
    【解决方案3】:

    我认为 MySql.Data 类不支持未命名参数。如果您热衷于使用它们,您可以通过 Odbc 驱动程序访问您的 MySql 数据库,它们支持这一点。

    您需要为查询中的参数命名:

    "SELECT LEVEL FROM USERS WHERE VAL_1 = @val1 AND VAL_2 = @val2;"
    

    我选择了参数指示符“@”,但最近的 MySql.Data 版本同时支持“@”和“?”。

    然后更新您的参数构造函数以传入正确的参数名称(您不需要在此处包含参数指示符,尽管这样做没有任何区别)。

    m.Parameters.Add(new MySqlParameter("val1", val1));
    

    附言。您可能已经知道这一点,或者它只是在 sn-p 中被省略了,但我认为您忘记在您的 ExecuteReader 实例上调用 Read。

    【讨论】:

    • 我实际上确实忘记了我的代码,并且在执行路径到达那里时就找到了它。我正在重构一堆旧查询,并且一些代码正在移动,这本身就很容易出错。感谢您的帮助!
    【解决方案4】:
    protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
    {
        MySqlConnection con = new MySqlConnection("server=localhost;User Id=root;database=result;password=1234");
        con.Open();
    
        MySqlCommand cmd = new MySqlCommand("Select * from users where username=?username and password=?password", con);
        cmd.Parameters.Add(new MySqlParameter("username", this.Login1.UserName));
        cmd.Parameters.Add(new MySqlParameter("password", this.Login1.Password)); 
    
        MySqlDataReader dr = cmd.ExecuteReader();
        if (dr.HasRows ==true)
        {
            e.Authenticated = true;
        }
    }
    

    【讨论】:

      【解决方案5】:
      m.Parameters.AddWithValue("parameter",value) 
      

      将是参数化查询的更好选择。

      【讨论】:

        【解决方案6】:

        如果你想多次执行sql,那么你应该使用这种方式:

        conn.Open();
        cmd.Connection = conn;
        
        cmd.CommandText = "INSERT INTO myTable VALUES(NULL, @number, @text)";
        cmd.Prepare();
        
        cmd.Parameters.AddWithValue("@number", 1);
        cmd.Parameters.AddWithValue("@text", "One");
        
        for (int i=1; i <= 1000; i++)
        {
            cmd.Parameters["@number"].Value = i;
            cmd.Parameters["@text"].Value = "A string value";
        
            cmd.ExecuteNonQuery();
        }
        

        第一次没有“ExecuteNonQuery”,只是添加带有伪造值的参数,然后在循环中添加真实值。

        查看此链接: https://dev.mysql.com/doc/connector-net/en/connector-net-programming-prepared-preparing.html

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-29
          相关资源
          最近更新 更多