Duplicate Key Entry on Update query MySQL - mysql

UPDATE Table1, Table2
SET Table1.Col1 = 1, Table1.Col2 = 2, Table2.Col1 = 3
WHERE Table1.PKey = Table2.PKey AND Table1.PKey = 199
results in duplicate key entry
#1062 - Duplicate entry '199-1' for key 'PRIMARY'
please help i've been scratching my head. I want this query to be optimal and fast since its used inside a loop that loops through a lot of rows and updates for each one. Dont want to split into 2 queries since then it will be 2 separate query calls per row.

Your query above should work -- reference:
https://stackoverflow.com/a/9417254/1073631
Guessing that you're trying to update a primary key (unique) column with a value that is already in another row in that same table --- hence the duplicate entry error.

I think the primary key for your Table1 is on PKey AND Col1, i.e.
CREATE TABLE `Table1`
...
PRIMARY KEY (`PKey`,`Col1`)
The error about the duplicate entry '199-1' points in that direction.

Related

Number of rows that are using the foreign key

I have a problem with counting the number of items/rows that are using the foreign key.
For example.
Table "A" has a foreign key of "group_id" and there is a row with "group_id" of "5" and a couple of items/posts/rows in table "B" are using the foreign key (in this case the ID of "5"). How would I know how to cont the rows that are using that "group_id"?
Here's what I mean.
Thanks very much.
UPDATE
Here is a sketch that explains my problem
PK = Primary Key
FK = Foreign key
You can query the number of rows like this:
SELECT group_id, COUNT(*) FROM table_B GROUP BY group_id;
Your image seems to show that you want table_A to keep the count persistently as an attribute column.
Some people design triggers for this. For example, in an INSERT trigger on table_B, increment the count attribute column of table_A by 1. In a DELETE trigger on table_B, decrement the count column of table_A by 1.
This sort of works, but it causes more overhead for inserts and deletes, and it causes more exclusive locking on table_A.
It's easier to do the SELECT query that I showed above.

mysql - INSERT... ON DUPLICATE KEY UPDATE, but not really...?

Hi I've been trying to get this to work, I thought I had it with mysql - INSERT... ON DUPLICATE KEY UPDATE, but no luck.
I have a table as such:
sessionID is unique,
productID references another table and is not unique, but not common, should be a max of 3 rows containing the same value,
sessionType is either 1, 2 or 3, and would link with productID,
I need to check if the table has a row where there is a matching pair of productID and sessionType, if there is then sessionDate & sessionCapacity in that row should be UPDATED, if there isn't then a new row inserted.
$vals = array($pID,$data['pSessionDate'],'1',$data['pQty'],$pID,$data['pSessionDate'],'1',$data['pQty']);
$db->Execute("INSERT INTO VividStoreSessions (pID,sDate,sType,sCapacity) VALUES (?,?,?,?) ON DUPLICATE KEY UPDATE pID=?,sDate=?,sType=?,sCapacity=?",$vals);
Hope that makes sense to someone and thanks in advance for any help!
Your insert looks valid. But, first you need a unique index/constraint:
create unique index unq_VividStoreSessions_productId_sessionType
on VividStoreSessions, productId, sessionType)
Then you can write the code to only use four parameters:
INSERT INTO VividStoreSessions (pID, sDate, sType, sCapacity)
VALUES (? ,?, ?, ?)
ON DUPLICATE KEY UPDATE sDate = VALUES(sDate), Capacity = VALUES(Capacity);
Finally, you need to ensure that sType only takes on the values of 1, 2, or 3. Perhaps you want to enforce this at the application layer. Otherwise, you need a trigger or foreign key constraint to ensure that there are only three rows.

On duplicate key ignore - Update multiple tables

I am attempting to insert data into two tables (table1 and table2), conditional on the uniqueness of the data being entered into table1. Table1 has a unique key set on pop & email & neighborhood. The idea is that if the same person submits the same pop in a neighborhood, then nothing happens in either table. If someone else enters the same pop and neighborhood then it enters the data in table1 and increases the votes in table2 by 1. I have heard some people talking about "on duplicate key ignore" which I think would work if implemented as below but I am not actually sure that the command is real:
mysql_query("INSERT INTO `table1` VALUES ('$pop','$first', '$last', '$email',
'$neighborhood') on duplicate key ignore (INSERT INTO `table2`
VALUES ('$pop', '$neighborhood','$votes', '$city') ON DUPLICATE KEY UPDATE
`votes` = `votes` +1)");
I have the following code working but understand that it will enter data into table2
regardless of unique data in table1.
mysql_query("INSERT INTO `table1` VALUtS ('$pop','$first', '$last', '$email', '$neighborhood')");
mysql_query("INSERT INTO `table2` VALUES ('$pop', '$neighborhood', '$votes', '$city') ON DUPLICATE KEY UPDATE `votes` = `votes` +1");
Please let me know if you have any questions.
Why not have a single table? Change your unique key to pop,neighborhood,email (so pop,neighborhood are the leftmost two and can be used in a group by) and drop the 'votes' column. You can then run a query like SELECT pop, neighborhood, count(*) AS votes FROM table1 GROUP BY pop,neighborhood;
I don't think there's any such thing as ON DUPLICATE KEY IGNORE, but there is INSERT IGNORE INTO ... which basically says don't return any errors if the insert failed. If you need to keep separate tables you'll have to run the first query, check to see if you got a duplicate key error, then insert...on duplicate key update into the second table.

ON DUPLICATE KEY UPDATE ... with WHERE or subselection?

i am a bit concerned about one of my mysql queries... The following query receives a variable $DB_id... if a row with that primary key already exists the query performs an update.
$this->db->query(" INSERT INTO modules_text
( module_id,
module_content,
module_index
)
VALUES ( '{$DB_id}',
'{$content['text']}',
'{$index}'
)
ON DUPLICATE KEY
UPDATE module_content = '{$content['text']}',
module_index = '{$index}'
");
NOW THE THING THAT CONCERNS ME... There is no relation if the affected rows actually belong to the user. I would like to add a where statement to the UPDATE part or first make a subselecion of the rows which are permitted to be affected. SOmething like:
[...]
ON DUPLICATE KEY
UPDATE module_content = '{$content['text']}',
module_index = '{$index}'
WHERE module_post_id = '{$post]}'
Is this somehow possible... Until now i didnt find a solution... Any help would be very appreciated... THANKS A LOT!!!!!
Saludos Sacha!
This isn't how ON DUPLICATE KEY works. The update portion of the INSERT will only occur if there's a match for the UNIQUE key(s) or PRIMARY key for the table. (i.e.: The UNIQUE/PRIMARY key(s) are effectively the WHERE clause.)
See the full MySQL docs for more information.

How to insert a row, but on duplicate; update it instead?

I have a table which contains the items the users of my game owns. If a user buys a new item, it should be inserted, but if he already got it, it should be increased instead.
I understand I can use INSERT ... ON DUPLICATE KEY UPDATE, but I don't understand how in my problem.
The item_id isn't unique, because many players can own the same weapon (ie. a longsword). The user_id isn't unique either, because a player can own many items.
So, my question is how to make the query UPDATE instead of INSERT if a row containing both the user_id and item_id already exists?
I know this question is old but none of the answers are correct.
You need a PRIMARY or UNIQUE index on user_id and item_id (both columns in one index).
Then you can use "INSERT INTO ... VALUES ... ON DUPLICATE KEY UPDATE count=count+1" no problem.
This is EXACTLY what ON DUPLICATE UPDATE will do for you.
That's not what the "ON DUPLICATE KEY UPDATE" will do for you. If it were me, I would attempt the insert. If it failed, check why (you're checking for errors already, right?). If it's because of a duplicate key, do your update. If the error is for some other reason, then handle that appropriately.
You do want ON DUPLICATE KEY UPDATE. It looks for the Primary Key of the table, and if it exists, updates all the other rows.
So your table has a primary key of (userid, itemid) and the following values:
userid itemid strength
4 5 6
And you want to bump it to strength=9, use this:
INSERT INTO table ON DUPLICATE KEY UPDATE VALUES(4,5,9)
It will insert a row with 4,5,9 if it doesn't exist, and will update strength to 9 on the row with primary key (4,5) if it does exist. It won't update any other rows (e.g. rows with userid4 but itemid 10 or itemid 5 but userid 70) because they don't match the whole PK.
You could do something like the following (assumes your user id is in the variable UserID and item ID is in item_ID) :
SELECT
#rowCount := COUNT(*)
FROM
table
WHERE
user_id = UserID
AND item_id = ItemID;
IF (#rowCount > 0) THEN
... do update
ELSE
... do insert
END IF;
Can you do something like
UPDATE TABLE
set COL = 'BLAH BLAH'
where ITEM_ID = #itemid AND USER_ID = #userid
IF ##ROWCOUNT = 0
BEGIN
INSERT INTO TABLE (col...)
VALUES (vals...
END