Zum Inhalt
wannacode

ALTER TABLE: eine Tabelle ändern

Kurz gesagt: ALTER TABLE fügt einer bestehenden Tabelle Spalten hinzu, benennt sie um oder entfernt sie; SQLite kann nur das, für alles andere baut man eine neue Tabelle, und DROP TABLE entfernt die Tabelle ganz.

Problem

Der Kurier ruft an

Der Kurier kommt an, und der Kunde macht nicht auf. Der Kurier will eine Telefonnummer. In customers gibt es keine Spalte für eine Telefonnummer.

Die Tabelle lässt sich nicht noch einmal anlegen: Sie enthält 20 Kunden mit Bestellungen, Bewertungen und Anmeldedaten. Sie muss an Ort und Stelle geändert werden.

Die Idee

ADD COLUMN

ALTER TABLE ändert eine Tabelle, die schon existiert. ADD COLUMN fügt eine Spalte hinzu, geschrieben wie in CREATE TABLE:

SQLDatenbank: Shop

Die bestehenden Kunden haben NULL bekommen: Ihre Telefonnummern sind noch nicht bekannt. Die Daten in den anderen Spalten werden nicht angefasst.

Sieh es dir an

Eine Pflichtspalte in einer vollen Tabelle

Das Marketing will eine Spalte „hat der Kunde dem Newsletter zugestimmt“, und zwar als Pflichtspalte:

SQLDatenbank: Shop

Ein Fehler. Die Tabelle hat schon 20 Zeilen. Wenn die Spalte NOT NULL ist, was soll darin für sie stehen? SQLite weiß es nicht, also weigert es sich.

Mit DEFAULT weiß es:

SQLDatenbank: Shop

Alle bestehenden Kunden haben 0 bekommen: Sie haben nicht zugestimmt, bis sie etwas anderes sagen.

Genauer, für Neugierige

SQLite hat bei ADD COLUMN weitere Grenzen. Die neue Spalte darf nicht UNIQUE oder PRIMARY KEY sein. Hat sie REFERENCES und ist die Prüfung eingeschaltet, muss DEFAULT NULL sein. Ein CHECK auf die neue Spalte ist erlaubt: SQLite prüft ihn auch gegen die bestehenden Zeilen.

Probier es aus

Die Einheit

Produkte werden stückweise verkauft, aber bald werden manche nach Kilo verkauft. Füge products eine Spalte unit hinzu: Text, Pflicht, mit dem Standardwert 'Stk.'.

SQLDatenbank: Shop

Die Idee

RENAME COLUMN und DROP COLUMN

RENAME COLUMN ändert den Namen einer Spalte. Die Daten bleiben:

SQLDatenbank: Shop

SQLite ändert den Namen auch überall sonst im Schema, wo die Spalte erwähnt wird.

DROP COLUMN entfernt eine Spalte samt ihren Daten. Der Shop wird nie ein Fax schicken:

SQLDatenbank: Shop

DROP COLUMN gibt es in SQLite seit Version 3.35 (2021). Es kann keine Spalte entfernen, von der das Schema abhängt: einen Primärschlüssel, eine UNIQUE-Spalte oder eine Spalte, die ein Index oder eine View benutzt.

SQLDatenbank: Shop

Die Idee

Was SQLite nicht kann

Das Lager will, dass der Bestand nie negativ ist. Das ist CHECK (stock >= 0) auf einer Spalte, die es schon gibt:

SQLDatenbank: Shop

SQLite kann einer bestehenden Spalte keine Regel hinzufügen und auch ihren Typ nicht ändern. In SQLite kann ALTER TABLE nur Spalten hinzufügen, umbenennen und entfernen und die Tabelle umbenennen.

Für alles andere baust du eine neue Tabelle. So müssen Bewertungen einen Text haben:

SQLDatenbank: Shop

Vier Schritte: eine neue Tabelle mit der Regel, die Daten mit INSERT … SELECT kopieren, DROP TABLE für die alte und RENAME TO für die neue. Hätte eine Bewertung keinen Text gehabt, wäre das Kopieren an NOT NULL hängen geblieben. Dann korrigierst du erst die Daten.

Genauer, für Neugierige

PostgreSQL und MySQL können mehr: ALTER TABLE products ADD CONSTRAINT stock_ok CHECK (stock >= 0) und den Typ einer Spalte ändern. Für SQLite steht das ganze Vorgehen in der Dokumentation („ALTER TABLE“, der Abschnitt über Änderungen, die es nicht direkt unterstützt). Dort gibt es auch Schritte für die Fremdschlüssel, Indizes und Trigger der alten Tabelle. Die Bewertungen haben keine davon, deshalb reichen hier vier Schritte.

Die Idee

DROP TABLE

DROP TABLE entfernt die ganze Tabelle mit allen Daten. Es gibt kein Zurück. Die Aktion von 2025 ist längst vorbei:

SQLDatenbank: Shop

sqlite_schema ist die Liste der Tabellen von SQLite. promo_2025 ist weg. Die zweite Zeile gibt wegen IF EXISTS keinen Fehler. Ohne es bricht das Entfernen einer Tabelle, die es nicht gibt, ab:

SQLDatenbank: Shop

Eine Tabelle, auf die andere Tabellen zeigen, lässt sich so nicht entfernen. order_items und reviews zeigen auf products:

SQLDatenbank: Shop

DROP TABLE löscht zuerst alle Zeilen, und REFERENCES aus der vorigen Lektion erlaubt das nicht.

Übung

Zwei Änderungen

1. Die Kuriere wollen eine Telefonnummer und einen Lieferhinweis („Klingel 3, Eingang B“).

Füge customers die Spalten phone und delivery_note hinzu, beide Text.

SQLDatenbank: Shop

2. In reviews heißt das Datum created_at, und in products heißt es added_at. Was gleich ist, sollte gleich heißen.

Benenne added_at in products in created_at um.

SQLDatenbank: Shop

In einem echten Projekt wird das Schema nicht von Hand in einer Konsole geändert, sondern mit Migrationen: Dateien mit solchen ALTER TABLE-Anweisungen, die auf jedem Computer und Server in derselben Reihenfolge laufen. Du siehst sie im Modul über die Datenbank im Programm.

Test

Teste dich

1. Du fügst einer Tabelle mit 20 Kunden eine Spalte phone TEXT hinzu. Was steht bei den bestehenden Kunden darin?
2. Warum bricht ADD COLUMN newsletter INTEGER NOT NULL mit einem Fehler ab?
3. Wie fügst du in SQLite einer bestehenden Spalte ein CHECK hinzu?
4. Was macht DROP TABLE IF EXISTS promo_2025, wenn es die Tabelle nicht gibt?

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