blackbeam / rust-mysql-simple

Mysql client library implemented in rust.
Apache License 2.0
665 stars 146 forks source link

MySQL - DriverError { Statement takes 4 parameters but 2 was supplied } #249

Closed NielDuysters closed 4 years ago

NielDuysters commented 4 years ago

I've got the following piece of code which compiles:

pub fn add_user(&self, data: RegistrationForm) -> bool {
            let mut conn = self.conn.get_conn().unwrap();

            let execute_result = conn.exec_batch("
            INSERT INTO users (
                username, email, birthdate, password
            ) VALUES (
                :username, :email, :birthdate, :password
            )", params! {
                "username" => &data.username,
                "email" => data.email,
                "birthdate" => data.birthdate,
                "password" => data.password
            });

            match execute_result {
                Ok(_) => {
                    println!("User {} added!", data.username);
                    true
                }
                Err(e) => {
                    eprintln!("Failed to add user {}: {}", data.username, e.to_string());
                    false
                }
            }
        }

I'm sure that data.username, data.email, data.birthdate, data.password ain't empty. For some reason I get the following error at runtime;

Failed to add user test: DriverError { Statement takes 4 parameters but 2 was supplied }

I guess this has something to do with the prepared statement failing. But I don't see how it could fail?

blackbeam commented 4 years ago

Thanks for report. I'll look into it. But could you please try to wrap params! { .. } into vec![] and see if it still errors?

blackbeam commented 4 years ago

The purpose of exec_batch is to execute a statement repeatedly with different sets of parameters:

conn.exec_batch(query, vec![params1, params2, params3, ..]);

Turns out that the result of params! invocation itself satisfies the bound on exec_batch's second parameter (IntoIter<Item: Into<Params>>). So calls like the following one are possible, yet semantically incorrect:

conn.exec_batch(query, params! { .. });

Thanks for report. I'll fix this.

Regarding your code. Since there is only one set of parameters and the query result is ignored I suggest you use exec_drop.

NielDuysters commented 4 years ago

Okay thanks. That solved it. Is there a way to get the insert id?

NielDuysters commented 4 years ago

Found it.

self.conn.get_conn().unwrap().last_insert_id();

Thx