Question

In MYSQL how do I update (not replace) a row if it exists else create a new row.

The column that I need to test is not the primary key, it holds an email address.

basically I have a table that stores emails and other random data. I reference the rows as saved sessions by the primary-unique-auto-incriminating-number column (id)

The reason I uses the id column to refer to the session data rather than the email column is because the email is entered by the user who has no idea about the id columns existence.

EDIT: And the reason why I am not refering to the session by the email is because emails are too/different lengths (long story but they make my QR Codes all different sizes and I don't wan't to expose emails)

I am pretty sure of two things:

REPLACE INTO

this looks like it will destroy my id number as this method copies the row while it removes the old

and

ON DUPLICATE KEY UPDATE

this seems require comparison of a unique key (id) which is not what I need it would be better if I could do something like:

ON DUPLICATE email UPDATE

or something like this (but I don't think it is valid MYSQL):

var email='email@address.com';
var mysql=
"UPDATE table SET (...) WHERE email='"+email+"' "+
"IF @@ROWCOUNT=0 "+
"INSERT INTO table VALUES (...)";

MYSQL can't be THAT ridged can it?

Was it helpful?

Solution 2

From the docs: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html, you only have to use a unique key field. I mean, if you transform the email field as an unique field, running:

ALTER TABLE `your_table` ADD UNIQUE INDEX `email` (`email`);

now, when you try to insert a row with the same email, using INSERT ... ON DUPLICATE KEY UPDATE, it'll update the values of all the fields while keeps the value of the email untouched:

a | b | email
1 | 1 | existed@email.com

After running...

INSERT INTO my_table ( a, b, email ) VALUES ( 2, 2, 'existed@email.com' ) 
on duplicate key update a=VALUES(a), b=VALUES(b)

you'll have

a | b | email
2 | 2 | existed@email.com

Keep an eye on specify which fields you want to be updated, if you don't specify them, it won't be updated!

EDIT: Now, with a SQLFiddle to show it working: http://sqlfiddle.com/#!2/79e67/3

OTHER TIPS

Actually, you answered your question yourself: Yes, any SQL-buildt-in update/replace method that can fall back to insert needs a unique field. To update a non-unique-field, you´ll have to use a where-condition and check if any rows has been altered. (Keep transactioning in mind)

I see that for some reason you do not want a unique email-column. Did you see that you can have multi-column unique indeces?

If, for example, you had a unique index over email and timestamp, you could use ON DUPLICATE KEY UPDATE. If email comes first in the order of the 2 columns, it even substitutes for the non-unique email-only index.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top