Mysql
 sql >> Base de données >  >> RDS >> Mysql

Appel UPSERT standard SQL

La seule solution prise en charge par MySQL et HSQLDB consiste à interroger les lignes que vous avez l'intention de remplacer, et conditionnellement soit INSERT soit UPDATE. Cela signifie que vous devez écrire plus de code d'application pour compenser les différences entre les implémentations RDBMS.

  1. COMMENCER LA TRANSACTION.
  2. SÉLECTIONNER ... POUR LA MISE À JOUR.
  3. Si le SELECT trouve des lignes, alors UPDATE.
  4. Sinon, INSÉRER.
  5. ENGAGEZ-VOUS.

MySQL ne prend pas en charge l'instruction ANSI SQL MERGE. Il prend en charge REMPLACER et INSÉRER... SUR LA MISE À JOUR DE LA CLÉ EN DOUBLE. Voir ma réponse à " INSERT IGNORE" vs "INSERT ... ON DUPLICATE KEY UPDATE" pour en savoir plus.

Re commentaires :Oui, une autre approche consiste simplement à essayer l'INSERT et à voir si cela réussit. Sinon, faites une mise à jour. Si vous tentez l'INSERT et qu'il rencontre une clé en double, cela générera une erreur, qui se transformera en une exception dans certaines interfaces client. L'inconvénient de faire cela dans MySQL est qu'il génère un nouvel ID d'auto-incrémentation même si l'INSERT échoue. Donc, vous vous retrouvez avec des lacunes. Je sais que les écarts dans la séquence d'auto-incrémentation ne sont généralement pas préoccupants, mais j'ai aidé un client l'année dernière qui avait des écarts de 1000 à 1500 entre les insertions réussies à cause de cet effet, et le résultat a été qu'ils ont épuisé la gamme d'un INT dans leur clé primaire.

Comme le dit @baraky, on pourrait plutôt tenter d'abord la MISE À JOUR, et si cela n'affecte aucune ligne, alors faire l'INSERT à la place. Mon commentaire sur cette stratégie est que la mise à jour de zéro ligne n'est pas une exception - vous devrez vérifier le "nombre de lignes affectées" après la mise à jour pour savoir si elle "a réussi" ou non.

Mais interroger le nombre de lignes affectées vous ramène au problème initial :vous devez utiliser des requêtes différentes dans MySQL par rapport à HSQLDB.

HSQLDB :

CALL DIAGNOSTICS(ROW_COUNT);

MySQL :

SELECT ROW_COUNT();