MySQL - Daten aus Temp- ind Main-Tabelle (neue einfügen, alte löschen)
Moin moin,
mit dem Befehl
füge ich Daten aus einer Temp-Tabelle in eine Main-Tabelle ein, da in der Main-Tabelle bereits Daten vorhanden sind (neue Daten werden eingefügt, alte aktualisiert)
Jetzt suche ich nach einer Möglichkeit Daten aus einer Temp-Tabelle in eine Main-Tabelle einzufügen, indem neue eingefügt und alte gelöscht werden.
Gibt es da was?
Mit den besten Grüßen!
mit dem Befehl
REPLACE INTO
füge ich Daten aus einer Temp-Tabelle in eine Main-Tabelle ein, da in der Main-Tabelle bereits Daten vorhanden sind (neue Daten werden eingefügt, alte aktualisiert)
Jetzt suche ich nach einer Möglichkeit Daten aus einer Temp-Tabelle in eine Main-Tabelle einzufügen, indem neue eingefügt und alte gelöscht werden.
Gibt es da was?
Mit den besten Grüßen!
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 3092271039
Url: https://administrator.de/contentid/3092271039
Ausgedruckt am: 21.11.2024 um 21:11 Uhr
15 Kommentare
Neuester Kommentar
Hallo,
https://dev.mysql.com/doc/refman/8.0/en/replace.html
Gruß,
Peter
Zitat von @freshman2017:
Jetzt suche ich nach einer Möglichkeit Daten aus einer Temp-Tabelle in eine Main-Tabelle einzufügen, indem neue eingefügt und alle gelöscht werden.
und alle gelöscht? Und wenn in der Temp-Tabelle keine Daten sind? In der Version die zum 03.03.3333 erscheinen soll, soll es machbar sein. Getestet an der Weltbevölkerung am 02.02.2222. Vorher ca. 18 Mrd, nach lauf des Scripts 0 (so geht Wachstum). So wie von dir gefordert Jetzt suche ich nach einer Möglichkeit Daten aus einer Temp-Tabelle in eine Main-Tabelle einzufügen, indem neue eingefügt und alle gelöscht werden.
https://dev.mysql.com/doc/refman/8.0/en/replace.html
Gruß,
Peter
Deiner Bescheibung nach suchst sowas wie hier:
[code]
postgres=# create table meine_temp_table(id int generated always as identity primary key, data int);
CREATE TABLE
postgres=# insert into meine_temp_table (data) select * from generate_series(1,10) x;
INSERT 0 10
postgres=# select * from meine_temp_table;
id | data
+------
1 | 1
2 | 2
3 | 3
4 | 4
5 | 5
6 | 6
7 | 7
8 | 8
9 | 9
10 | 10
(10 rows)
postgres=# create table meine_ziel_tabelle (i int);
CREATE TABLE
[/code]
Damit haben wir erst einmal Quell- und Zieltablle. Nun denn, frisch ans Werk mit einem eleganten Einzeiler:
[code]
postgres=# with del as (delete from meine_temp_table returning data) insert into meine_ziel_tabelle select * from del;
INSERT 0 10
[/code]
Und die Kontrolle:
[code]
postgres=# select * from meine_temp_table;
id | data
+------
(0 rows)
postgres=# select * from meine_ziel_tabelle ;
i
1
2
3
4
5
6
7
8
9
10
(10 rows)
postgres=#
[/code]
Das ganze ist so auch transaktionssicher, also auch in einem Multi-User-Umfeld sauber machbar.
[code]
postgres=# create table meine_temp_table(id int generated always as identity primary key, data int);
CREATE TABLE
postgres=# insert into meine_temp_table (data) select * from generate_series(1,10) x;
INSERT 0 10
postgres=# select * from meine_temp_table;
id | data
+------
1 | 1
2 | 2
3 | 3
4 | 4
5 | 5
6 | 6
7 | 7
8 | 8
9 | 9
10 | 10
(10 rows)
postgres=# create table meine_ziel_tabelle (i int);
CREATE TABLE
[/code]
Damit haben wir erst einmal Quell- und Zieltablle. Nun denn, frisch ans Werk mit einem eleganten Einzeiler:
[code]
postgres=# with del as (delete from meine_temp_table returning data) insert into meine_ziel_tabelle select * from del;
INSERT 0 10
[/code]
Und die Kontrolle:
[code]
postgres=# select * from meine_temp_table;
id | data
+------
(0 rows)
postgres=# select * from meine_ziel_tabelle ;
i
1
2
3
4
5
6
7
8
9
10
(10 rows)
postgres=#
[/code]
Das ganze ist so auch transaktionssicher, also auch in einem Multi-User-Umfeld sauber machbar.
Zitat von @freshman2017:
Werden hier dann erst die alten Daten gelöscht und dann die neuen hinzugefügt:
Werden hier dann erst die alten Daten gelöscht und dann die neuen hinzugefügt:
with del as (delete from meine_temp_table returning data) insert into meine_ziel_tabelle select * from del;
Ja. Gelöscht und in der Zieltabelle eingefügt. In einem Statement, atomar.
Zitat von @freshman2017:
Würde es auch andersrum funktionieren, erst neue einfügen und die alten die nicht in der Temp Tabelle stehen, löschen?
Würde es auch andersrum funktionieren, erst neue einfügen und die alten die nicht in der Temp Tabelle stehen, löschen?
verstehe nicht, was Du erreichen willst ...
Zitat von @freshman2017:
Ich habe Daten in einer Temp Tabelle, die ich zuerst in die Main Tabelle schreiben möchte und die Daten die vorher in der Main Tabelle standen, sollen nicht mehr zur Verfügung stehen. Also alle Daten in der Main sollen mit denen aus der Temp Tabelle überschrieben werden.
Zitat von @akretschmer:
verstehe nicht, was Du erreichen willst ...
Zitat von @freshman2017:
Würde es auch andersrum funktionieren, erst neue einfügen und die alten die nicht in der Temp Tabelle stehen, löschen?
Würde es auch andersrum funktionieren, erst neue einfügen und die alten die nicht in der Temp Tabelle stehen, löschen?
verstehe nicht, was Du erreichen willst ...
Ich habe Daten in einer Temp Tabelle, die ich zuerst in die Main Tabelle schreiben möchte und die Daten die vorher in der Main Tabelle standen, sollen nicht mehr zur Verfügung stehen. Also alle Daten in der Main sollen mit denen aus der Temp Tabelle überschrieben werden.
Ja, dann vorher ein DELETE.
Hallo,
Gruß,
Peter
Zitat von @freshman2017:
Wenn ich das DELETE vorher ausführe und dann die Daten aus der Temp in die Mai schreibe, wäre die Datenbank ja kurzfristig leer.
Was ist Kurzfristig? Und warum ist es tragisch wenn für ca. 500 ms die Datenbank leer ist?Wenn ich das DELETE vorher ausführe und dann die Daten aus der Temp in die Mai schreibe, wäre die Datenbank ja kurzfristig leer.
Daher dachte ich, dass das DELETE zum Schluss kommen könnte
Was ist einfacher und schneller? Alles löschen oder Datensatzweise erst ermitteln ob gelöscht werden kann, dann diesen Datensatz löschen, auf zum nächsten. Wenn du nen Auto willst und das Ford Modell T (bj. 1920) dir nicht reicht (weil du ja nichts gefordert oder gesagt hast)...Gruß,
Peter
Zitat von @freshman2017:
Wenn ich das DELETE vorher ausführe und dann die Daten aus der Temp in die Mai schreibe, wäre die Datenbank ja kurzfristig leer.
Wenn ich das DELETE vorher ausführe und dann die Daten aus der Temp in die Mai schreibe, wäre die Datenbank ja kurzfristig leer.
Transaktionen wurden schon erfunden. Was auch in dem Zusammenhang sich anböte: MERGE
postgres=# \h merge
Command: MERGE
Description: conditionally insert, update, or delete rows of a table
Syntax:
[ WITH with_query [, ...] ]
MERGE INTO target_table_name [ [ AS ] target_alias ]
USING data_source ON join_condition
when_clause [...]
where data_source is
{ source_table_name | ( source_query ) } [ [ AS ] source_alias ]
and when_clause is
{ WHEN MATCHED [ AND condition ] THEN { merge_update | merge_delete | DO NOTHING } |
WHEN NOT MATCHED [ AND condition ] THEN { merge_insert | DO NOTHING } }
and merge_insert is
INSERT [( column_name [, ...] )]
[ OVERRIDING { SYSTEM | USER } VALUE ]
{ VALUES ( { expression | DEFAULT } [, ...] ) | DEFAULT VALUES }
and merge_update is
UPDATE SET { column_name = { expression | DEFAULT } |
( column_name [, ...] ) = ( { expression | DEFAULT } [, ...] ) } [, ...]
and merge_delete is
DELETE
URL: https://www.postgresql.org/docs/15/sql-merge.html
postgres=#
Zitat von @freshman2017:
Ich hatte schon folgendes überlegt, weiß aber nicht, ob es Sinn macht:
Erfahrungen?
Ich hatte schon folgendes überlegt, weiß aber nicht, ob es Sinn macht:
DELETE FROM main WHERE id NOT IN(SELECT DISTINCT id FROM temp)
Erfahrungen?
Zuerst wolltest Du, Zitat: "Jetzt suche ich nach einer Möglichkeit Daten aus einer Temp-Tabelle in eine Main-Tabelle einzufügen, indem neue eingefügt und alte gelöscht werden."
Alles nebulös, so wirklich versteht wohl keiner, was Dein Problem eigentlich ist.
Moin Freshman,
alles mit einem Befehl, wie es akretschmer mit PostgreSQL macht, bekommst Du wohl mit MySQL nicht hin. Also brauchst Du zwei Befehle und setzt eine Transaktion drumrum, dann kann es Dir auch egal sein, ob die Tabelle kurzzeitig leer ist. Solange Deine Transaktion läuft, haben die anderen eh Pause.
Wenn Du ohnehin die Temp-Tabelle 1:1 in die Haupttabelle bringen willst, kannst Du problemlos erst die komplette Tabelle löschen und dann die Temp-Tabelle reinkopieren, also einfach:
Probleme kann es aber natürlich geben, wenn Du Fremdschlüssel auf Deiner Haupttabelle hast, weil die Daten, die auf Deine Haupttabelle verweisen, dann entweder gelöscht werden oder meckern, je nach dem, wie sie angelegt sind. Aber dieses Problem hast Du auch, wenn Du den replace-Befehl von MySQL verwendest. der macht nämlich auch erst ein delete und dann ein insert. Wenn eine Tabelle aber so, durch einen Import, aktualisiert wird, dann sind da hoffentlich keine Fremdschlüssel drauf.
Wenn Du aber Fremdschlüssel hast, dann solltest Du besser insert ... on duplicate key update verwenden, der macht nämlich wirklich ein update, wenn der Datensatz schon da ist.
Ob Du dann das delete vor oder nach dem replace bzw. insert ... on duplicate key update ausführst, ist Jacke wie Hose. Allerdings würde ich nicht "where id not in (...)" verwenden, sondern "where not exists (...)". Bei SQL Server ist das schneller, ich weiß nicht, wie das MySQL handhabt.
Gruß, Mad Max
alles mit einem Befehl, wie es akretschmer mit PostgreSQL macht, bekommst Du wohl mit MySQL nicht hin. Also brauchst Du zwei Befehle und setzt eine Transaktion drumrum, dann kann es Dir auch egal sein, ob die Tabelle kurzzeitig leer ist. Solange Deine Transaktion läuft, haben die anderen eh Pause.
Wenn Du ohnehin die Temp-Tabelle 1:1 in die Haupttabelle bringen willst, kannst Du problemlos erst die komplette Tabelle löschen und dann die Temp-Tabelle reinkopieren, also einfach:
delete from Haupttabelle
insert into Haupttabelle ...
Wenn Du aber Fremdschlüssel hast, dann solltest Du besser insert ... on duplicate key update verwenden, der macht nämlich wirklich ein update, wenn der Datensatz schon da ist.
Ob Du dann das delete vor oder nach dem replace bzw. insert ... on duplicate key update ausführst, ist Jacke wie Hose. Allerdings würde ich nicht "where id not in (...)" verwenden, sondern "where not exists (...)". Bei SQL Server ist das schneller, ich weiß nicht, wie das MySQL handhabt.
Gruß, Mad Max