Why are 2 rows affected in my `INSERT ... ON DUPLICATE KEY UPDATE`?
Asked Answered
M

2

113

I'm doing an INSERT ... ON DUPLICATE KEY UPDATE for a PRIMARY KEY in the following table:

DESCRIBE users_interests;
+------------+---------------------------------+------+-----+---------+-------+
| Field      | Type                            | Null | Key | Default | Extra |
+------------+---------------------------------+------+-----+---------+-------+
| uid        | int(11)                         | NO   | PRI | NULL    |       |
| iid        | int(11)                         | NO   | PRI | NULL    |       |
| preference | enum('like','dislike','ignore') | YES  |     | NULL    |       |
+------------+---------------------------------+------+-----+---------+-------+

However, even though these values should be unique, I'm seeing 2 rows affected.

INSERT INTO users_interests (uid, iid, preference) VALUES (2, 2, 'like')
ON DUPLICATE KEY UPDATE preference='like';
Query OK, 2 rows affected (0.04 sec)

Why is this happening?

EDIT

For comparison, see this query:

UPDATE users_interests SET preference='like' WHERE uid=2 AND iid=2;
Query OK, 1 row affected (0.44 sec)
Rows matched: 1  Changed: 1  Warnings: 0
Malda answered 19/9, 2010 at 20:23 Comment(6)
Why do you have two primary keys in the first place?Inconsequent
@Pekka, the PRIMARY KEY is a single pk created on (uid, iid) since most queries will be run when both values are known.Malda
@Josh I see. The manual seems to discourage it though: In general, you should try to avoid using an ON DUPLICATE KEY UPDATE clause on tables with multiple unique indexes. Does it need to be a primary key? Why not a normal index?Inconsequent
@Pekka, honestly not sure. I'm still relatively new to this. Does an index make more sense in this case?Malda
@Josh yup, a normal index spanning both columns should would work fine hereInconsequent
Pekka - To me he appears to be saying that there is indeed only one index, across both columns. (AFAIK MySQL won't allow you to declare two primary keys anyway.)Preoccupied
I
249

From the manual:

With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if the row is inserted as a new row and 2 if an existing row is updated.

Icon answered 19/9, 2010 at 20:31 Comment(6)
And 0 if an existing row is set to its current values.Majors
I just wonder what would be the rationale behind it.. clearly, it could have been returned as response code instead of number of rows affected to make it less confusingBerny
... :|. Is there a way to determine the actual number of rows affected? Even if an existing row is updated, there is still only one row affectedRossiya
Is this the same for batch inserts as well? … VALUES (2, 2, 'like'), (3, 3, 'like'), (4, 4, 'like') ON DUPLICATE …Razorbill
I wonder how many like me wasted 30 minutes trying to figure out WHICH two rows were updated...only to discover this arcane abuse of an interface.Wisniewski
@Majors and on the same paragraph in the doc, there's a flag CLIENT_FOUND_ROWS that makes such case return 1 instead of 0Phox
B
9

So you know whether you updated a row (duplicate key) or just inserted one: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

Berthaberthe answered 19/9, 2010 at 20:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.