Insert or Update if duplicate based on unique index - php

Here is what I want to do. Insert if the unique index (code) doesn't exist in the table already. If it exists then simply update the row.
I can't use primary key because it is Auto Increment ID. Here is the code
$sql="INSERT INTO codes (code,registration,country)
VALUES ('$war','$regi','$country') ON DUPLICATE KEY UPDATE code='$war', registration='$regi', country='$country'";
But it doesn't work because I think it is checking for duplicate primary key. So when I try to insert the row in which the value of column code is same as previous row I get Duplicate entry 'xxx' for key 'code' error. So how to make this work for unique index code ?
Ahmar

ON DUPLICATE KEY UPDATE works with UNIQUE indexes as well as PRIMARY KEY values. Try setting one of the values you are trying to update to be UNIQUE on your database table.

All you have to do is set code to be a unique index. Then, anytime you try to do an insert where code matches it will update instead.
Alter this code as needed
alter table `table` add unique index(`code`);

You are correct, having a primary key on your table will not allow you to insert duplicate key values.
In the past, I have used something like this:
SELECT COUNT(*)
FROM codes
WHERE code = '$war'
Then if the count is > 0, you know there's a duplicate and you do:
UPDATE codes
SET registration = '$regi', country = '$country'
WHERE code = '$war'
Otherwise you do:
INSERT INTO codes (code, registration, country)
VALUES ('$war', '$regi', '$country')
However, if we assume you're using MySQL, you might be able to make use of either INSERT IGNORE or REPLACE.
If you use:
INSERT IGNORE codes (code, registration, country)
VALUES ('$war', '$regi', '$country')
The values will be inserted if the code does not already exist. If the code does exist, no record is inserted and MySQL will silently discard the statement without generating an error.
I think what you probably want is this:
REPLACE INTO codes (code, registration, country)
VALUES ('$war', '$regi', '$country')
REPLACE INTO behaves just like INSERT INTO if the record is new. But if the primary key is duplicated, it will perform an UPDATE instead.
Again, INSERT IGNORE and REPLACE INTO are for MySQL only.
Reference: http://www.tutorialspoint.com/mysql/mysql-handling-duplicates.htm

Related

Insert or update (if exists) without primary key

I have the following database MySQL table.
id (PK, AI)
email
country
lastlogin
I have a regular query in PHP that inserts this into the table.
however, logically, if this code runs several times, the same row will be inserted to the database every time.
I want my reference for checking and duplication to be the email field, and if the email is the same, update the country and the lastlogin.
I checked on other questions for a similar issue and the suggested way was to use ON DUPLICATE KEY like this
INSERT INTO <table> (field1, field2, field3, ...)
VALUES ('value1', 'value2','value3', ...)
ON DUPLICATE KEY UPDATE
field1='value1', field2='value2', field3='value3', ...
However, my primary key is not the email field rather the id but I don't want to run the check on it.
One option is make the email field unique, and then it should behave the same as primary key, at least with regard to MySQL's ON DUPLICATE KEY UPDATE:
ALTER TABLE yourTable ADD UNIQUE INDEX `idx_email` (`email`);
and then:
INSERT INTO yourTable (email, country, lastlogin)
VALUES ('tony9099#stackoverflow.com', 'value2', 'value3')
ON DUPLICATE KEY UPDATE
email='value1', country='value2', lastlogin='value3'
If the email tony9099#stackoverflow.com already exists in your table, then the update would kick in with alternative values.
From the MySQL documentation:
If you specify ON DUPLICATE KEY UPDATE, and a row is inserted that would cause a duplicate value in a UNIQUE index or PRIMARY KEY, MySQL performs an UPDATE of the old row.
This approach doesn't only work with primary keys, it also works with any column having a unique index.
As Dan has mentioned, the ROW_COUNT() in-built function does not support this solution with a standard configuration.
MySQL::ROW_COUNT()
For UPDATE statements, the affected-rows value by default is the number of rows actually changed. If you specify the CLIENT_FOUND_ROWS flag to mysql_real_connect() when connecting to mysqld, the affected-rows value is the number of rows “found”; that is, matched by the WHERE clause.
If modifying the database schema is not an option, you could use the following method:
UPDATE `table` SET `country`='value1', `lastlogin`='value1' WHERE `email`='value3'
IF ROW_COUNT()=0
INSERT INTO `table` (`email`, `country`, `lastlogin`) VALUES ('value1', 'value2', 'value3')
you can use
$query=mysql_query("select * from table where email = 'your email'");
if(mysql_num_rows($query) > 0){
//update
}else{
//insert
}
You can load a row with the given email first and then decide if you have to insert or update depending on the existence of the loaded row. This needs multiple SQL statements, but it can be written in a DBMS vendor independent way. Use a surrounding transaction to handle concurrency. An index on the email-column is useful to keep the existence - check fast. Adding a unique - constraint on the email-column is an option to guarantee that there will never be multiple rows with same email.
You can do it manually like before inserting the value to table first check whether the value exists in table or not if yes then update your related field
$qry = mysql_query("select * from table where email='abc#abc.com'");
$count = mysql_num_rows($qry);
if($count > 0){
write your update query here
}else{
write your insert query here
}

Get inserted id if inserted happend by REPLACE INTO

I'm using REPLACE INTO to update the row where mod_id is the unique/primary key. I wanted to know the mysql_inserted_id() if it was inserted.
I tried this:
$query_2 = $DB->query('REPLACE INTO mods (mod_id, group_id, css) VALUES (0, 4585, "css string")');
$inserted_id = mysql_insert_id();
But I keep getting $inserted_id of 0 even if an insert happend.
I think, its better to use INSERT... ON DUPLICATE KEY UPDATE. The reason being REPLACE always delete the old row optionally and then insert new row. While INSERT...ON DUPLICATE KEY UPDATE, tries to update the existing row as far as possible (based on primary or unique keys). And you can last_insert_id()

MYSQL ON DUPLICATE KEY UPDATE didn't update

I have a mysql on duplicate key statement.
mysql_query("INSERT INTO statistics (classify, apply) VALUES ('$classify', 1)
ON DUPLICATE KEY UPDATE apply = apply + 1");
id classify apply
1 A 1
but it didn't update the existing row and it keep add another row, Where is the problem?
It's probably the column classify is not unique. You need to have a UNIQUE field in the table to make ON DUPLICATE KEY UPDATE work. If you have not set one, you can execute this statement below.
ALTER TABLE statistics ADD CONSTRAINT tb_uq UNIQUE (classify)
ON DUPLICATE KEY will update a row only when you try to insert a record that would throw a duplicate keys error (like the name states). So this happens only if you are a using a unique key or a primary key for that column. It looks like you didn't created a unique key for the classify column.

get the primary key after a DUPLICATE KEY error?

If I run an insert query but it fails because of duplicated key error is there any way to get its primary key without doing another select?
Basically:
INSERT INTO tbl (field) VALUES ('myvalue')
This fails because there is already a record with ID:1 and field:myvalue.
Now I Want to know that ID:1 without doing another query:
SELECT id FROM tbl WHERE field = 'myvalue'
is it possibile?
Here is a link that provides four different ways to deal with this:
http://mikefenwick.com/blog/insert-into-database-or-return-id-of-duplicate-row-in-mysql/
There is a provision with each library to get the id of the row which is inserted.
Like: for simple mysql_query() use mysql_insert_id() after that to retrive the id of the last inserted row
Check this link
EDIT:
Please Check that if you have defined the unique index for field column.
If yes then you cannot insert duplicate in the column field

On Duplicate Key Update (Non unique field)

I'm working on a CSV import script in PHP attached to a MySQL database. I want to give the users the option to either insert new rows if duplicates are found or update them.
I can't use ON DUPLICATE KEY UPDATE because the column cannot be unique, otherwise it won't cater for when they want to have duplicates.
How would I go about this?
Use 2 queries - a select query to determine if the row exists, then based on that result either an insert or update query.
I would script it for use on the command line. In your loop, check if an entry with the same key already exists. If it does, prompt the user to decide what to do using fgets(STDIN).
why not just add a UNIQUE key to the table, possibly spanning multiple fields?
here is an example given the following simple phonebook table:
CREATE TABLE phonebook (
firstname VARCHAR(255),
lastname VARCHAR(255),
home VARCHAR(50),
mobile VARCHAR(50)
)
you can easily add a key making firstname AND lastname together unique.
ALTER TABLE phonebook ADD UNIQUE (firstname, lastname)
that way you can use the ON DUPLICATE KEY UPDATE statement to easily update the phone numbers when the name is already on the list:
INSERT INTO phonebook (firstname, lastname, home, mobile)
VALUES ("john", "doe", "12345", "45678")
ON DUPLICATE KEY UPDATE home = "12345", mobile = "45678"
everything else is getting unnecessarily complex.

Categories