Параметризованный запрос для MySQL с C#

У меня есть код ниже (я включил то, что я считаю, все соответствующие разделы):

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 при добавлении первого параметра. Что я сделал не так?

6 ответов

Решение

Попробуйте это вместо этого:

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;
}
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;
    }
}

Вам нужно использовать именованные параметры в вашем запросе. Например:

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

Затем передайте имена параметров при создании экземпляров объектов MySqlParameter следующим образом:

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

будет лучшим вариантом для параметризованного запроса.

Если вы хотите выполнить 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

Я не думаю, что классы MySql.Data поддерживают безымянные параметры. Если вы заинтересованы в их использовании, вы можете получить доступ к своей базе данных MySql через драйверы Odbc, они поддерживают это.

Вам нужно будет указать параметры в вашем запросе:

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

Я выбрал индикатор параметров "@", но последние версии MySql.Data поддерживают как "@", так и "?".

Затем обновите ваш конструктор параметров, чтобы они передавали правильное имя параметра (вам не нужно включать индикатор параметра здесь, хотя это не имеет никакого значения, если вы это сделаете).

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

PS. Вы, вероятно, уже знаете это, или это было просто опущено во фрагменте, но я думаю, что вы забыли вызвать Read в вашем экземпляре ExecuteReader.

Другие вопросы по тегам