Update post/row, instead of creating new one - php

I am building a system, where you can create blog posts for your website.
In there I have an ajax-function which is saving a draft of your post every two minutes.
In this way you're not losing your work if your computer or internet crashes.
But right now, it is saving a new row every time it auto-saves. How to I do, so instead of creating multiple rows, it is updating the row instead?
I have already tried with ON DUPLICATE KEY UPDATE, which didn't work. I think it might be because that it requires an unique field in the form. But the only unique in my database is the actual ID of the post/row.
This is the code I tried:
INSERT INTO blog (title, text, date)
VALUES ('$blog_title','$blog_text','".time()."')
ON DUPLICATE KEY UPDATE
title='$blog_title', text='$blog_text', modified_date='".time()."'
I have an idea, to get the post/row ID, when the post is auto-saved the first time. Here I could use mysql_insert_id(). Then this ID could be stored in a hidden input field and when it auto-saves again, it will see that there already is a post/row with that ID, and then it will just update instead of creating a new one.
Is that a good and safe solution, or should I do something else?
I can't seem to find a better one.
I have found some other similar questions, but they where using JSON, which I haven't worked with yet.
Hope someone can help me with this :)

When you create a new row, put the ID into a hidden field. Then the code to process the input can do:
if ($_POST['id']) {
// update existing row
} else {
// insert new row and put ID into hidden field
}
There's no need to use ON DUPLICATE KEY because you know from the input data whether it's indended as a new entry or an update.

Related

CakePHP: inserting into a MySQL ARCHIVE engine table

I have a small ARCHIVE engine table that I want to submit logs into whenever someone does something. I am not giving a unique "id" to every row; instead my "id" column is the user's ID.
I use this->model->save() and the first insert is fine. The problem is Cake thinks I'm trying to UPDATE on the second time that someone does something, when really all I want is to create another record, with the same user's ID, with a different action or timestamp.
How do I force CakePHP to INSERT only, without using query()? And without having to make 5th column for "row ID"?
Always make sure to unset the primary key. For instance in the beforeValidate. This will trigger a save instead of an update.
See the documentation

Mysql update BUT keep the old data?

In a customer CMS the customer can update their personal information, like change their address and first/last name. I use a mysql UPDATE query for that.
Problem with working like this is, is that people can change their information. E.g. change their name from john doe to asdfdas. I would like to SAVE their old information.
What are my options? What is the best way to do this?
Assuming the user has a unique ID you could have an old_user_information table and when you do an update also do a new entry into that table. The table would have an autogenerated ID as well as the unique user ID and the rest of that users past information.
A user could have multiple rows in this table but only one row in the real Users table.
Edit: If I were you I would write a stored procedure that does both of these things so that it is easier to manage if things change.
You can make table that contains something like this
`yourTableID, field, value, date`
and update this with a trigger. You write an update trigger that adds the old value if it is changed. Look at the manual here to find out more about triggers.
If you don't want to use triggers you could obviously do the same in your logic: just update the history table with the old value. But this needs some trickery to find out if you need to update it, but nothing to complicated.
For easy retrieval what happened you might want to add something like "oldvalue" AND "newvalue", but the latter isn't really needed, as it is either in the next update as 'old' value, or it is the current value.
Create new columns for the data being updated column would be prior_to_update_column
On update, move the old info into prior_to_update_column
If the user updates again, append to the prior_to_update_column seperated by , (to look like an array).
This should keep all the previous info the user updates
add an additional field name version
and use Insert instead of update
あの答えのとうりに、やってない。
UPDATE table name SET column=column+'new value' WHERE condition

MySQL Many to Many. To delete or to edit?

I have a Many-to-Many table, in which I input some form info. I recently made this form dynamic, so that when an input elements value is changed, it is sent to database via AJAX.
So my question is:
Is it faster to try and find the values that exist, edit them, create the ones that don't and delete the ones that are not used anymore OR Should I delete all of the values for the id, and insert all of the new ones?
In response to comment, an elaboration.
A form , that has about 10 fields. Some of them mandatory, some not. Every time you access it, it generates a random identifier.
When a user starts filling the form, after the focus an element is lost, the whole form is submitted through AJAX, and all of the values that are not empty, are input in the many to many table.
The table has 3 fields : form identificator , element name , element value;
The question rephrased:
Do I delete all of the entries with the required form identificator, or try to find the fields and edit them?
It will require less code to delete all the existing relations and add new ones
Make sure you do this in a transaction
Handle errors correctly
Less code == fewer bugs, less developer time. So that is definitely faster.
I always delete all & insert in cases like this. I'd suspect that it'd be more processing time to search, edit, create, delete.
You can also try looking at:
INSERT INTO table (field1, field2) VALUES ('Value1', 'Value2')
ON DUPLICATE KEY UPDATE field1 = 'Value1'
Which will insert a new record or update an existing -- I'd still suspect the delete/insert to be faster -- depending on the number of fields you'd be updating at any given time.

How to archive changes to table rows?

I have a MySQL database where I am storing information that is entered from a PHP web page. I have a page that allows the user to view an existing row, and make changes and save them to the database. I want to know the best way to keep the original entries, as well as the new update and any subsequent updates.
My thought is to make a new table with the same columns as the first, with an additional timestamp field. When a user submits an update, the script would take the contents of the main table's row, and enter them into the archive table with a timestamp when it was done, and then enter in the new values to the main table. I'd also add a new field to the main table to specify whether or not the row has ever been edited.
This way, I can do a query of the main table and get the most current data, and I can also query the archive table to see the change history. Is this the best way to accomplish this, or is there a better way?
You can use triggers on update, delete, or insert to keep track of all changes, who made them and at what time.
Lookup database audit tables. There are several methods, I like the active column which gets set to 0 when you 'delete' or 'update' and the new record gets inserted. It does make a headache for unique key checking. The alternative I've used is the one you have mentioned, a separate table.
As buckbova mentions you can use a trigger to do the secondary insert on 'delete' or 'update'. Otherwise manage it in your PHP code if you don't have that ability.
You don't need a second table. Just have a start and end date on each row. The row without an end date is the active record. I've built entire systems using this method, and just so long as you index the date fields, it's very fast.
When retrieving the current record, AND end_date IS NULL gets added to the WHERE clause.
In this situation, I would recommend you to consider all properties in one table after adding it few columns:
active/ not active
ID of the person who kept these parameters
timestamp of adding

INSERT command inserting duplicates

I am writing a quiz website.
What should happen is:
A page has a question on it and four buttons or a textbox.
When you click a button, it calls itself with
the answer number in the address
like: ?q=[question number]&a=[answer].
If the question
uses a textbox it POSTs the answer.
This code should then detect that
something has been sent to it and
write that to a database.
The user id is stored in a cookie.
There is also a key column in the database. the idea is that it stores all answers a user has submitted over time and users can change their answers.
<?PHP
mysql_connect("------", "------", "------") or die();
mysql_select_db("------") or die();
$q=$_GET['q'];
if(isset($_GET['a'])){
$a=$_GET['a'];
} else {
$a=$_POST['longanswer'];
}
if(isset($a)){
$u=$_COOKIE['id'];
if($qust['atype']==1){
mysql_query("INSERT INTO answers (`userid` ,`answer` ,`qid`) VALUES ($u, $a, $q);");
} else {
mysql_query("INSERT INTO answers (`userid` ,`answer` ,`qid`) VALUES ($u, '$a', $q);");
}
}
?>
I don't think it should matter, but later on on the code, it queries the database with the SELECT command.
When i run this code, it seems to enter 2 or 3 entries to the database. The trend seems to be that when i run the code it enters the previous answer, followed by the new answer.
Any help would be greatly appreciated. Thanks,
Logan
It seems like what you want to do is to allow only one answer per question per user. If that's the case, you'll want a UNIQUE constraint on your table on userid and qid:
ALTER TABLE answers ADD UNIQUE(userid,qid);
This will result in an error when you try to insert a row with the same userid and qid. If you want to allow users to change their error, you can change your INSERT query to:
INSERT INTO answers (userid ,answer ,qid) VALUES ($uid, '$answer', $qid) ON DUPLICATE KEY UPDATE answer='$answer'
This will prevent multiple records from showing up in the database, but multiple INSERTs might still be called from your PHP code. To fix that, we'd have to see some more of your code.
Another option would be to first try to retrieve the data you're about to enter into the database. If you find it, it's already there, so don't add it again. The suggestions for using constraints are sound but if the data you're trying to prevent duplicates of isn't easily added to the constraints or the data you don't want duplicates of is not exactly the same data (say just similar data) then this is another option.
The unique constraint mentioned by cmptrgeekken should definately be added if you only allow one answer per user, but then you must also handle the primary key violation if it occurs: Inform the user it has already replied OR replace the previous value, depending of how you want the site to work.
Also, Is for some reason the request triggered more than once? Maybe by javascript, or some other logic of yours? If duplicate answers appears when you only click once, this seems to be the case.
/B

Categories