From MySQL 4.1.0 onwards, it is possible to add ON DUPLICATE KEY UPDATE
statement to specify behavior when values inserted (with INSERT
or SET
or VALUES
) are already in destination table w.r.t. PRIMARY KEY
or some UNIQUE
field. If value for PRIMARY KEY
or some UNIQUE
field are already in table, INSERT
is replaced by an UPDATE
.
How does
ON DUPLICATE KEY UPDATE
behave in case there are multipleUNIQUE
fields in my table ?Can I have one update only, if either
UNIQUE
field is matched ?Can I have an update only if both
UNIQUE
fields are matched simultaneously ?
Consider
if a and b are
UNIQUE
fields,UPDATE
occurs ona = 1 OR b = 2
. Also when conditiona = 1 OR b = 2
is met by two or more entries, update is done only once.Ex here table table with Id and Name
UNIQUE
fieldsIf query is
then we get
which violates uniqueness of Id and Name. Now with
we get
Behavior on multiple keys is the following
UPDATE
inON DUPLICATE KEY UPDATE
is performed if one of theUNIQUE
field equals the value to be inserted. Here,UPDATE
is performed onId = 1 OR Name = C
. It is equivalent toWhat if I want one update only, for either key
Can use
UPDATE
statement withLIMIT
keywordwhich will give
What if I want one update only if values for both keys are matched
One solution is to
ALTER TABLE
and make thePRIMARY KEY
(or uniqueness) work on both fields.Now, on
we get
since no duplicate (on both keys) is found.
how does MySQL behave ... It behaves as expected, that is executes ON DUPLICATE KEY clause.
Can I have one update for either... In reality, you have only one ON DUPLICATE KEY clause, so you need to put some code to differentiate which constraint was involved. Fortunatelly, it is possible. The only thing you should know, the order of assignment matters, and you can assign multiple times. Suppose, you have unique constraint on a and b, and you want to update c only if a uniqueness is involved: ... KEY UPDATE c = IF(a = VALUES(a) and b <> VALUES(b), VALUES(c), c), b = VALUES(b)
but if you change the order of assignments the second condition within if will be always false.
See 2.