sql >> Database >  >> RDS >> Mysql

Invoegen als rij niet bestaat (UPSERT) in MySQL

  • Gebruik INSERT IGNORE
  • Gebruik REPLACE
  • Gebruik INSERT ... ON DUPLICATE KEY UPDATE

MySQL biedt een aantal handige instructies wanneer het nodig is om INSERT rijen na bepalen of die rij in feite nieuw is of al bestaat.

Hieronder zullen we de drie verschillende methoden onderzoeken en de voor- en nadelen van elk uitleggen, zodat u goed begrijpt hoe u uw eigen verklaringen kunt configureren bij het verstrekken van nieuwe of mogelijk bestaande gegevens voor INSERTION .

INSERT IGNORE gebruiken

Met behulp van INSERT IGNORE zorgt er effectief voor dat MySQL negert uitvoeringsfouten tijdens het uitvoeren van INSERT verklaringen. Dit betekent dat een INSERT IGNORE instructie die een dubbele waarde bevat in een UNIQUE index of PRIMARY KEY veld niet een fout produceren, maar in plaats daarvan gewoon die specifieke INSERT . negeren geheel te bevelen. Het voor de hand liggende doel is om een ​​groot aantal INSERT . uit te voeren verklaringen voor een combinatie van gegevens die zowel al in de database bestaan ​​als nieuwe gegevens die in het systeem komen.

Bijvoorbeeld onze books tabel kan al een paar records bevatten:

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)

Als we een grote hoeveelheid nieuwe en bestaande gegevens moeten INSERT en een deel van die gegevens bevat een overeenkomende waarde voor de id veld (dat is een UNIQUE PRIMARY_KEY in de tabel), met behulp van een eenvoudige INSERT zal een verwachte fout produceren:

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'

Aan de andere kant, als we INSERT IGNORE . gebruiken , de duplicatiepoging wordt genegeerd en er treden geen resulterende fouten op:

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)

Met REPLACE

In het geval dat u daadwerkelijk wilt vervangen rijen waar INSERT commando's zouden fouten produceren vanwege dubbele UNIQUE of PRIMARY KEY waarden zoals hierboven beschreven, is een optie om te kiezen voor de REPLACE verklaring.

Bij het uitgeven van een REPLACE statement, zijn er twee mogelijke uitkomsten voor elk gegeven commando:

  • Er is geen bestaande gegevensrij gevonden met overeenkomende waarden en dus een standaard INSERT instructie wordt uitgevoerd.
  • Een overeenkomende gegevensrij is gevonden, waardoor die bestaande rij wordt verwijderd met de standaard DELETE statement, dan een normale INSERT wordt daarna uitgevoerd.

We kunnen bijvoorbeeld REPLACE . gebruiken om ons bestaande record van id = 1 uit te wisselen van Op zoek naar verloren tijd door Marcel Proust met Green Eggs and Ham door 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)

Merk op dat hoewel we slechts één rij hebben gewijzigd, het resultaat aangeeft dat twee rijen werden beïnvloed omdat we eigenlijk DELETED de bestaande rij en vervolgens INSERTED de nieuwe rij om deze te vervangen.

Meer informatie over het gebruik van REPLACE kan worden gevonden in de officiële documentatie.

Gebruik INSERT ... ON DUPLICATE KEY UPDATE

De alternatieve (en algemeen geprefereerde) methode voor INSERTING in rijen die dubbele UNIQUE . kunnen bevatten of PRIMARY KEY waarden is om de INSERT ... ON DUPLICATE KEY UPDATE . te gebruiken verklaring en clausule.

In tegenstelling tot REPLACE – een inherent destructief commando vanwege de DELETE commando's die het uitvoert wanneer nodig - met behulp van INSERT ... ON DUPLICATE KEY UPDATE is niet-destructief , in die zin dat het alleen INSERT . zal uitgeven of UPDATE instructies, maar nooit DELETE .

We hebben bijvoorbeeld besloten dat we onze id = 1 . willen vervangen record van Green Eggs and Ham en zet het terug naar de originele In Search of Lost Time in plaats daarvan opnemen. We kunnen daarom onze originele INSERT statement en voeg de nieuwe toe ON DUPLICATE KEY UPDATE clausule:

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;

Merk op dat we normale UPDATE . gebruiken syntaxis (maar met uitzondering van de onnodige table naam en SET trefwoord), en alleen de non-UNIQUE waarden. Ook, hoewel niet nodig voor de ON DUPLICATE KEY UPDATE methode om correct te functioneren, hebben we er ook voor gekozen om user variables te gebruiken dus we hoeven niet de werkelijke waarden op te geven die we willen INSERT of UPDATE meer dan eens.

Als resultaat is onze id = 1 record was correct UPDATED zoals verwacht:

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)

Meer informatie is te vinden in de officiële documentatie.


  1. SSIS Excel-import forceren van onjuist kolomtype

  2. Updates van het Microsoft Access-team (juni 2017)

  3. Formaat van formulierbesturing wijzigen in Access 2016

  4. Importeer CSV-bestand rechtstreeks in MySQL