Sqlite Insert into in mehrere Tabellen

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Phoenixx593
User
Beiträge: 4
Registriert: Freitag 24. Februar 2017, 09:07

Hallo zusammen,
ich versuche eine Zeile über mehrere Tabellen einzufügen. Leider klappt es nicht. Kann mir hierbei jemand helfen?

Nehmen wir mal folgendes an:

table1:

id -> Wird vergeben
obj_id -> Primary Key
Name -> Wird vergeben

table2:
obj_id -> FR Key
Hobby -> Wird vergeben

Ich habe folgendes für Mysql gefunden:

Code: Alles auswählen

INSERT INTO table1 (id, name)
  VALUES('5', 'Hans');
INSERT INTO table2 (obj_id, Hobby) 
  VALUES(LAST_INSERT_ID(), 'Coden');
Achtung: Bitte beachtet das die Spalte "id" und der Sin dahinter in meinem wirklichen code eine wichtige Rolle spielt.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was heisst denn "geht nicht"?
Phoenixx593
User
Beiträge: 4
Registriert: Freitag 24. Februar 2017, 09:07

__deets__ hat geschrieben: Sonntag 3. April 2022, 17:10 Was heisst denn "geht nicht"?
Weil es ein Mysql befehel ist. Ich suche auch eher was mit "Join" syntax.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das macht es leider überhaupt nicht klarer. Und inserts kann es per Definition nicht mit Joins geben - denn ein join spannt mehrer Tabellen zusammen, aber einfügen kann man nur in eine.

Solange du also nicht etwas weiter ausholst, wird man dir nicht helfen können.
bfm
User
Beiträge: 88
Registriert: Donnerstag 14. März 2013, 09:42

so?

INSERT INTO table1 (id, name)
VALUES('5', 'Hans');
INSERT INTO table2 (id, Hobby)
VALUES('5', 'Coden');
Sirius3
User
Beiträge: 18051
Registriert: Sonntag 21. Oktober 2012, 17:20

@bmf: IDs sind immer Zahlen. Primäre IDs haben alle Tabellen, die gibt man aber nicht explizit an.
Da wir hier in einem Python-Forum sind, so sieht das dann in Python aus:

Code: Alles auswählen

from contextlib import closing
import sqlite3

connection = sqlite3.Connection('test.db')

with closing(connection.cursor()) as cursor:
    cursor.execute('CREATE TABLE person (id INTEGER PRIMARY KEY, name TEXT)')
    cursor.execute('CREATE TABLE hobby (id INTEGER PRIMARY KEY, person_id INTEGER, hobby TEXT)')


name = "Hans"
hobby = "Coden"
with closing(connection.cursor()) as cursor:
    cursor.execute('INSERT INTO person (name) VALUES (?)', [name])
    cursor.execute('INSERT INTO hobby (person_id, hobby) VALUES (?, ?)', [cursor.lastrowid, hobby])
    connection.commit()
Normalerweise würde es eine eigene Tabelle mit den Hobbys geben, und eine weitere Tabelle, die die Personen mit den Hobbys miteinander verknüpft.
Benutzeravatar
sparrow
User
Beiträge: 4361
Registriert: Freitag 17. April 2009, 10:28

Ergänzend: Lies dich mal in das Thema "Normalisierung von Datenbanken" ein.
bfm
User
Beiträge: 88
Registriert: Donnerstag 14. März 2013, 09:42

Sirius3 hat geschrieben: Freitag 15. April 2022, 07:59 @bmf: IDs sind immer Zahlen. Primäre IDs haben alle Tabellen, die gibt man aber nicht explizit an.
In der Datenbanktabelle muss ich nicht zwingend immer einen automatischen Primary-Key bilden lassen. Vielleicht will ich hier ja meinen eigenen Pirmary-Key verwenden und der ist z. B. 5-stellig und ist nicht vorlaufend und ist nicht rein numerisch und setzt sich vielleicht auch mehreren Spalten zusammen. z. B. Kundennummer, Personalnummer, Auftragsnummer...... was geschickter ist, kommt immer auf die Daten und den Anwendungsfall drauf an.
Sirius3
User
Beiträge: 18051
Registriert: Sonntag 21. Oktober 2012, 17:20

Auch in Deinem Fall ist es besser einen automatischen Primary-Key zu haben. Kundennumnern, Personalnummern oder ähnliches werden gerne mal geändert.
bfm
User
Beiträge: 88
Registriert: Donnerstag 14. März 2013, 09:42

Sirius3 hat geschrieben: Samstag 16. April 2022, 10:03 Auch in Deinem Fall ist es besser einen automatischen Primary-Key zu haben. Kundennumnern, Personalnummern oder ähnliches werden gerne mal geändert.
und dann auch gleichzeitig in zig "Untertabellen" ändern? Wenn eine Personalnummer mal abgerechnet ist, dann ist sie abgerechnet. Zu dem Zeitpunkt sind dann schon etliche Meldungen an das Finanzamt und Krankenkassen raus. Ich glaube, da will man die Personalnummer nicht mehr ändern. Höchstens vielleicht stilllegen. Außerdem schon mal was von GOB gehört? Grundsätze ordnungsgemäßer Buchführung. Es wird nichts Falsche gelöscht, sondern Falsches wird storniert.

Es kommt immer auf den Anwendungsfall, ob es Sinn macht oder nicht. Eine Personalnummer oder Kundennummer wird nur einmal vergeben.
Benutzeravatar
sparrow
User
Beiträge: 4361
Registriert: Freitag 17. April 2009, 10:28

@bfm: Man muss das in keiner Untertabelle ändern, weil die Information nur in einer einzigen Tabelle steht. Denn die Datenbank muss natürlich normalisiert sein

In der Praxis macht man das eigentlich immer so, dass die ID ein automatisches Integer Feld (oder vergleichbares) ist und die Fälle, die du hier nennst als Constraints auf der Relation angelegt werden. Es stellt sich einfach zu oft heraus, dass sich an Geschäftslogiken etwas ändert, und dann ist das Ändern von Constraints deutlich einfacher.
Ich sehe keine Nachteile aber weiß aus eigener Erfahrung, dass es viele Vorteile hat.

Das hat auch nicht mit irgendwelchen Buchhsltungsdingen zu tun. Wir reden hier von relationalen Datenbanken. Dass etwas nicht geändert werden kann, bildet man auf andere Weise ab.
Benutzeravatar
__blackjack__
User
Beiträge: 13533
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@bfm: Das geht solange gut bis sich halt doch mal was ändert an Dingen die sich nie ändern. Postleizahlen beispielsweise sind 4-stellig und werden immer 4-stellig bleiben. Ups. Ich habe selbst mehrere Datenbanken gesehen bei denen sich dieser Primärschlüssel dann halt doch mal geändert hat. Vielleicht gibt es ja irgendwann ein europäisches Finanzamt und Personalnummern werden durch eine Länderkennung ergänzt. Oder halb Europa muss sich mit dem russischen Finanzamt auseinandersetzen, weil die militärische Auseinandersetzung nicht geklappt hat.

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Man muss bedenken dass so ein primary key häufig gleich mehrfach in Indizes vorkommt und häufig Vergleiche (durch joins) darauf passieren. Um daher größtmögliche Performance zu haben und wenige Platz unnötig zu beanspruchen ist es fast immer eine schlechte Idee einen natural key als primary key zu benutzen.

Dazu kommt das Problem, wie schon erwähnt, dass sich primary keys nur sehr schwer ändern lassen. Effektiv macht man so aus einer two-way door decision eine one-way door decision. Normalerweise möchte man eigentlich genau dass Gegenteil erreichen, schliesslich ist niemand perfekt und du weißt nie genau wie die Zukunft aussieht. Was z.B. wenn zwei Unternehmen mergen, schon hast du möglicherweise Konflikte bei Personal-, Kundennummern usw. Einmal vergeben ist also gar nicht so leicht, es sei den du nutzt UUIDs.

Ganz besonders heikel ist auch Sicherheit/Privatsphäre bei sowas. Primary keys tauchen üblicherweise an vielen Stellen auf wie z.B. URLs, die man nicht so absichert wie die Inhalte auf die verwiesen wird. Man sollte sich gut überlegen welche Informationen man da bereit ist zu leaken, wobei da natürlich auch ein einfacher aufsteigender primary key schon problematisch sein kann.
Antworten