PDO update query to append data into MYSQL db using named placeholder - php

I'm building sql UPDATE query to append string value using only NAMED PLACEHOLDERS to the already existing value in db. please suggest necessary changes in below code to work or suggest how to use named placedholders in concat update syntax
$name="Lastname";
$stmt = $conn->prepare("UPDATE users SET name= name + :name WHERE id=:id");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':id', $id);
$stmt->execute();
Expected Output:
Before: Table has 'name' column-value "Firstname"
After code execution: 'name' column-value "FirstnameLastname"

+ is not the normal way to concatenate strings in SQL. The standard operator is || and the function concat() is usually available:
UPDATE users
SET name = CONCAT(name, :name)
WHERE id = :id;

Related

Update a single row in SQL

I am having trouble with a really simple SQL statement: UPDATE.
I would only like to update the booking_date column in a specific row.
Here is the statement I'm using:
UPDATE `coupon-codes` SET `booking_id`=:timestamp WHERE `id` = :id
I'm using PDO named placeholders.
I always get an incorrect syntax error. What am I doing wrong?
Edit:
I tried without backticks:
UPDATE coupon-codes SET booking_id = :timestamp WHERE id = :id
Still doesn't work.
Here's the error message I'm getting:
Edit 2:
Here is the error message I'm getting when using backticks:
Edit 3:
For reference, here is an INSERT statement I used before, which works without any problems:
INSERT INTO `coupon-codes` (`code`, `date`) VALUES (:code, :date)
Edit 4:
Sorry, wrongly said some things in the comments, to clarify, see this:
I am using BACKTICKS everywhere. This is the query that doesnt work:
UPDATE `coupon-codes` SET `booking_date`=:timestamp WHERE `id` = :id
I also had a typo in the original question which had booking_id instead of booking_date field, but that doesn't matter, since I'm getting a SYNTAX ERROR.
Here is the PHP code I'm trying to run it with:
$stmt = $db->prepare("UPDATE `coupon-codes` SET `booking_date`=:timestamp WHERE `id` = :id");
$stmt->bindParam(':timestamp', $time);
$stmt->bindParam(':id', $id);
$stmt->execute();
Basic MySQL syntax:
'foo' - single-quotes. turns the quote word into a string literal
`foo` - backticks. used to escape table/fieldnames that happen to be reserved words
SELECT 'select' FROM ... -- select the literal word "select" from some table
SELECT `select` FROM ... -- select the field NAMED "select" from some table
SELECT select FROM ... -- syntax error - using a reserved word "select"
Given your error messages, you probably have one of the following:
UPDATE 'coupon-code' ... -- can't update a string. must specify a table name
UPDATE coupon-code ... -- math operation: coupon MINUS code - not a table name
Have you tried to use Predefined Constants (http://php.net/manual/en/pdo.constants.php);
Example:
$stmt = $db->prepare("UPDATE `coupon-codes` SET `booking_date`=:timestamp WHERE `id` = :id");
$stmt->bindParam(':timestamp', $time, PDO::PARAM_STR);
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->execute();

PDO insert new record to database based on lastInsertId()

Ive just started learning PDO and I'm struggling by simply inserting a new record based from
$lastid = $db->lastInsertId();
The ID gets created in the database table from another function.
But nothing happens when i try to insert a new record based on that ID.
function add_name($last_id, $name) {
$db = some_db();
$query = "INSERT INTO team (name) VALUES (:name) WHERE id = '".$last_id."'";
$stmt = $db->prepare($query);
$stmt ->bindParam(':name', $name, PDO::PARAM_STR);
$stmt->execute();
}
INSERT ... WHERE is not valid SQL. If you are inserting a new record, an autoincremnt ID will be generated at that time (if you have such defined for the table).
If you are trying to INSERT a new row into a related table with the last id from another table, then you would set that value as one of your column inputs. So the workflow would look like this:
INSERT [column data for table_a] INTO table_a
[GET autoincrement from last insert]
INSERT (table_a_foreign_key_column, [other table_b columns]) VALUES (table_a_id, [other table_b values) INTO table_b
UPDATE:
Since UPDATE is what you want, you can make update like this:
UPDATE team
SET name = :name
WHERE id = :id
You should use parameters for both name and id values. It is still not clear to me why you would need to make an insert and then an update within the same script execution. It's not like you received any more input from the user that you did not already have. I would guess you could just insert this name values when first creating the record and save yourself the extra trouble of multiple queries.
i think your sql query is wrong, try this:
function add_name($last_id, $name) {
$db = some_db();
$query = 'INSERT INTO team (id, name) VALUES (:id, :name)';
$stmt = $db->prepare($query);
$stmt ->bindParam(':name', $name, PDO::PARAM_STR);
$stmt ->bindParam(':id', $last_id, PDO::PARAM_INT);
$stmt->execute();
}
MySQL Insert Where query

dynamic update query using bind params

I am into situation where i dont know which fields would be set to update , i can get the columns and respected values which need to updated, but how can i get the type of each field for binding parameters using mysqli ?
UPDATE City SET Name = ?,CountryCode = ?,District = ? WHERE 1
Lets say this is the query i got as for now .. and I would something like this to update ..
$stmt = $conn->stmt_init();
if($stmt->prepare($query)) {
$stmt->bind_param('sss', $name, $countrycode, $district);
$stmt->execute();
}
but what if i dont know 'sss' ( in dynamic context ) ?
You can use string for everything. MySQL will convert strings to numbers when necessary. Just as you can do something like:
SET id = '123'
when writing a regular query.

Using WHERE IN (...) with PDO doesn't work when the string is bound

I have a query that looks like this:
UPDATE table SET column = UNIX_TIMESTAMP()
WHERE id IN (:idString)
Where idString is a string of comma separated ids and is passed to execute() in an array. To my surprise, when this query is executed, only the row with the first id in idString is updated.
After banging my head against the wall for a while, I finally decided to try it like this:
UPDATE table SET column = UNIX_TIMESTAMP()
WHERE id IN (' . $idString . ')
The second query works as expected.
Why won't the query work when I bind the string of ids using PDO?
In SQL, the string
'1,2,3,5,12'
Is a single value, and casting it in a numeric context, it will just have the value of the leading digits, so just the value 1.
This is much different from the set of multiple values:
'1', '2', '3', '5', '12'
Any time you use bound parameters, whatever you pass as the parameter value becomes just one single value, even if you pass a string of comma-separated values.
If you want to pass a set of multiple values to parameters in your SQL query, you must have multiple parameter placeholders:
UPDATE table SET column = UNIX_TIMESTAMP()
WHERE id IN (:id1, :id2, :id3, :id4, :id5)
Then explode your string of values and pass them as an array:
$idlist = array('id1' => 1, 'id2' => 2, 'id3' => 3, 'id4' => 5, 'id5' => 12);
$pdoStmt->execute($idlist);
For cases like this, I would recommend using positional parameters instead of named parameters, because you can pass a simple array instead of an associative array:
$pdoStmt = $pdo->prepare("UPDATE table SET column = UNIX_TIMESTAMP()
WHERE id IN (?, ?, ?, ?, ?)");
$idlist = explode(",", "1,2,3,5,12");
$pdoStmt->execute($idlist);
#mario adds a comment that you can use FIND_IN_SET(). That query would look allow you to pass one string formatted as a comma-separated string of values:
$pdoStmt = $pdo->prepare("UPDATE table SET column = UNIX_TIMESTAMP()
WHERE FIND_IN_SET(id, :idString)");
$pdoStmt->execute(["idString" => "1,2,3,5,12"]);
However, I usually don't recommend that function because it spoils any chance of using an index to narrow down the search. It will literally have to examine every row in the table, and during an UPDATE that means it has to lock every row in the table.
Your working solution is not good as it's subject to SQL INJECTION.
The reason it's not working is because you are allocating an array, instead of plain comma separated values.
You have to use implode to separate the values of the array, and then assign the comma separated values to a variable wich can be used by pdo.
Otherwise you can use instead of : $idString, ? in the select statement, and executing the prepared statement from and array which holds the $idString.
$query=$db->prepare("Select a From table where b =? order by 1;");
$query->execute(array($idString));
You are trying to pass a string as a set to a prepared statement. MySQL is trying to execute the query
-- assuming idString is "1,2,3,4,5"
UPDATE table SET column = UNIX_TIMESTAMP() WHERE id IN ("1,2,3,4,5");
instead of
UPDATE table SET column = UNIX_TIMESTAMP() WHERE id IN (1,2,3,4,5);
you'll have to either use the statement
UPDATE table SET column = UNIX_TIMESTAMP() WHERE id == ?
and execute it for however many id's you have or prepare the statement by injecting id string into the query
When binding, PDO expects a single value. Something like this will work, given your $idString above (though if you have the source array, even better!):
$ids = explode(',', $idString);
$placeholders = implode(', id', array_keys($ids));
if($placeholders) {
$placeholders = 'id' . $placeholders;
$sql = "UPDATE table SET column = UNIX_TIMESTAMP()
WHERE id IN ({$placeholders})";
// prepare your statement, yielding "$st", a \PDOStatement
$st = $pdo->prepare($sql);
// bind every placeholder
foreach($ids as $key => $id) {
$st->bindValue("id{$key}", $id);
}
// execute
$st->execute();
}

pdo update statement using concat is not working

I am still new to PDO and am having trouble getting the update statement below to work. I want to be able to update the name field by just appending to the current value with a comma and the new name. Resulting name field should be like james,doug,paul,etc. This is probably a simple answer but I haven't been able to find a solution through a lot of googling!
Thanks in advance
$stmt = $db->prepare('UPDATE table SET name = concat(name, ',' :name) WHERE id = :id');
$stmt->execute( array('name' => $name, 'id' => $id) );
you lack comma inside your concat.
$stmt = $db->prepare("UPDATE table SET name = concat(name, ',', :name) WHERE id = :id");
^ ^ here ^

Categories