Wie kann ich aktualisieren, falls vorhanden, einfügen, wenn nicht (AKA „Upsert“ oder „merge“) in MySQL?
-
10-07-2019 - |
Frage
Gibt es eine einfache Möglichkeit, um eine Zeile INSERT
, wenn es nicht vorhanden ist, oder UPDATE
wenn es vorhanden ist, ein MySQL-Abfrage mit?
Lösung
Ja, INSERT ... ON DUPLICATE KEY UPDATE
. Zum Beispiel:
INSERT INTO `usage`
(`thing_id`, `times_used`, `first_time_used`)
VALUES
(4815162342, 1, NOW())
ON DUPLICATE KEY UPDATE
`times_used` = `times_used` + 1
Andere Tipps
Ich weiß, dass dies eine alte Frage, aber die Google mich führt hier vor kurzem so dass ich andere vorstellen, kommen auch hier.
@chaos ist richtig: dort die INSERT ... ON DUPLICATE KEY UPDATE
Syntax.
Allerdings bat die ursprüngliche Frage zu MySQL speziell und in MySQL gibt es die REPLACE INTO ...
Syntax. IMHO ist dieser Befehl leichter und einfacher für upserts zu verwenden. Aus dem Handbuch:
REPLACE funktioniert genau wie INSERT, mit der Ausnahme, dass, wenn eine alte Zeile in der Tabelle für einen Primärschlüssel oder einen eindeutigen Index den gleichen Wert wie eine neue Zeile hat, die alte Zeile gelöscht wird, bevor die neue Zeile eingefügt wird.
Hinweis: Dies ist nicht Standard-SQL ist. Ein Beispiel aus dem Handbuch:
CREATE TABLE test (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
data VARCHAR(64) DEFAULT NULL,
ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
mysql> REPLACE INTO test VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.04 sec)
mysql> REPLACE INTO test VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 2 rows affected (0.04 sec)
mysql> SELECT * FROM test;
+----+------+---------------------+
| id | data | ts |
+----+------+---------------------+
| 1 | New | 2014-08-20 18:47:42 |
+----+------+---------------------+
1 row in set (0.00 sec)
Edit: Nur eine faire Warnung, dass REPLACE INTO
nicht UPDATE
ist gefallen. Wie das Handbuch sagt, löscht REPLACE
die Zeile, wenn es vorhanden ist, dann eine neue einfügt. (Beachten Sie die lustigen „2 Zeilen betroffen“ im Beispiel oben.) Das heißt, es wird die Werte von ersetzen alle Spalten einer vorhandenen Datensatz (und nicht nur aktualisieren einige Spalten.) Das Verhalten von REPLACE INTO
MySQL ist ähnlich wie die SQLite der INSERT OR REPLACE INTO
. Siehe diese Frage für einige Abhilfen, wenn Sie nur ein paar Spalten aktualisiert werden soll ( und nicht alle Spalten), wenn der Datensatz bereits vorhanden ist.