Dans certains cas de figure on peut souhaiter d’insérer un record et n’effectuer aucun changement si les informations sont déjà présentes.
Un exemple concret est l’entretien d’une table d’adresses email erronnées qui peut être utile lorsqu’un hébergeur a pour politique de bloquer les envois pour éviter le spam.
La requête suivante permet d’insérer une nouvelle adresse email et de tout simplement « ignorer » un DUPLICATE KEY error (le champ email ci-dessous est défini comme UNIQUE) en faisant un update de la clé primaire avec sa valeur actuelle.
INSERT INTO email_failures SET email="' . $db->escape( $email ) . '", date_failure= NOW() ON DUPLICATE KEY UPDATE id=id
L’avantage de cette approche est qu’elle évite d’utiliser l’option IGNORE qui peut masquer d’autres types d’erreurs.
– James Poulson.
Bonjour revlis,
Bonne question. Pour précision le mot clé IGNORE permute MySQL en mode non-stricte. Cela a pour effet d’ignorer les DUPLICATE KEY ERROR mais également d’autres types erreurs comme celles liées à de données non-valides en entrée. Pour reprendre l’exemple du lien ci-dessous, la date ‘2009-02-31′ produit un simple warning en mode non-stricte.
5.8.5. Overriding Input Data Restrictions
http://book.opensourceproject.org.cn/lamp/mysql/mysql5cert/opensource/0672328127/ch05lev1sec8.html
P.S: Il y a d’autres alternatives qu’on peut utiliser selon ses besoins comme un REPLACE (attention: remplace la clé primaire vu qu’il s’agit d’un DELETE et INSERT en interne) ou un branchement conditionnel.
IF NOT EXISTS (SELECT email FROM email_failures WHERE email = ‘user@domain.com’) THEN (INSERT (email, date) VALUES (‘user@domain.com’, NOW() ) INTO email_failures)
Et pourquoi pas utiliser INSERT IGNORE ? « INSERT IGNORE INTO email_failures SET email= »‘ . $db->escape( $email ) . ‘ », date_failure= NOW() » ?