PHP/MYSQL: Update query after delete query removes relevant rows - php

Hello Stack Overflow Community,
I have a table which stores information about an event running sheet. When a user updates this timesheet, I first insert the new data, in order, to the end of the table. To differentiate this data from the data last entered/updated, I have a boolean column called 'transit', and all such new data is marked as TRUE, whilst all previous data is marked as FALSE.
The idea behind this is that in case an error occurs while updating the table with the new data, the previous data is not lost, which would be the case if I deleted all data from the table first, and then entered the new rows.
Creating these rows is working fine, however when I conduct the following code...
$query = "DELETE FROM " . $table_name . " WHERE transit = 0";
if (!$result = mysqli_query($conn, $query)) {
echo("Query Error: " . mysqli_error($conn));
exit();
}
$query = "UPDATE " . $table_name . " SET transit = 0";
if (!$result = mysqli_query($conn, $query)) {
echo("Query Error: " . mysqli_error($conn));
exit();
}
...all the new data which was inserted with transit = 1 is deleted. After I did some research on Stack Overflow, it was apparent I should be using mysqli_multi_query(); - When I tried that with this modified code...
$query = "DELETE FROM " . $table_name . " WHERE transit = 0; UPDATE " . $table_name . " SET transit = 0";
if (!$result = mysqli_multi_query($conn, $query)) {
echo("Query Error: " . mysqli_error($conn));
exit();
}
.... I was getting the "Commands out of sync; you can't run this command now" error.
Closing and reopening the connection between the sequential queries did not make a difference, nor did adding:
mysqli_store_result($conn);
mysqli_free_result($result);
while (mysqli_next_result());
help either, as someone suggested on another post. Is this some sort of buffer issue with MySql? Any help would be appreciated!
Thank you very much for taking the time to read!
UPDATE
So the logic seems to in fact work, ie enter new data and mark it with transit = 1, delete all data marked with transit = 0, then set all remaining data to transit = 0, when using the mysqli_multi_query() function, as well as the mysqli_store_result($conn); mysqli_free_result($result); while (mysqli_next_result());, as I described above. However, as described, this throws the Commands out of sync error. I thought that meant the queries had failed, but apparently, they have succeeded.
In that case, what is causing this error to throw? Thanks!

Related

I cant update the reserve of products in Database

I am building an e-shop, and I want to update the reserve on products in the database but the code is not working properly. Can you check it out, please
if (filter_input(INPUT_GET,'checkout')){
$sql="UPDATE tblproduct SET apothema=18 WHERE id=1"}
if (filter_input(INPUT_GET,'checkout')){
$sql="UPDATE tblproduct SET apothema=18 WHERE id='1'";
// connect to database to run your query so the above query will execute
$run = $conn->query($sql);
//this is optional
//you can use like this to check if your connect is success and data is inserted.
if ($conn->query($sql) === TRUE) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
}
I think the problem is only here WHERE id = '1' "; remember that you need to use that'value to compare'and don't forgot to put ; in the end too. One more thing, you need to connect to database and run query to insert data to your database.

Doctrine Entity Manager gets Read Only error from database

public function save($itemId, $invoiceName)
{
$query = "
INSERT INTO invoice (item_id, invoice_name)
VALUES (" . $itemId . ",'" . $invoiceName . ")
";
$connection = $this->entityManager->getConnection('master');
return $connection->executeQuery($query);
}
Error while trying to insert into table:
An exception occurred while executing ' INSERT INTO invoice (item_id, invoice_name) VALUES (10600029,'FV/1823/06/2018/SOL') ': SQLSTATE[HY000]: General error: 1290 The MySQL server is running with the --read-only option so it cannot execute this statement
Checked connection to DB its fine.
Tried to save something with same user with a DBeaver DB client and it went through all fine - saved without any problem.
you need to close the connection used before to change connection and insert I think, try something like this:
$connection = $this->entityManager->getConnection()->close();
$query = "
INSERT INTO invoice (item_id, invoice_name)
VALUES (" . $itemId . ",'" . $invoiceName . ")
";
$connection = $this->entityManager->getConnection('master');
return $connection->executeQuery($query);
Even tho I specified 'master' the request was catched by slave all the time.
$entityManager->getConnection()->prepare('INSERT ... ')->execute();
Appeared to fix the problem.

When i inserting data into mysql it insert two datas, and i dont know why

When i inserting using this code it insert two datas and i downt know how to fix it
$sql = "SELECT Version_id FROM versions ORDER BY Version_id DESC LIMIT 1;";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$lastVersion =$row["Version_id"];
}
}
echo($lastVersion);
$lastVersion++;
$sql = "INSERT INTO versions (version)
VALUES ('v$lastVersion')";
if (mysqli_query($conn, $sql)) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . mysqli_error($conn);
}
While I don't exactly understand what you mean with "two datas", I do see multiple issues with your code.
First of all it is horribly inefficient and prone to race conditions. It's also quite wrong, in that it doesn't do what you want it. Not to mention should be replaced with native database functionality.
Most of these can be fixed by simply changing the version_id field to a AUTO_INCREMENT. This will automatically give the new record the next available ID in the set, exactly as what you're trying to do. Then you can retrieve this ID by using "lastInsertId()"
That'll make all of the code in your post superflous, and only require you do do something like this when actually inserting data:
$sql = "INSERT INTO `version`(`setting`, `date`) VALUES (:setting, :date)";
$stmt = $db->prepare ($sql);
$res = $stmt->execute ($data);
$newID = $db->lastInsertId ();
After this the new version ID is stored in the $newID variable.
Of course, if you want to UPDATE the version ID for some reason, then INSERT is the wrong command to use. Also, why use an entire table for what's basically a simple version number? In short, your whole table doesn't make a whole lot of sense for me.
I recommend explaining the rationale behind it, so that we can possibly come up with some better solutions you can use.

Call a PHP function inside of a while loop

I have a function which gets a particular set of users from a table where a particular WHERE condition is meet.
I need to send each of them a message.
So, I used another function to send the message. And called that function inside he following while loop
while($user= mysqli_fetch_assoc($users_set)){
send_message($user['email']);
}
So, the problem is, the function is called only just one time. (Only with the last value of the loop)
How to fix this problem and make the function called with each value of the loop...
This is the full code...
$query = "SELECT * ";
$query .= "FROM user ";
$query .= "WHERE confirmed = 0";
$user_set = mysqli_query($db_conx, $query);
confirm_query($user_set);
while($user = mysqli_fetch_assoc($user_set)){
send_message($user['email']);
}
Here is the send message function....
function send_message($email){
global $db_conx;
$invitee_user = get_user_by_email($email);
$query5 = "INSERT INTO notification(";
$query5 .= "description, user_id";
$query5 .= ") VALUES(";
$query5 .= "'You have been confirmed'";
$query5 .= ", {$invitee_user['id']}";
$query5 .= ")";
$result5 = mysqli_query($db_conx, $query5);
if($result5){
//$_SESSION["message"] = "Notification sent". \mysqli_error($db_conx);
return "OK";
}else{
//$_SESSION["message"] = "Failed to send notification". mysqli_error($db_conx);
}
}
Here is the code for confirm_query()
function confirm_query($result_set){
if(!$result_set){
die("Fatal Error Occured : Database Query Failed Report this error");
}
}
I would just boil this down to one query and get rid of all the looping stuff
INSERT INTO notification (description, user_id)
SELECT 'You have been confirmed', user_id
FROM user
WHERE confirmed = 0
Your current logic is really convoluted.
You query the user table to get the user email field, then pass that email as parameter to your function only to then turn around and (I presume) look up the user ID based on email (when you already had this information from your initial query), then you make insert.
This means that for every record you return from first query, you need to do 2 queries to insert to the notification table. So if you had 100 results you would end up doing a total of at least 201 queries to complete the insertions.
Using my approach you make 1 query regardless of how many rows are affected.
One takeaway that you should get from this is that, anytime you see yourself trying to do some sort of nested querying, you should recognize this as an anti-pattern (a coding pattern that you do not want to typically use). There is usually a better approach that can be taken if you rethink how you are writing your queries.

php postgres UPDATE: check for success

I'm attempting to UPDATE my postgres table on Heroku and have been blocked by the eccentricity of the UPDATE statement.
My initial guess was to say:
$query = pg_query($someDB, $updateQuery);
and then check if it is false, but to no avail. Here's the troublesome snippet:
$update_query = "UPDATE jellybeans SET $form[1]=$data[1], $form[2]=$data[2] WHERE $form[0]='$data[0]'";
echo 'attempting update: ' . $update_query . '<br>';
$update = pg_query($connect, $update_query);
echo "Rows updated: ", pg_affected_rows($update);
//if update failed, push to the table
How does one check on statements like INSERTS, DELETES, and the like? I'm surprised affected_rows doesn't return anything meaningful. Much appreciated.
*EDIT: * Using a SELECT query first yielded the best result:
$exists_query = "SELECT * FROM jellybeans WHERE $form[0]='$data[0]'";
$exists = pg_query($connect, $exists_query);
if($row = pg_fetch_row($exists)){
$update_query = "UPDATE jellybeans SET $form[1]=$data[1], $form[2]=$data[2] WHERE $form[0]='$data[0]' RETURNING *";
echo '<br>' . 'Attempting: ' . $update_query;
$update = pg_query($connect, $update_query);
}else{
$insert_query = "INSERT INTO jellybeans VALUES('$data[0]', $data[1], $data[2])";
echo '<br>' . 'Attempting: ' . $insert_query;
$insert = pg_query($connect, $insert_query);
pg_free_result($insert);
}
pg_free_result($exists);
pg_free_result($update);
From there a simple $row = pg_fetch_row($exists) gives a reliable existence check. In the future, it would probably be best to add an IF FOUND check into the query itself.
One way of knowing is to get the updated rows:
UPDATE ... WHERE condition RETURNING *;
This will return the set of rows updated, just count the number of results.
CREATE OR REPLACE PROCEDURE public."ChangePassword"(
IN id int,
IN pwd text,
OUT affectedrows int)
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
UPDATE "UserProfile" SET "Password" = pwd WHERE "Id" = id;
GET DIAGNOSTICS affectedrows := ROW_COUNT;
END
$BODY$;
After execution of the stored procedure in below way, it will return the affected row count(s), if any.
Why are you even using pg_* functions? Have you considered using PDO instead? You'd probably have more luck with PDOStatement::rowCount.

Categories