freshman2017
Goto Top

MySQL - Daten aus Temp- ind Main-Tabelle (neue einfügen, alte löschen)

Moin moin,

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!

Content-ID: 3092271039

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

Ausgedruckt am: 21.11.2024 um 21:11 Uhr

Pjordorf
Pjordorf 16.06.2022 um 18:58:26 Uhr
Goto Top
Hallo,

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 face-smile

https://dev.mysql.com/doc/refman/8.0/en/replace.html

Gruß,
Peter
freshman2017
freshman2017 16.06.2022 um 19:34:35 Uhr
Goto Top
Ich habe einen Schreibfehler entdeckt, direkt korrigiert.

Frage also eigentlich, am Ende sollen nur die Daten aus der Temp Tabelle in der Main Tabelle stehen.

Zitat von @Pjordorf:

Hallo,

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 face-smile

https://dev.mysql.com/doc/refman/8.0/en/replace.html

Gruß,
Peter
akretschmer
akretschmer 16.06.2022 um 20:12:36 Uhr
Goto Top
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.
freshman2017
freshman2017 16.06.2022 um 21:56:58 Uhr
Goto Top
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;
akretschmer
akretschmer 17.06.2022 um 08:50:46 Uhr
Goto Top
Zitat von @freshman2017:

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.
freshman2017
freshman2017 17.06.2022 um 11:45:06 Uhr
Goto Top
Würde es auch andersrum funktionieren, erst neue einfügen und die alten die nicht in der Temp Tabelle stehen, löschen?
akretschmer
akretschmer 17.06.2022 um 12:11:54 Uhr
Goto Top
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?

verstehe nicht, was Du erreichen willst ...
freshman2017
freshman2017 17.06.2022 um 15:02:16 Uhr
Goto Top
Zitat von @akretschmer:

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?

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.
akretschmer
akretschmer 17.06.2022 um 15:20:16 Uhr
Goto Top
Zitat von @freshman2017:

Zitat von @akretschmer:

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?

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.
freshman2017
freshman2017 18.06.2022 um 21:30:23 Uhr
Goto Top
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

Zitat von @akretschmer:

Zitat von @freshman2017:

Zitat von @akretschmer:

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?

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.
Pjordorf
Pjordorf 19.06.2022 um 00:34:48 Uhr
Goto Top
Hallo,

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?

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
akretschmer
akretschmer 19.06.2022 um 08:55:49 Uhr
Goto Top
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.


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=# 
freshman2017
freshman2017 19.06.2022 um 16:23:52 Uhr
Goto Top
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?
akretschmer
akretschmer 19.06.2022 um 16:53:27 Uhr
Goto Top
Zitat von @freshman2017:

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.
MadMax
MadMax 20.06.2022 um 14:18:25 Uhr
Goto Top
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:
delete from Haupttabelle
insert into Haupttabelle ...
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