insert update on duplicate key

alexfrenzel92

SQL-Guru
Beiträge
122
Guten Morgen!

Mit
Code:
INSERT INTO TabelleX (Spalte1, Spalte2, ...) VALUES (1, 2, ...)UPDATE ON DUPLICATE KEY Spalte1 = 1
schaffe ich es, eine vorhandene Zeile mit dem Wert 1 in Spalte 1 mit diesen Werten upzudaten oder (falls es keine Zeile gibt, in der Spalte1 = 1) eine neue einzufügen

Ich bin gerade auf der Suche nach einem Code, der eine Zeile (in eine Tabelle mit 5 Spalten) dann einfügt, wenn es noch keine Zeile gibt, in der Spalte1 = 1 UND Spalte2 = 2

Spalte1 und Spalte2 verstehen sich als Alias

Das müsste doch ein einfaches sein oder?
 
Werbung:
mit PostgreSQL:

Code:
test=# create table alexf (s1 int, s2 int, s3 int, s4 int, s5 int, primary key(s1, s2));
CREATE TABLE
test=*# insert into alexf values (1,2,3,4,5) on conflict (s1,s2) do update set s3=excluded.s3, s4=excluded.s4, s5=excluded.s5 where (alexf.s1,alexf.s2)=(excluded.s1,excluded.s2);
INSERT 0 1
test=*# select * from alexf;
 s1 | s2 | s3 | s4 | s5
----+----+----+----+----
  1 |  2 |  3 |  4 |  5
(1 Zeile)

test=*# insert into alexf values (1,2,13,14,15) on conflict (s1,s2) do update set s3=excluded.s3, s4=excluded.s4, s5=excluded.s5 where (alexf.s1,alexf.s2)=(excluded.s1,excluded.s2);
INSERT 0 1
test=*# select * from alexf;
 s1 | s2 | s3 | s4 | s5
----+----+----+----+----
  1 |  2 | 13 | 14 | 15
(1 Zeile)

test=*#

Ich weiß nicht, ob MySQL das kann. Und auch nicht wie.
 
Da gibts sicherlich einige Wege, hier mal zwei Ideen:
Code:
IF NOT EXISTS ( SELECT 1 FROM TabelleX WHERE spalte1 = 1 AND spalte2 = 2 ) BEGIN INSERT INTO TabelleX(spalte1,spalte2) VALUES(1,2) END;
Code:
INSERT INTO TabelleX(spalte1,spalte2) SELECT 1 AS spalt1,2 AS spalte2 EXCEPT SELECT spalte1,spalte2 FROM TabelleX
 
Da gibts sicherlich einige Wege, hier mal zwei Ideen:
Code:
IF NOT EXISTS ( SELECT 1 FROM TabelleX WHERE spalte1 = 1 AND spalte2 = 2 ) BEGIN INSERT INTO TabelleX(spalte1,spalte2) VALUES(1,2) END;
Code:
INSERT INTO TabelleX(spalte1,spalte2) SELECT 1 AS spalt1,2 AS spalte2 EXCEPT SELECT spalte1,spalte2 FROM TabelleX
Eine Variante mit Duplicate key update gibt es nicht?
Spontan hätte ich gedacht, das geht irgendwie bis ich gemerkt habe, dass ich nur weiß, wie mein Code funktioniert als dass ich auch wüsste, wie.
Was macht duplicate key genau? Einfügen, es sei denn, der erste Wert (in dem Fall 1 in Spalte 1) ist schon so platziert, dann wir er überschrieben?
Oder wie funktioniert duplicate key?

danke für die beiden ansätze dennoch
 
Mir ist nicht ganz klar was du erreichen willst aber grundsätzlich kannst du das auch mit einem schlikchten IF ELSE nachbauen.

Unterschätze den Aufwand nicht, es richtig zu machen. Solch ein "Upsert" konnte PG lange Zeit nicht, es gab diverse Versuche, es via stored procs zu machen, aber es wirklich 'sicher' zu machen in Hinsicht auf z.B. multiple Inserts und in Umgebungen mit vielen gleichzeitigen Zugriffen ist nicht trivial.
 
Mir ist nicht ganz klar was du erreichen willst aber grundsätzlich kannst du das auch mit einem schlikchten IF ELSE nachbauen.

Das ist eine Art und Weise zu programmieren. Wenn man Prozeduren auf möglichst wenig, möglichst kurzreichende Schritte reduziert, desto besser kann das Gehirn das verarbeiten, speichern, weiterarbeiten, optimieren, perfektionieren. Schon klar, dass man es immer noch "einfach auswendig lernen kann" aber es gibt immer ein noch besseres Programm, je optimierter man es gestaltet. Das ist das Ziel und deswegen frage ich hier nach, ob es so und so geht.
Jetzt könnte man darüber diskutieren oder herausfinden, ob ein IF ELSE nicht sogar noch kurzschrittiger ist als eine DUPLICATE KEY Abfrage, aber das ist individuell, weil ich mich mit IF ELSE in SQL (ich denke, du meinst in sql) weniger gut kenne und dennoch duplicate key bisher die in der hinsicht bessere lösung finde
 
Mir ist nicht ganz klar was du erreichen willst aber grundsätzlich kannst du das auch mit einem schlikchten IF ELSE nachbauen.
Wo wir gerade beim Thema sind.
Durch den Link, den du mir netterweise bereitgestellt hast (den ich nicht kannte) habe ich erkannt, dass DUPLICATE KEY ein "if exist update else insert" nicht drauf hat.
Code:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF EXISTS[...]
diese fehlermeldung bekomme ich bei folgendem code
Code:
IF EXISTS (
SELECT *
FROM TabelleX
WHERE Spalte1=1
AND Spalte2 =2
)
UPDATE TabelleX SET Spalte1 = 1 AND Spalte2 = 2, ... WHERE Spalte1=1 AND Spalte2 =2 ELSE INSERT INTO TabelleX(Spalte1, Spalte2, ...)
SELECT 1 , 2, ...
 
Da fehlt mindestens ein BEGIN, besser ist aber, grade im Zusammenspiel mit ELSE eine saubere Struktur.
Code:
IF NOT EXISTS [...]
BEGIN
INSERT [...]
END
ELSE
BEGIN
UPDATE [...]
END
Natürlich verstehe ich den Wunsch das möglichst elegant und performant zu lösen. Da bin ich jetzt vermutlich auch nicht so sehr drinn da MySQL. Bei MSSQL scheint es auch kein ON DUPLICATE KEY zu geben sondern Lösungen mit MERGE - nicht das ich sowas hier bisher gebraucht hätte :)
 
Code:
IF NOT EXISTS (SELECT * FROM TabelleX WHERE Spalte1= 1 AND Spalte2= 2)
BEGIN
INSERT INTO TabelleX (Spalte1, Spalte2) SELECT 1, 2
END
ELSE
BEGIN
UPDATE TabelleX SET Spalte1= 1 AND Spalte2= 2 WHERE Spalte1= 1 AND Spalte2= 2
END

MySqli sagt:
Code:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF NOT EXISTS [...] BEGI' at line 1
 
Werbung:
Code:
SELECT CASE WHEN (SELECT Spalte1 FROM TabelleX WHERE Spalte1 = 1 AND Spalte2 = 2) IS NOT NULL THEN 'Zeile vorhanden' ELSE 'Zeile nicht vorhanden' END AS a
Code:
<?php if ($row[0] == 'Zeile vorhanden') { ...[update]... } else { ...[insert]... } ?>

So läuft das mit Mysqli(i) und Php. mysqli hatte ich leider nicht erwähnt
 
Zurück
Oben