freshman2017
Goto Top

MySQL - TempTabelle in MainTabelle übernehmen

Guten Tag liebe Gemeinde,

ich stehe "mal" wieder auf dem Schlauch. Ich würde gerne in MySQL Daten aus einer Temp Tabelle in eine Main Tabelle schreiben und zwar Updaten, wenn der Eintrag Anhand einer ID vorhanden ist und neu einfügen, wenn es diesen noch nicht gibt.

Aus MSSQL kenne ich es wie folgt:

MERGE test_3 t 

USING test_3_temp s ON 
	
	(
	s.ID = t.ID
	)
	
WHEN MATCHED THEN UPDATE SET 
    
	t.ID = s.ID,
	t.wert1 = s.wert1,
	t.wert2 = s.wert2
	
WHEN NOT MATCHED BY TARGET THEN INSERT 
	
	(
	ID, wert1, wert2
	)
    
VALUES
	
	(
	s.ID, s.wert1, s.wert2
	);


Wie stelle ich es am besten bei MySQL an?
Mit den besten Grüßen aus dem Süden!

Content-ID: 2893757414

Url: https://administrator.de/contentid/2893757414

Ausgedruckt am: 24.11.2024 um 14:11 Uhr

ukulele-7
ukulele-7 25.05.2022 um 15:02:36 Uhr
Goto Top
Wenn MySQL kein MERGE kann ganz klassisch, mit UPDATE oder INSERT. Dazu kannst du etwa wie folgt vorgehen:
UPDATE test_3
SET test_3.wert1 = s.wert1,
test_3.wert2 = s.wert2
FROM test_3
INNER JOIN test_3_temp s
ON test_3.ID = s.ID
WHERE test_3.wert1 != s.wert1
OR test_3.wert2 != s.wert2

INSERT INTO test_3
SELECT s.*
FROM test_3_temp s
LEFT JOIN test_3 t
ON s.ID = t.ID
WHERE t.ID IS NULL
In deinem MERGE macht übrigens ID im UPDATE Teil keinen Sinn, das kann ja nicht abweichend sein, darauf wird ja gejoint - nur der Vollständigkeit halber.

Unter MSSQL hatte ich auch kuriose Dinge mit MERGE gesehen daher verfahre ich eigentlich immer so. Zumal ich den UPDATE Teil auch für jeden Wert gesondert durchführen kann und dann auch nur dieser Wert angefasst wird. Kann bei aktiven Log-Triggern sinnvoll sein.
ukulele-7
ukulele-7 25.05.2022 um 15:05:28 Uhr
Goto Top
Ergänzend kann man auch noch andere Wege nutzen, beim INSERT könnte man auch mit EXCEPT arbeiten, aber auch das ist ja vielleicht nicht überall gegeben. Wichtig ist die Reihenfolge, erst UPDATE auf den Bestand und dann neue Datensätze. Wenn alles in einer Transaktion laufen muss dürfte das auch gehen, ist aber vielleicht gar nicht nötig.
sabines
sabines 25.05.2022 um 17:09:51 Uhr
Goto Top
Moin,

ich werfe mal insert on duplicate key update in den Raum
https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html

Grüße
LordGurke
LordGurke 26.05.2022 um 13:37:48 Uhr
Goto Top
Statt "INSERT INTO" kannst du auch "REPLACE INTO" benutzen - syntaktisch verhalten die sich identisch.
Wenn der Primärschlüssel vorhanden ist, wird MySQL dann den Eintrag akutalisieren.
freshman2017
freshman2017 26.05.2022 aktualisiert um 17:45:42 Uhr
Goto Top
Hallo,
wie würde denn der SQL Befehl dazu aussehen? Wenn die Daten aus der temp in die Main kopiert werden sollen?

Ich habe eine Tabelle test und eine Tabelle test_temp mit dem gleichen Aufbau. (Felder: adrnr,vname,nname). Der Primärschlüssel ist bei mir die „adrnr“.

Zitat von @LordGurke:

Statt "INSERT INTO" kannst du auch "REPLACE INTO" benutzen - syntaktisch verhalten die sich identisch.
Wenn der Primärschlüssel vorhanden ist, wird MySQL dann den Eintrag akutalisieren.
LordGurke
Lösung LordGurke 26.05.2022 um 18:00:32 Uhr
Goto Top
Das müsste dann (ungetestet) gehen mit:
REPLACE INTO `livetabelle` SELECT * FROM `temptabelle`

So würde es zumindest mit einem reinen INSERT gehen, aber REPLACE sollte sich identisch verhalten.
freshman2017
Lösung freshman2017 27.05.2022 um 10:06:03 Uhr
Goto Top
Das mit dem INSERT klappt wunderbar, beim Update bekomme ich noch eine Fehlermeldung, woran kann es liegen?

SQL-Befehl:

UPDATE customers
SET customers.name = s.name,
customers.lastname = s.lastname
FROM customers_tmp
INNER JOIN customers_tmp s
ON customers.adrnr = s.adrnr
WHERE customers.name != s.name
OR customers.lastname != s.lastname
MySQL meldet:Dokumentation

#1064 - Fehler in der SQL-Syntax. Bitte die korrekte Syntax im Handbuch nachschlagen bei 'FROM customers_tmp 
INNER JOIN customers_tmp s
ON customers.adrnr = s.adrnr
...' in Zeile 4  

Zitat von @ukulele-7:

Wenn MySQL kein MERGE kann ganz klassisch, mit UPDATE oder INSERT. Dazu kannst du etwa wie folgt vorgehen:
UPDATE test_3
SET test_3.wert1 = s.wert1,
test_3.wert2 = s.wert2
FROM test_3
INNER JOIN test_3_temp s
ON test_3.ID = s.ID
WHERE test_3.wert1 != s.wert1
OR test_3.wert2 != s.wert2

INSERT INTO test_3
SELECT s.*
FROM test_3_temp s
LEFT JOIN test_3 t
ON s.ID = t.ID
WHERE t.ID IS NULL
In deinem MERGE macht übrigens ID im UPDATE Teil keinen Sinn, das kann ja nicht abweichend sein, darauf wird ja gejoint - nur der Vollständigkeit halber.

Unter MSSQL hatte ich auch kuriose Dinge mit MERGE gesehen daher verfahre ich eigentlich immer so. Zumal ich den UPDATE Teil auch für jeden Wert gesondert durchführen kann und dann auch nur dieser Wert angefasst wird. Kann bei aktiven Log-Triggern sinnvoll sein.
ukulele-7
Lösung ukulele-7 27.05.2022 um 10:49:50 Uhr
Goto Top
Also wenn dann macht das hier keinen Sinn:
FROM customers_tmp
INNER JOIN customers_tmp s
sondern nur:
FROM customers
INNER JOIN customers_tmp s
UPDATE ... FROM mit JOIN ist eventuell auch nicht zulässig bei MySQL, da bin ich mir nicht sicher.