Warning: mysqli_stmt::bind_param(): Number of variables doesn't match number - php

I am receiving this error and am unable to figure out why.
Warning: mysqli_stmt::bind_param(): Number of variables doesn't match number of parameters in prepared statement in C:\xampp\htdocs\insert.php on line 32
$SELECT = "SELECT id FROM heroes WHERE name = ? LIMIT 1";
$INSERT = "INSERT INTO heroes (id, name, title, bp, ticket, diamond) VALUES ('NULL', '$name', '$title', '$bp', '$ticket', '$diamond')";
//Prepare statement
$stmt = $connection->prepare($SELECT);
$stmt->bind_param("s", $name);
$stmt->execute();
$stmt->bind_result($name);
$stmt->store_result();
$rnum = $stmt->num_rows;
if ($rnum==0){
$stmt->close();
$stmt = $connection->prepare($INSERT);
$stmt->bind_param("sssss", $name, $title, $bp, $ticket, $diamond);
$stmt->execute();
echo "New hero inserted successfully, sir!";
} else {
echo "There is already a hero with this name, sir!";
}
$stmt->close();
$connection->close();

You don't actually have any params to bind in your insert:
$INSERT = "INSERT INTO heroes (id, name, title, bp, ticket, diamond) VALUES ('NULL', '$name', '$title', '$bp', '$ticket', '$diamond')";
Do this:
$INSERT = "INSERT INTO heroes (name, title, bp, ticket, diamond) VALUES (?, ?, ?, ?, ?)";
Then the values you bind replace the question marks.
Also note there is a very significant difference between NULL and 'NULL' -- the latter is a string. If you have an auto-incrementing ID field, just leave it out of the insert and the database will fill it in for you.

Related

Can a prepared statement hold multiple queries in php

I am trying to protect my queries from SQL injections, recently. I have started turning the strings I used to make the queries into statements, however, some of the strings I made need to make multiple queries simultaneously, because one insert's id will be added to the next one as a foreign key, which I'll get by using the LAST_INSERT_ID(), and I need them to be executed one after another because of it.
Can a statement hold multiple queries simultaneously and be executed at once?
Here's what the code was before, by the by.
$sql = "INSERT INTO `user_info`(`first_name`, `last_name`, `phone`, `cpf`)
VALUES ('{$firstName}', '{$lastName}', '{$phone}', '{$cpf}');";
$sql .= "SELECT LAST_INSERT_ID() INTO #mysql_variable_here;";
$sql .= "INSERT INTO `{$table}`(`email`, `password`, `active`,`user_info_id`, `created`, `role_id`" . $restaurantInsert . ")
VALUES ('{$email}','{$password}', 1, #mysql_variable_here, '{$created}', {$role}" . $restaurantValue . " );";
$sql .= "INSERT INTO `address`(number, street, city, state, zip, district, country, created, user_info_id)
VALUES ('{$number}', '{$street}', '{$city}', '{$stateCode}', '{$zip}', '{$district}', 'BR', '{$created}', #mysql_variable_here);";
$result = $conn->multi_query($sql);```
You can't execute multiple statements in a prepared query:
SQL syntax for prepared statements does not support multi-statements
(that is, multiple statements within a single string separated by ;
characters)
so you will need to prepare and execute each of the queries separately, using mysqli_stmt::insert_id to get the appropriate id value for the second and third queries:
$sql = "INSERT INTO `user_info`(`first_name`, `last_name`, `phone`, `cpf`)
VALUES (?, ?, ?, ?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param('ssss', $firstName, $lastName, $phone, $cpf);
$stmt->execute();
$insert_id = $stmt->insert_id;
$stmt->close();
$sql = "INSERT INTO `{$table}`(`email`, `password`, `active`,`user_info_id`, `created`, `role_id`" . $restaurantInsert . ")
VALUES (?, ?, ?, ?, ?, ?, ?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param('ssiisss', $email, $password, 1, $insert_id, $created, $role, $restaurantValue);
$stmt->execute();
$stmt->close();
$sql = "INSERT INTO `address`(number, street, city, state, zip, district, country, created, user_info_id)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);";
$stmt = $conn->prepare($sql);
$country = 'BR';
$stmt->bind_param('sssssssi', $number, $street, $city, $stateCode, $zip, $district, $country, $created, $insert_id);
$stmt->execute();
$stmt->close();
Note I'm not 100% certain what you're trying to achieve with role_id" . $restaurantInsert . ", you might need to edit the second query appropriately to use that.

Two insert statements in php [duplicate]

This question already has an answer here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
Closed 6 years ago.
Hi guys how do I have two insert statements in the php codes to store the data into two different tables in the database?
$order = "INSERT INTO NewCase(CaseID, StaffName, Category, PriorityLevel, Status, Date, Summary, ResidentID)
VALUES (NULL, '$staffname', '$category', '$prioritylevel', '$status', '$checkdate', '$summary', NULL)";
$order .= "INSERT INTO NewResident(ResidentID, NRIC, ResidentName, Telephone, Email, Gender, Street1, Street2, PostalCode)
VALUES (NULL, '$nric', '$residentname', '$telephone', NULL, NULL, '$street1', '$street2', '$postalcode')";
$retval = mysqli_multi_query($link, $order);
You should be using mysqli prepared statements and nothing else.
$sql = "INSERT INTO NewCase VALUES (NULL, ?, ?, ?, ?, ?, ?, NULL)";
$stmt = $link->prepare($sql);
$stmt->bind_param("ssssss",$staffname, $category, $prioritylevel, $status, $checkdate, $summary);
$stmt->execute();
$sql = "INSERT INTO NewResident VALUES (NULL, ?,?,?, NULL, NULL, ?,?,?)";
$stmt = $link->prepare($sql);
$stmt->bind_param("ssssss",$nric, $residentname, $telephone, $street1, $street2, $postalcode);
$stmt->execute();
Take a look into transactions may be?
http://php.net/manual/en/mysqli.begin-transaction.php
mysqli_begin_transaction($link, MYSQLI_TRANS_START_READ_WRITE);
mysqli_query($link, $order1);
mysqli_query($link, $order2);
mysqli_commit($link);
mysqli_close($link);
Also if transaction fail you can always rollback
Also I suggest you use more Object Oriented approach:
$mysqli = new mysqli("localhost", "user", "password", "world");
$mysqli->query();
$mysqli->query();
$mysqli->close();

How incorporate On Duplicate Key with bind_param

Hi How can i incorporate On Duplicate Key with mysqli_stmt_bind_param
$stmt = mysqli_prepare($con, "INSERT INTO assy (ItemID,partid,qty,rev,bomEntry) VALUES (?, ?, ?, 'A',?) ON DUPLICATE KEY UPDATE partid=$bom");
mysqli_stmt_bind_param($stmt, "ssii", $itemid, $bom, $qty, $bomEntry) or die(mysqli_error($con));
$recordd = $tv->search(454545400000, 's=2');
//print_r($recordd);echo"1<br/>";
foreach($recordd as $data2) {
$itemid = $data2['fields']['CALC STOCK NO'];
$bomEntry = 1;
if ($data2['fields']['BOM WHEEL PN']) {
$bom = $data2['fields']['BOM WHEEL PN'];
$qty=1;
mysqli_stmt_execute($stmt) or die(mysqli_stmt_error($stmt));
$bomEntry++;
}
}
I tried something like
$stmt = mysqli_prepare($con, "INSERT INTO table_name (ItemID,partid,qty,rev,bomEntry) VALUES (?, ?, ?, 'A',?) ON DUPLICATE KEY UPDATE patid=$bom;");
.
.
.
but it set to blank
Your $bom is a string so it need to be quoted, or preferably swapped out of the query and bound via a placeholder. Here is the placeholder and binding approach:
$stmt = mysqli_prepare($con, "INSERT INTO assy (ItemID,partid,qty,rev,bomEntry) VALUES (?, ?, ?, 'A',?) ON DUPLICATE KEY UPDATE partid=?");
mysqli_stmt_bind_param($stmt, "ssiis", $itemid, $bom, $qty, $bomEntry, $bom);
With prepared statements you rarely will want variables in your query.

Insert auto-incremented ID using prepared statements

When inserting a new record into a table with an auto-incrementing ID column, it is normally enough to give the ID field the value NULL or omit it from the INSERT query, as explained at How to insert new auto increment ID
INSERT INTO `database`.`table` (`id`, `user`, `result`) VALUES (NULL, 'Alice', 'green')");
or
INSERT INTO `database`.`table` (`user`, `result`) VALUES ('Alice', 'green')");
My question is - how do you do the same thing when using prepared statements. I have tried the following, using NULL:
$stmt = $db->prepare("INSERT INTO `db` (id, name, password, text) VALUES (NULL, ?, ?, ?)");
$stmt->bind_param('sss', $name, $password, $text);
$stmt->execute();
and the fowllowing, omitting the ID field:
$stmt = $db->prepare("INSERT INTO `test_db` (name, password, text) VALUES (?, ?, ?)");
$stmt->bind_param('sss', $name, $password, $text);
$stmt->execute();
When I run this I get nothing inserted and no error message in the browser. I think it is because it is trying to insert a duplicate value for the ID field (stackoverflow.com/questions/12179770/…) - but why it should do that when this seems equivalent to the non-prepared-statement way of inserting data, and then give no message, I'm not sure.
Any ideas most welcome!

Mysqli Procedural Insert Into Table not working

I am trying to insert into a table with Procedural Mysqli. It is not posting any errors nor is it posting the information to the database. Here is my code:
$query = "INSERT INTO Accounts (FirstName, LastName, Username, Password, Access) VALUES ({$_POST['FirstNameTbx']}, {$_POST['LastNameTbx']}, {$_POST['UsernameTbx']}, {$_POST['PasswordTbx']}, {$_POST['AccessDDL']})";
mysqli_query($link, $query);
mysqli_close($link);
$Error .= "$query";
Update:
I changed to prepared statement, now I am getting:
Warning: mysqli_stmt::bind_param() [mysqli-stmt.bind-param]: Number of elements in type definition string doesn't match number of bind variables in /home/bryantrx/public_html/ec/add_user.php on line 19
There are only 5 variables that need to be bound, and the UserID auto increments, so it doesn't need to be bound or referenced in the statement..
if ($stmt = $link->prepare("INSERT INTO Accounts (FirstName, LastName, Username, Password, Access) VALUES (?, ?, ?, ?, ?)")){
$stmt->bind_param($_POST['FirstNameTbx'], $_POST['LastNameTbx'], $_POST['UsernameTbx'], $_POST['PasswordTbx'], $_POST['AccessDDL']);
$stmt->execute();
$Error .= "success";
$stmt->close();
} else {
echo $link->error;
}
To get an error message you need to call mysqli_error:
$error = mysqli_error($link);
You would also make life easier (and more secure) for yourself if you built your queries using prepare and parameters:
$query = "INSERT INTO Accounts (FirstName, LastName, Username, Password, Access)
VALUES ( ?, ?, ?, ?, ?)";
if ($stmt = mysqli_stmt_prepare($link, $query)) {
mysqli_stmt_bind_param($stmt, "sssss",
$_POST['FirstNameTbx'],
$_POST['LastNameTbx'],
$_POST['UsernameTbx'],
$_POST['PasswordTbx'],
$_POST['AccessDDL']);
if (!mysqli_stmt_execute($stmt)) {
$error = mysqli_stmt_error($stmt);
}
mysqli_stmt_close($stmt);
} else {
$error = mysqli_error($link);
}
mysqli_close($link);
UPDATE - ok, you've swapped to OO which is fine. When using bind_param the first parameter describes the data you are binding. In this case if it is five strings, you would put 5 "s" like so:
$stmt->bind_param("sssss",
$_POST['FirstNameTbx'],
$_POST['LastNameTbx'],
$_POST['UsernameTbx'],
$_POST['PasswordTbx'],
$_POST['AccessDDL']);

Categories