Home » Php » Mysql — Need something like UPDATE […] ON DUPLICATE KEY […]

Mysql — Need something like UPDATE […] ON DUPLICATE KEY […]

Posted by: admin October 26, 2017 Leave a comment


I’m validating the e-mails of several databases.
Our validation provider created us a list of e-mails with a status to put (checked, non-responding, and so on…)

But for some adresses, we also got a fix (e.g. [email protected] => [email protected]mail.com)

I need to put the right status (20), and only sometimes fix the e-mail. I also could have to fix the mail while the status is already right.

My current PDO request to update those is as follows :

$req_fix_mail_and_update_status = "
    UPDATE {$user_table_name}
        SET status = :mail_status1
        , {$mail_column_name} = :mail_fixed1
    WHERE (({$mail_column_name} LIKE :mail_address)  OR  ({$mail_column_name} LIKE :mail_fixed2))
        AND ((status != :mail_status2) OR ({$mail_column_name} NOT LIKE :mail_fixed3))

Now, here comes the tricky part :

One of the databases stores data about several websites, and may contain mail duplicates.

I got a composed unique constraint on something like (fk_site, email)

… and an edge case, with some e-mails having both “fixed” and “non-fixed” values entries

e.g. :

Login   FK_Site  Mail            Status
Alice        01  [email protected]        0
Alice        01  [email protected]         0
Bob          02  [email protected]         0

Of course, trying to fix the wrong adress would makes duplicate invalid because of the (fk_site, email) unique constraint would fail on Alice => the requests fails (#$%§@&!).

But Bob stil needs his mail fixed, and the lines need their status updated, too !

I’m looking for a way to get around this, but can’t find anything with SQL.
Making one (say, up to two) more requests when I fail could be ok, but it seems to be a slippy way, and I don’t want to turn the task to something dirty and unreadable for such an edge cas

Typically, an UPDATE [...] with a "ON DUPLICATE KEY <just update status>" clause is what I’d need, but I wasn’t surprise to see is doesn’t exist.

My worker is written in PHP, and uses PDO

Any idea ?