PHP Prepared Statement SQL with where value - php

I am trying to run this query on an existing row in sql table:
if($stmt = $mysqli->prepare("INSERT INTO 4rounds (player2_name, player2_army1_name, player2_army2_name, player2_army3_name, player2_army4_name, player2_identifier, player2_stage, player2_army1_position, player2_army2_position, player2_army3_position, player2_army4_position) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) WHERE pairing_id = ?")) {
but it returns the error:
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'WHERE pairing_id = ?' at line 1
The query works without the WHERE clause. I think there is a problem with binding the parameter in this matter and I should use VALUE as well to bind it later but I can't seem to find anything online about binding a param in this manner.
These are the binds I am trying with:
$stmt->bind_param("ssssssssssss", $player2_name, $player2_army1_name, $player2_army2_name, $player2_army3_name, $player2_army4_name, $player2_identifier, $player2_stage, $player2_army1_position, $player2_army2_position, $player2_army3_position, $player2_army4_position, $pairing_id);

INSERT statements don't have WHERE clauses, and I'm not sure why you would want such a thing... Those only exist in SELECT and UPDATE queries, typically.

Related

PHP mysqli prepare statement bind_param boolean error

Testing the statement from all side, but failed to find a solution for it.
// Insert the new user into the database
if( $insert_stmt = $mysqli->prepare("INSERT INTO client (username, email,
password, reg_ip, salt, country, ref_id, pin, ref_by, ref_by_2) VALUES ( ?,
?, ?, ?, ?, ?, ?, ?, ?, ?)")){
$insert_stmt->bind_param("ssssssssii", $username, $email, $pass_2,
$reg_ip, $random_salt, $countryname, $ref_code, $hashed_pin, $user_id3,
$user_id4);
$insert_stmt->execute();
This never executes or gets inside the if statement.
I debugged it by removing the if part, that shows bind_param() is boolean error.
$insert_stmt = $mysqli->prepare("INSERT INTO client (username, email,
password, reg_ip, salt, country, ref_id, pin, ref_by, ref_by_2) VALUES ( ?,
?, ?, ?, ?, ?, ?, ?, ?, ?)");
$insert_stmt->bind_param("ssssssssii", $username, $email, $pass_2, $reg_ip,
$random_salt, $countryname, $ref_code, $hashed_pin, $user_id3, $user_id4);
if($insert_stmt->execute()){
Fatal error: Call to a member function bind_param() on boolean
I have done following test:
All 10 variables data type test = OK (with gettype() function)
Variables data value = OK (printed all data value for checking)
Mysql query statement = OK (tested on MYSQL directly with inputted data, mysql is inserting values)
There is no syntax error either.
Variable alignment is = Ok
Data connection is = ok (as it runs other prepare statements without errors on same page)
Then where is the mistake?
I figure it out.
Solution:
It was not working because of the previous prepare statement $stmt_aff connection was not closed.
Once I closed it. Next Prepare statement $insert_stmt started working.
A good lesson learned why bind_param boolean error get produced if there are multiple prepare statement on the same page.
$stmt_aff->close();

PDO prepared statement isn't working

I'm finding that my PDO MySQL insertion isn't working
The basic format of it is:
INSERT INTO `my_table` (id, email_hash, dob, 1, 6, 10) VALUES (?, ?, ?, ?, ?, ?)
It actually comes like this:
$InsertQuery = $db->prepare("INSERT INTO `my_table` (id, email_hash, dob, $NumbersString) VALUES (?, ?, ?, $QuestionMarkString)");
$InsertQuery->execute(array("$ID, $hashed_email, $dob, $YesNoString"));
The variable $QuestionMarkString fills in (correctly) the number of question mark placeholders.
The variable $YesNoString is a string of "1"s of appropriate length to act as markers in the database.
So even when I can see that the first part of the query successfully becomes formed as:
INSERT INTO `my_table` (id, email_hash, dob, 1, 6, 10) VALUES (?, ?, ?, ?, ?, ?)
... and the content of the execute array successfully becomes:
52, $2y$10$h9yXWUd8edQVMTSwZrX7T.pJ/C1pLDE9b081OtGmG6nbAtXr7lASK, 29062016, 1, 1, 1
.. the insert still doesn't happen. I get a PHP error saying:
PHP Warning: PDO::prepare(): SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '1, 6, 10) VALUES (?, ?, ?, ?, ?, ?)' at line [etc]
It should be:
$InsertQuery->execute(array($ID, $hashed_email, $dob, $YesNoString));
Also, you cannot have columns that only contain digits:
Identifiers may begin with a digit but unless quoted may not consist solely of digits.
Therefore you need to wrap your columns in backticks `
my_table
doesn't contain the columns in $NumbersString (1,6,10)
or you need to add backticks to the column names
(`1`,`6`,`10`)
Try putting backticks (`) around the numeric column names:
INSERT INTO `my_table` (id, email_hash, dob, `1`, `6`, `10`) VALUES (?, ?, ?, ?, ?, ?);

When is it necessary to bind parameters with MySQLi?

From this code I received an error.
//Prepare insert statement.
if($InsertEventQuery = $mysqli->prepare("INSERT into events(eventname, eventdesc, eventmonth, eventdate, eventyear, eventstart, eventend) VALUES ('$EventName','$EventDesc','$EventMonth','$EventDate','$EventYear','$EventStart','$EventEnd')"))
{
//Bind parameters of insert statement.
$InsertEventQuery->bind_param('ssiiiii', $EventName, $EventDesc, $EventMonth, $EventDate, $EventYear, $EventStart, $EventEnd);
This is the error:
Warning: mysqli_stmt::bind_param(): Number of variables doesn't match number of parameters in prepared statement in[...]
I looked into it because the error appears to be incorrect and found:
PHP Warning: mysqli_stmt::bind_param(): Number of variables doesn't match number of parameters in prepared statement
You do not need to bind parameters in this case. Placeholders are used for the values in an INSERT statement, or in a WHERE clause. (Note that placeholders are not allowed for identifiers, such as the column names in your statement.)
This confused me and I am now wondering in interest of security, when is it necessary to bind parameters and when is it necessary to use placeholders.
Binding parameters is a good idea in any INSERT statement as it will prevent SQL injection, and will also sanitize your strings for free.
I usually get it working using question mark in prepare statement like this:
//Prepare insert statement.
if ($InsertEventQuery = $mysqli->prepare("INSERT into events(eventname, eventdesc, eventmonth, eventdate, eventyear, eventstart, eventend) VALUES (?, ?, ?, ?, ?, ?, ?)"))
{
//Bind parameters of insert statement.
$InsertEventQuery->bind_param('ssiiiii', $EventName, $EventDesc, $EventMonth, $EventDate, $EventYear, $EventStart, $EventEnd);

mysqli prepared statement with ADDTIME CURTIME fails

There are so many questions on SO for failed prepared statements, but I cannot find one which solves my exact problem (or explains it, atleast).
I'm trying to give my users a login-token which is valid for 5 minutes.
When I execute the query through PHPMyAdmin it works just fine:
WORKING QUERY
INSERT INTO LOGGEDIN (userID, loggedInToken, loggedInRefresh) VALUES
(1, "HJKFSJKFDSKLJFLS", ADDTIME(CURTIME(), '00:05:00'));
However, when trying to execute the query through PHP using a prepared statement it fails.
$stmt = $this->conn->prepare("INSERT INTO LOGGEDIN VALUES (userID, loggedInToken, loggedInRefresh) VALUES (?, ?, ADDTIME(CURTIME(), '00:05:00'))");
$stmt->bind_param("is", $userID, $token);
I get the error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VALUES (?, ?, ADDTIME(CURTIME(), '00:05:00'))' at line 1
It is the exact same query so I think it's due to how the prepare handles the query.
I've also tried entering the '00:05:00' as a variable because I thought the ' was causing the error but it fails as well.
$five_minutes = '00:05:00';
$stmt->bind_param("iss", $userID, $token, $five_minutes);
When I remove the prepare and use the following query:
$query = "INSERT INTO LOGGEDIN VALUES (userID, loggedInToken, loggedInRefresh) VALUES (" . $userID . ", '" . $token . "', ADDTIME(CURTIME(), '00:05:00'))";
if ($result = $mysqli->query($query)) {
...
It works fine but I would like to keep my code consistent and use a prepared statement everywhere I can.
How can I let this query execute properly using a prepared statement? If all else fails I think I could create the timestamp in PHP and pass it through to the database thus bypassing the whole ADDTIME calculation, but I would like to know what is causing the problem in the first place.
Problems need to be understood, not dodged.
You have a superfluous VALUES on your query:
$stmt = $this->conn->prepare("INSERT INTO LOGGEDIN VALUES (userID, loggedInToken, loggedInRefresh) VALUES (?, ?, ADDTIME(CURTIME(), '00:05:00'))");
^^
Remove that:
$stmt = $this->conn->prepare("INSERT INTO LOGGEDIN (userID, loggedInToken, loggedInRefresh) VALUES (?, ?, ADDTIME(CURTIME(), '00:05:00'))");

Prepared statement mysqli

I'm getting obsessed. I'm working for the first time with prepared statement and I am sure I have read somewhere that you could prepare a statement like:
$stmt = $db->prepare("INSERT INTO {$table} (:var1, :var2) VALUES (:val1, :val2)");
$stmt->bind_param(':var1', $var1);
$stmt->bind_param(':var2', $var2);
$stmt->bind_param(':val1', $val1);
$stmt->bind_param(':val2', $val2);
$stmt->execute();
Or something like that. I remember that I have read that you could call the vars with a specific name with ':' as prefix. But I really can't find an example of that. I read the php manual and I couldn't find any sample of this thing.
Is it right or have I dreamed it?
Faq
If you are wondering why I can't use simply the '?' method:
$stmt = $db->prepare("INSERT INTO {$table} (?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?)");
this gets hard to write.
You can't do :var1,:var2,:varX in both the column names list and the VALUES list for one thing. Secondly, PDO accepts named parameter binding.
See PHP Data Objects and examples in PDO::prepare.

Categories