Column count doesn't match value count only in PHP - php

I use this solution (the accepted one) to insert no duplicates, because I can't set an unique index (table belong to another software), this way:
$InsertAddress = $DatabaseConnection -> prepare("INSERT INTO `tt_address` (`pid`, `tstamp`, `first_name`, `last_name`, `email`, `phone`, `address`, `city`, `zip`) SELECT * FROM (SELECT 272 AS `tmp_pid`, ? AS `tmp_tstamp`, ? AS `tmp_first_name`, ? AS `tmp_last_name`, ? AS `tmp_email`, ? AS `tmp_phone`, ? AS `tmp_address`, ? AS `tmp_city`, ? AS `tmp_zip`) AS `tmp` WHERE NOT EXISTS (SELECT `email` FROM `tt_address` WHERE `email` = ?) LIMIT 1")
$InsertAddress -> bind_param('issssssss', $Timestamp, $_POST['firstname'], $_POST['lastname'], $_POST['mail'], $_POST['phone'], $_POST['address'], $_POST['ort'], $_POST['plz'], $_POST['mail']);
$InsertAddress -> execute();
echo($DatabaseConnection -> error);
But I get the following error:
Column count doesn't match value count at row 1
If I copy the query in phpMyAdmin and replace the ? with sample data the query works.
What is wrong?

Parameter markers (the question marks) can't be used for column names.

Related

Why deos PDO SELECT Work but BASIC INSERT fails?

I have connected to the db and able to update a record.
I have a variable named "action" that is either "update" or "add".
I use it in a switch statement to set my query to either "SELECT" or "INSERT".
SELECT statement works.
INSERT statement does not.
I get this error on $pdo->execute($data).
PHP Fatal error: Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in ...
PDOStatement->execute(Array)
The error is thrown by the PDOStatement
Here is what I have tried, seems pretty straight-forward, but i'm struggling with it.
$data = [
'firstName'=> $firstName,
'lastName'=> $lastName,
'badge'=> $badge,
'department'=> $department,
'image'=> $image,
'active'=> $active,
'stars'=> $stars,
'email'=> $email,
'primary_key'=> $primaryKey,
];
$sql = "INSERT INTO `team`
(`primary_key`,`firstName`, `lastName`, `badge`, `department`, `image`, `active`, `stars`, `email`)
VALUES
(NULL, :firstName, :lastName, :badge, :department, :image, :active, :stars, :email)";
$pdo->prepare($sql);
$pdo->execute($data); <- error is here
When I simply echo my $data array to see if there is something odd. I don't see anything based off all the sites, I've read.
//$data array DATA
primary_key =
firstName = test
lastName = test
badge = 9000
department = marketing
image = 9000.jpg
active = 1
stars = 0
email = tester#test.com
primary_key in db is auto-increment
primary_key is $_post[] on update query and NULL insert query (auto increment db column)
Any errors that would prevent this INSERT query from working that you can see? I'm stuck. I know it the array has 9 variables, there are 9 fields to insert, and 9 values listed.
I know it the array has 9 variables, there are 9 fields to insert, and 9 values listed.
Count the parameters. There are 8 of them. The array includes a value called primary_key for which there is no parameter in the query.
primary_key in db is auto-increment
Then don't insert a value for it:
$sql = "INSERT INTO `team`
(`firstName`, `lastName`, `badge`, `department`, `image`, `active`, `stars`, `email`)
VALUES
(:firstName, :lastName, :badge, :department, :image, :active, :stars, :email)";
And remove primary_key from the $data array.

WHERE NOT EXISTS

I have a simple table with two columns "referralID" & "studentID"
I can add like this
$stmt = $pdo->prepare('INSERT INTO referralStudents (referralID,studentID) VALUES (?, ?)');
$stmt->execute([$myID,$studentID]);
I'm trying to get the WHERE NOT EXISTS statement to work. If there is already a row with both "referralID" & "studentID" don't add.
Both of these don't work can you show me where I'm going wrong?
$stmt = $pdo->prepare('INSERT INTO referralStudents (referralID,studentID) VALUES (?, ?) WHERE NOT EXISTS (SELECT * FROM referralStudents WHERE referralID = ? and studentID = ?")');
$stmt->execute([$myID,$studentID,$myID,$studentID]);
$stmt = $pdo->prepare('INSERT INTO referralStudents (referralID,studentID) VALUES (?, ?) WHERE NOT EXISTS (referralID,studentID) VALUES (?, ?)');
$stmt->execute([$myID,$studentID,$myID,$studentID]);
You need a SELECT statement and not VALUES to apply the conditions of the WHERE clause:
INSERT INTO referralStudents (referralID,studentID)
SELECT ?, ?
FROM dual
WHERE NOT EXISTS (SELECT * FROM referralStudents WHERE referralID = ? and studentID = ?)
You may remove FROM dual if your version of MySql is 8.0+.
See a simplified demo.
If the fields are empty i bet they are NULL. A field filled with NULL is existing but its content is NULL (NULL doesnt mean empty or non existing). Maybe this is what you need:
INSERT INTO refferalStudents (refferalID, studentID) VALUES (?,?) WHERE refferalID IS NULL AND studentID IS NULL

PHP mySQLi prepare fails with duplicate column '?'

I am attempting to prepare a statement with mysqli
$stmt = $mysqli->prepare("INSERT HIGH_PRIORITY INTO `user` (`FirstName`, `LastName`, `Department`, `Email`) SELECT * FROM (SELECT ?,?,?,?) AS tmp WHERE NOT EXISTS ( SELECT `Email` FROM `user` WHERE `Email` = ? ) LIMIT 1;");
if (!$stmt) {
printf('errno: %d, error: %s', $mysqli->errno, $mysqli->error);
die;
}
$statementReturnCode = $stmt->bind_param("sssss", $ssoFirstName, $ssoLastName, $ssoDepartment, $ssoEmail, $ssoEmail);
if (!$statementReturnCode) {
printf('errno: %d, error: %s', $stmt->errno, $stmt->error);
}
$stmt->execute();
$stmt->close();
When this is run I receive the following error:
errno: 1060, error: Duplicate column name '?'
I've been able to bind in this fashion in the past, but I've never tried to bind the same column twice in a different location in the query (Email).
How can I use the same value for Email in two different locations, or is this a different issue?
To clarify what is being done with this query:
This query will be run frequently. If the user exists already in the user table, no insert should be attempted. If the user does not exist, the user should be added to the user table.
The user table has a UserID field that auto-increments. If an insert is attempted the user will not be added due to a unique constraint, but the AUTO-INCREMENT will add 1 even though the insert did not occur. This WHERE NOT EXISTS query is an attempt to mitigate this issue.
Example use:
INSERT INTO `user` (
`user`.`FirstName`,
`user`.`LastName`,
`user`.`Department`,
`user`.`Email`)
SELECT * FROM (SELECT 'John', 'Doe', 'Marketing', 'John.Doe#mycorp.com') AS tmp
WHERE NOT EXISTS (
SELECT `user`.`Email`
FROM `user`
WHERE `user`.`Email` = 'John.Doe#mycorp.com'
) LIMIT 1;
I have tested this query and it works as I had expected. The issue I'm having is with properly changing this query into a prepared statement with php.
Column names aren't string literals, you don't bind column names
$stmt = $mysqli->prepare(sprint("INSERT HIGH_PRIORITY INTO `user` (`FirstName`, `LastName`, `Department`, `Email`) SELECT * FROM (SELECT '%s', '%s', '%s', '%s') AS tmp WHERE NOT EXISTS ( SELECT `Email` FROM `user` WHERE `Email` = ? ) LIMIT 1;"), $ssoFirstName, $ssoLastName, $ssoDepartment, $ssoEmail);
if (!$stmt) {
printf('errno: %d, error: %s', $mysqli->errno, $mysqli->error);
die;
}
$statementReturnCode = $stmt->bind_param("s", $ssoEmail);
if (!$statementReturnCode) {
printf('errno: %d, error: %s', $stmt->errno, $stmt->error);
}
This cannot be done. Prepared statements using PHP's mysqli extension cannot be used for several things including:
Table names
Columns in select lists
I was attempting to use a dynamic item in a select list which cannot be done.
https://www.owasp.org/index.php/PHP_Security_Cheat_Sheet#Where_prepared_statements_do_not_work

MySQLi prepared statements: insert increment of a value

Is it possible in any way to insert an increment of a certain column value ?
$stmt->$this->mysqli->prepare('INSERT INTO `users` ( `email`,`date_added`,`playCount`) VALUES ( ?, NOW(), ? )');
$stmt -> bind_param('si',$email, WHAT); // playCount++ somehow ...
$stmt -> execute();
I know I can use UPDATE to do that, but then I need to check if user exists first and then do INSERT and afterward UPDATE just for one column? There should be a better approach I think?
EDIT: UPDATE also won't work (won't prepare successfully-returns false: any ideas what might be wrong?)
$stmt = $this->mysqli->prepare('UPDATE `users` SET `newsletter` = ?, `date_last` = NOW(), points=points+?, WHERE `email` = ?');
(reference)
"INSERT INTO users ( `email`,`date_added`,`playCount`)
VALUES ( ?, NOW(), (SELECT MAX(playCount) from users)+1 );"

want to do a double MYSQL INSERT INTO to two different tables

I want to be able to insert into two different mysql tables using php with the second mysql insert being dependent on the member id of the first insert.
For example:
mysql_query("
INSERT INTO `member_users` (
`id`,
`first_name`,
`last_name`,
`username`,
`password`,
`address1`,
`address2`,
`postcode`,
`access`,
`expires`
) VALUES (
NULL,
'$fname',
'$lname',
'$email',
'$passhash',
'$add1',
'$city',
'$postcode',
'',
''
)"
);
Then I want to take the id of this member user to create a mysql_query insert on the same page eg:
mysql_query("
INSERT INTO `member_orders` (
`order_id`,
`member_id`,
`date`,
`item`,
`size`,
`quantity`,
`price`,
`tracking_id`,
`status`,
`item_sent`,
`notes`
) VALUES (
NULL,
'$userid',
'',
'',
'',
'',
'',
'',
'',
'',
''
)
");
its probably a really easy answer and a really silly question but cannot seem to find the answer anywhere
thanks in advance
If I have understood correctly, and you need to get the member_id from the first query, to use in the second query, you can use the PHP function
$the_member_id = mysql_insert_id();
http://php.net/manual/en/function.mysql-insert-id.php
You can also do it without using that PHP function
$sql = "SELECT LAST_INSERT_ID()";
// add code here to run the query.
You can use the php function mysql_insert_id() to get the last id you input into the database.
EG:
$sql = "INSERT INTO `table` VALUES (NULL, 'Thomas', 'Male')";
$query = mysql_query($sql);
$id = mysql_insert_id();
So in your question after the first INSERT you need this:
$userid = mysql_insert_id();
Then your second query will work.
You can use mysql_insert_id() to get id, generated by last insert.
mysql_insert_id — Get the ID generated from the previous INSERT operation
You could use the LAST_INSERT_ID MySQL function in your second SQL statement to get the last insert ID from the first.
mysql_query("
INSERT INTO `member_orders` (
`order_id`,
`member_id`,
`date`,
`item`,
`size`,
`quantity`,
`price`,
`tracking_id`,
`status`,
`item_sent`,
`notes`
) VALUES (
NULL,
LAST_INSERT_ID(),
'',
'',
'',
'',
'',
'',
'',
'',
''
)
");
I would recommend that if you use this approach then you execute the queries within a transaction. That way there's no way that another insert can occur between your first insert and your second, thus throwing off the result of LAST_INSERT_ID.
After executing mysql_query() function you can get lastly inserted id of lastly inserted table by mysql_insert_id().
You can do something like what is done in this example
$sql = "INSERT INTO users(name,gender) VALUES ('$name','$gender')";
$result = mysql_query( $sql,$conn );
$user_id = mysql_insert_id( $conn );
$sql = "INSERT INTO website(site,user) VALUES ('$site',$user_id)";
$result = mysql_query( $sql,$conn );
Manual for mysql_insert_id

Categories