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

Comment INSÉRER si la ligne n'existe pas (UPSERT) dans MySQL

  • Utilisation de INSERT IGNORE
  • Utilisation de REPLACE
  • Utilisation de INSERT ... ON DUPLICATE KEY UPDATE

MySQL fournit un certain nombre d'instructions utiles lorsqu'il est nécessaire de INSERT lignes après déterminer si cette ligne est, en fait, nouvelle ou existe déjà.

Ci-dessous, nous examinerons les trois méthodes différentes et expliquerons les avantages et les inconvénients de chacune afin que vous sachiez comment configurer vos propres déclarations lorsque vous fournissez des données nouvelles ou potentiellement existantes pour INSERTION .

Utilisation de INSERT IGNORE

Utilisation de INSERT IGNORE provoque effectivement l'ignorance de MySQL erreurs d'exécution lors de la tentative d'exécution de INSERT déclarations. Cela signifie qu'un INSERT IGNORE instruction qui contient une valeur en double dans un UNIQUE index ou PRIMARY KEY le champ ne le fait pas produira une erreur, mais ignorera simplement ce INSERT particulier commande entièrement. Le but évident est d'exécuter un grand nombre de INSERT déclarations pour une combinaison de données déjà existantes dans la base de données ainsi que de nouvelles données entrant dans le système.

Par exemple, nos books table peut déjà contenir quelques enregistrements :

mysql> SELECT * FROM books LIMIT 3;
+----+-------------------------+---------------------+----------------+
| id | title                   | author              | year_published |
+----+-------------------------+---------------------+----------------+
|  1 | In Search of Lost Time  | Marcel Proust       |           1913 |
|  2 | Ulysses                 | James Joyce         |           1922 |
|  3 | Don Quixote             | Miguel de Cervantes |           1605 |
+----+-------------------------+---------------------+----------------+
3 rows in set (0.00 sec)

Si nous avons un gros lot de données nouvelles et existantes à INSERT et une partie de ces données contient une valeur correspondante pour le id champ (qui est un UNIQUE PRIMARY_KEY dans le tableau), en utilisant un INSERT de base produira une erreur attendue :

mysql> INSERT INTO books
    (id, title, author, year_published)
VALUES
    (1, 'Green Eggs and Ham', 'Dr. Seuss', 1960);
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'

D'autre part, si nous utilisons INSERT IGNORE , la tentative de duplication est ignorée et aucune erreur résultante ne se produit :

mysql> INSERT IGNORE INTO books
    (id, title, author, year_published)
VALUES
    (1, 'Green Eggs and Ham', 'Dr. Seuss', 1960);
Query OK, 0 rows affected (0.00 sec)

Utilisation de REPLACE

Dans le cas où vous souhaiteriez effectivement remplacer lignes où INSERT les commandes produiraient des erreurs dues à la duplication de UNIQUE ou PRIMARY KEY valeurs comme indiqué ci-dessus, une option consiste à opter pour le REPLACE déclaration.

Lors de l'émission d'un REPLACE , il y a deux résultats possibles pour chaque commande émise :

  • Aucune ligne de données existante n'est trouvée avec des valeurs correspondantes et donc un INSERT standard instruction est exécutée.
  • Une ligne de données correspondante est trouvé, provoquant la suppression de cette ligne existante avec le standard DELETE instruction, puis un INSERT normal est effectué par la suite.

Par exemple, nous pouvons utiliser REPLACE pour échanger notre enregistrement existant de id = 1 de À la recherche du temps perdu de Marcel Proust avec Œufs verts et jambon par le Dr Seuss :

mysql> REPLACE INTO books
    (id, title, author, year_published)
VALUES
    (1, 'Green Eggs and Ham', 'Dr. Seuss', 1960);
Query OK, 2 rows affected (0.00 sec)

Notez que même si nous n'avons modifié qu'une seule ligne, le résultat indique que deux lignes ont été affectées car nous avons en fait DELETED la ligne existante puis INSERTED la nouvelle ligne pour la remplacer.

Plus d'informations sur l'utilisation de REPLACE peut être trouvé dans la documentation officielle.

Utilisation de INSERT ... ON DUPLICATE KEY UPDATE

La méthode alternative (et généralement préférée) pour INSERTING dans des lignes pouvant contenir des doublons UNIQUE ou PRIMARY KEY valeurs est d'utiliser le INSERT ... ON DUPLICATE KEY UPDATE déclaration et clause.

Contrairement à REPLACE – une commande intrinsèquement destructive due au DELETE commandes qu'il exécute si nécessaire - en utilisant INSERT ... ON DUPLICATE KEY UPDATE est non destructif , en ce sens qu'il n'émettra jamais que INSERT ou UPDATE instructions, mais jamais DELETE .

Par exemple, nous avons décidé de remplacer notre id = 1 record de Œufs verts et jambon et revenez à l'original À la recherche du temps perdu enregistrer à la place. Nous pouvons donc reprendre notre INSERT d'origine et ajoutez le nouveau ON DUPLICATE KEY UPDATE clause :

mysql> SET @id = 1,
    @title = 'In Search of Lost Time',
    @author = 'Marcel Proust',
    @year_published = 1913;
INSERT INTO books
    (id, title, author, year_published)
VALUES
    (@id, @title, @author, @year_published)
ON DUPLICATE KEY UPDATE
    title = @title,
    author = @author,
    year_published = @year_published;

Notez que nous utilisons la UPDATE normale syntaxe (mais en excluant l'inutile table nom et SET mot-clé), et en attribuant uniquement le non-UNIQUE valeurs. Aussi, bien qu'inutile pour la ON DUPLICATE KEY UPDATE pour fonctionner correctement, nous avons également choisi d'utiliser des user variables nous n'avons donc pas besoin de spécifier les valeurs réelles que nous voulons INSERT ou UPDATE plus d'une fois.

En conséquence, notre id = 1 l'enregistrement a été correctement UPDATED comme prévu :

mysql> SELECT * FROM books LIMIT 1;
+----+------------------------+---------------+----------------+
| id | title                  | author        | year_published |
+----+------------------------+---------------+----------------+
|  1 | In Search of Lost Time | Marcel Proust |           1913 |
+----+------------------------+---------------+----------------+
1 row in set (0.00 sec)

Plus d'informations peuvent être trouvées dans la documentation officielle.