Zum Inhalt
wannacode

Die Bäckerei, Etappe 2: die Daten

Kurz gesagt: Etappe 2 füllt die Tabellen der Bäckerei mit INSERT, RETURNING und INSERT … SELECT und schreibt die erste Bestellung in einer Transaktion.

Problem

Leere Tabellen

Die Tabellen aus Etappe 1 sind fertig und leer. Die Bäckerei hat drei Kategorien, acht Produkte, fünf Kunden und ihre ersten Bestellungen. In dieser Etappe schreibst du sie hinein, und jede Regel aus Etappe 1 bewacht die Daten.

Alle Felder beginnen mit der Datenbank, die du bisher gebaut hast: die fünf Tabellen und die Daten aus den früheren Schritten der Etappe.

Die Idee

Die erste Zeile

INSERT INTO Tabelle (Spalten) VALUES (Werte) schreibt eine Zeile. Die Spalte id steht nicht in der Liste: INTEGER PRIMARY KEY ohne Wert bekommt von selbst die nächste Nummer.

SQLleere Datenbank

Die Spalten in Klammern sind wichtig. INSERT INTO categories VALUES (1, 'Brot') funktioniert auch, hängt aber von der Reihenfolge der Spalten in der Tabelle ab und bricht mit der ersten neuen Spalte.

Probier es aus

Die drei Kategorien

Schreibe die drei Kategorien mit einem INSERT: Brot, Teilchen und Getränke, in dieser Reihenfolge (Brot ist 1, Teilchen 2, Getränke 3).

SQLleere Datenbank

Die Idee

Was die Datenbank geschrieben hat

Das Programm braucht oft die Nummer der neuen Zeile, zum Beispiel um „Das Produkt wurde mit der Nummer 1 hinzugefügt“ anzuzeigen. RETURNING gibt die Spalten der geschriebenen Zeile zurück:

SQLleere Datenbank

RETURNING gibt auch die Werte zurück, die die Datenbank selbst eingesetzt hat: Stünde stock nicht in der Liste, käme 0 aus DEFAULT. Die acht Produkte werden mit einem INSERT geschrieben:

SQLleere Datenbank
Genauer, für Neugierige

RETURNING gibt es in SQLite seit Version 3.35 und in PostgreSQL. MySQL hat es nicht: Dort holt man die Nummer mit LAST_INSERT_ID(), und in SQLite geht es auch mit last_insert_rowid().

Sieh es dir an

Die Regeln wachen

Die Regeln aus Etappe 1 arbeiten jetzt. Ein Produkt mit Preis 0:

SQLleere Datenbank

Ein Produkt in Kategorie 9, die es nicht gibt:

SQLleere Datenbank

Ein Produkt ohne Namen:

SQLleere Datenbank

Keines der drei kommt hinein. Der Fehler kommt von der Datenbank, also spielt es keine Rolle, wer die Zeile schickt: die Seite, ein Importskript aus Excel oder ein Kollege in der Konsole.

Probier es aus

Die Kunden

Schreibe die fünf Kunden mit einem INSERT (Spalten name, email, city): Ivan Kolev, ivan.kolev@example.com, Sofia; Ana Petrova, ana.petrova@example.com, Plovdiv; Boris Nikolov, boris.nikolov@example.com, Sofia; Desislava Marinova, desislava.marinova@example.com, Varna; Kalin Todorov, kalin.todorov@example.com, ohne Stadt.

SQLleere Datenbank
Genauer, für Neugierige

UNIQUE vergleicht den Text Buchstabe für Buchstabe: Ivan.Kolev@example.com und ivan.kolev@example.com sind für die Datenbank zwei verschiedene E-Mails. Darum macht das Programm die E-Mail vor dem Schreiben zu Kleinbuchstaben, oder die Tabelle hält UNIQUE auf lower(email) mit einem Index (CREATE UNIQUE INDEX … ON customers (lower(email))).

Sieh es dir an

Dieselbe E-Mail

SQLleere Datenbank

Ivan aus Plovdiv ist eine andere Person mit derselben E-Mail, und die Datenbank lässt ihn nicht hinein. Die Anmeldung auf der Seite zeigt genau diesen Fehler als „Diese E-Mail ist schon registriert“.

Die Idee

Die Bestellung und ihre Zeilen

Eine Bestellung ohne status bekommt 'new' aus DEFAULT:

SQLleere Datenbank

Eine echte Bestellung besteht aber aus zwei Arten von Zeilen: einer in orders und mehreren in order_items. Stürzt das Programm dazwischen ab, bleibt eine Bestellung ohne ein einziges Produkt. Darum werden die beiden in einer Transaktion geschrieben: BEGIN, die Inserts, COMMIT. Bis zum COMMIT ist nichts endgültig.

Probier es aus

Die erste Bestellung

Ivan (Kunde 1) hat am 2026-10-01 zwei Landbrote (Produkt 1 zu 2,40) und drei Croissants (Produkt 4 zu 1,30) bestellt. Die Bestellung ist geliefert. Schreibe sie in einer Transaktion: die Bestellung (sie bekommt die Nummer 1) und ihre zwei Zeilen.

SQLleere Datenbank

Sieh es dir an

Abbrechen

Das Programm hat die Bestellung geschrieben und merkt, dass etwas nicht stimmt (die Karte wurde abgelehnt, eine Zeile brach mit einem Fehler ab). Dann schickt es statt COMMIT ein ROLLBACK:

SQLleere Datenbank

Während der Transaktion gibt es 2 Bestellungen, nach ROLLBACK wieder 1: Die zweite ist verschwunden, als hätte es das INSERT nie gegeben.

Genauer, für Neugierige

Hier hält jedes Feld beim ersten Fehler an, wie die Konsole. Das Programm macht dasselbe mit try: Bei einer Exception schickt es ROLLBACK. Die Transaktion wird nicht von selbst abgebrochen, wenn eine Abfrage fehlschlägt, also ist ROLLBACK Sache des Programms.

Sieh es dir an

Die anderen Bestellungen

Die Bestellungen 2 bis 6 werden genauso geschrieben. Hier sind sie, am Ende mit der Zahl der Bestellungen pro Status:

SQLleere Datenbank

Bestellung 4 ist storniert, 5 ist bezahlt und wartet auf die Lieferung, und 6 ist neu. Kalin (Kunde 5) hat noch nicht bestellt.

Übung

Der Preis aus dem Produkt

Die Seite kennt die Preise nicht auswendig. Wenn der Kunde kauft, wird der Preis in diesem Moment aus products geholt und in die Zeile geschrieben. INSERT … SELECT schreibt die Zeilen, die ein SELECT zurückgibt.

Kalin (Kunde 5) bestellt heute zwei Baguettes (Produkt 3). Schreibe die Bestellung (sie bekommt die Nummer 7, das Datum ist date('now')) und ihre Zeile, und hole unit_price mit INSERT … SELECT aus products.

SQLleere Datenbank

Die Idee

Die volle Datenbank

Die sechs Bestellungen sind in der Datenbank. Wie viele Zeilen jede Tabelle hat:

SQLleere Datenbank

Die nächste Etappe stellt Fragen an diese Daten: die Speisekarte, die Rechnung jeder Bestellung, wer was kauft.

Test

Teste dich

1. In INSERT INTO categories (name) VALUES (…) steht keine id. Woher kommt sie?
2. Die Bestellung ging hinein, und ihre Zeile brach mit einem Fehler ab. Was tut das Programm?
3. Warum wird der Preis der neuen Bestellzeile mit SELECT … FROM products geholt und nicht von Hand als 1,60 geschrieben?

Erstellt von Ivo Gergov im Rahmen der Kampagne von Evo Tech für zugängliche Programmierausbildung ·