PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : INSERT INTO über mehrere Tabellen



ashcr@ck
19.04.2017, 22:44
Moin,

ich möchte Eingaben einer Eingabemaske in einer DB speichern.
Kurzes Beispiel:
TabA -> ID, Name, und weitere Columns
TabB -> ID (primary key), ISBN, ID_A (Referenz auf ID in TabA)
TabC -> ID, Zusatzname

Ich möchte alle COlumns aus TabA füllen, aus TabB nur die ISBN und aus TabC nur den Zusatznamen.

Wie gehe ich da vor? Das LAden der Daten in die Maske mit Select funktioniert, aber insert und Update klappt nicht. Muss ich die Befehle mit Select kombinieren?

Jut4h.tm
19.04.2017, 22:56
Du machst einfach 3 inserts, das ist für den Anfang doch okay.
1. insert TabA
2. Last insert id auslesen
3. insert TabB
4. insert TabC

H4x0r007
20.04.2017, 10:39
Ich würde die verschiedenen Inserts auf jeden Fall in eine Transaktion packen, denn nach dem ersten Insert und vor den nachfolgenden ist die Datenbank in einem inkonsistenten Zustand. Man muss bei einer Datenbank immer damit rechnen, dass ein anderer Prozess gerade diese Daten lesen möchte.

Ich wusste bisher auch nicht, wie das in MySQL funktioniert, weil ich die Funktion LAST_INSERT_ID() (https://dev.mysql.com/doc/refman/5.7/en/information-functions.html) nicht kannte. Auf Stackoverflow habe ich allerdings dieses Snippet gefunden:


BEGIN;
INSERT INTO users (username, password)
VALUES('test', 'test');
INSERT INTO profiles (userid, bio, homepage)
VALUES(LAST_INSERT_ID(),'Hello world!', 'http://www.stackoverflow.com');
COMMIT;

BEGIN und COMMIT begrenzen die Transaktion und zwischendrin kannst du deine Inserts machen. Während der Transaktion kann kein anderer Nutzer der Datenbank auf die noch inkonststenten Daten zugreifen.

//edit: Du könntest vermutlich auch zuerst in einem Query die Transaktion beginnen und einen Insert ausführen, dir in PHP die insert_id merken und später die anderen Queries per PHP-Befehl absetzen. Denke nur an das COMMIT; am Ende

24ds
20.04.2017, 17:07
könntest du mal die Relationen aufzeigen?
So wie du es beschrieben hast, ist C nicht in Relation zu A oder B, B in relation zu A (und umgekehrt).

In dem Fall macht es gar keinen Sinn, einen Insert auf 3 Tabellen zu machen. Du kannst aber mit "returning" wenigstens auf 2 Statements runter.
Oder du baust dir eine stored procedure SP_ins_taba_b_c_(Name, weitere_columns, ISBN, Zusatzname), die im Kern das macht was H4x0r007 tut (nur nicht so hässlich :) )

ashcr@ck
20.04.2017, 17:51
Erest einmal danke für die bisherigen Lösungsvorschläge. Mit 3 Inserts habe ich es tatsächlich versucht, aber ohne Erfolg.

Zu den Relationen
TabB hat eine ID als Primary Key, und eine Relation zu TabA über eine ID.
TabA hat eine ID und eine ID_B. Über ID_B ist die Relation von Tab_B implementiert. Des Weiteren besitzt TabA eine ID_C.
TabC hat eine ID und einen Namen. Hier soll die Relation über die ID und ID_C aus TabA hergestellt werden. Ich hoffe es ist etwas verständlich.


Ursprünglich hatte ich gedacht, dass es mit einem oder zwei inserts kombiniert mit select getan ist. Scheinbar doch. :D

ashcr@ck
24.04.2017, 20:41
Ich habe mal die Tabellen aufgemalt und angehängt. Die eingekreisten IDs stehen auch in Relation zueinander.

https://anonimag.es/i/insert3f18d.jpg