Zum Inhalt springen
aviral gupta

// B1.2 · ca. 30 Min. · Einstieg

Tabellen anlegen: Datentypen, Namen und DROP TABLE

Nach dieser Lektion wählen Sie für jede Spalte einen passenden Typ, löschen eine Tabelle und legen sie ohne Fehler neu an und erkennen an der ERROR-Zeile, welcher Wert nicht passte.

Lektion 2 von 4 in B1 Erste Schritte

Danach können Sie

  • Für jede Spalte einen Typ wählen: integer, bigint, numeric(p,s), text, varchar(n), boolean oder date
  • Tabellen gut benennen und mit IF EXISTS und IF NOT EXISTS anlegen, löschen und neu anlegen
  • Die Fehler eines Typs lesen: value too long, numeric field overflow, date out of range, integer out of range
  1. Aufwärmen · Aufgabe 1 von 7

    Aufwärmen: Eine Spalte hält die Zahl der Exemplare eines Buchs: 1, 2, 3 … Welcher Typ passt am besten?

  2. Vorhersagen · Aufgabe 2 von 7

    Sagen Sie es voraus, bevor Sie weiterlesen: Die Spalte erlaubt zwei Nachkommastellen. Was liefert das SELECT?

    CREATE TABLE prices (amount numeric(5,2));
    INSERT INTO prices VALUES (12.345);
    SELECT amount FROM prices;
  3. Üben · Aufgabe 3 von 7

    Ergänzen Sie den Typ, damit die Spalte active nur true oder false aufnimmt.

    CREATE TABLE members (id integer, active ____);
    CREATE TABLE members (id integer, active );
  4. Üben · Aufgabe 4 von 7

    Ordnen Sie jeder Spalte den passenden Typ zu.

  5. Üben · Aufgabe 5 von 7

    Bringen Sie die Anweisungen in die Reihenfolge eines Skripts, das jedes Mal ohne Fehler läuft, auch wenn books schon existiert.

    1. 1.INSERT INTO books VALUES (1, 'Dune');
    2. 2.SELECT * FROM books;
    3. 3.DROP TABLE IF EXISTS books;
    4. 4.CREATE TABLE books (id integer, title text);
  6. Denksport · Aufgabe 6 von 7

    Knobelaufgabe. books existiert mit zwei Spalten. Welche Meldung folgt auf ERROR:, wenn dies läuft, oder gibt es keine?

    CREATE TABLE books (id integer, title text);
    CREATE TABLE IF NOT EXISTS books (id integer, title text, year integer);
    INSERT INTO books (id, title, year) VALUES (1, 'Dune', 1965);
  7. Anwenden · Aufgabe 7 von 7

    Mini-Aufgabe. Entwerfen Sie eine Tabelle members für eine Bibliothek: eine id, einen Namen mit höchstens 40 Zeichen, eine E-Mail-Adresse, den Tag des Beitritts und ob die Mitgliedschaft aktiv ist. Beginnen Sie das Skript mit DROP TABLE IF EXISTS, fügen Sie zwei Mitglieder mit Adressen unter example.com ein und listen Sie sie nach id sortiert auf. Versuchen Sie dann, ein Datum wie 2026-02-30 einzufügen, und lesen Sie den Fehler.

    Prüfen Sie Ihr Ergebnis anhand dieser Liste

Selbst programmieren

Lesen Sie das ausgearbeitete Beispiel und lösen Sie dann die Übungen. Ihr Code läuft in Ihrem Browser oder auf Ihrem Computer und wird nie hochgeladen.

Ausgearbeitetes Beispiel

Eine Tabelle mit fünf Typen

Das Skript löscht books, falls es existiert, legt die Tabelle mit fünf verschiedenen Typen an und fügt drei Bücher ein. Achten Sie darauf, wie jeder Wert zurückkommt: Die Preise erhalten zwei Nachkommastellen, 7.999 wird gerundet, und der Text 'no' wird als false gespeichert. Ändern Sie dann 12.5 in 123456.5 und führen Sie es erneut aus, um numeric field overflow zu sehen. Auf Ihrem Computer führen Sie es mit psql -X -q -v ON_ERROR_STOP=1 -f main.sql aus; beim ersten Mal gibt psql zusätzlich eine NOTICE aus, weil es noch kein books zum Löschen gibt.

main.sql

-- Start clean: remove books if an earlier run left it behind.
DROP TABLE IF EXISTS books;

CREATE TABLE books (
  id integer,
  title varchar(80),
  price numeric(6,2),
  added date,
  on_loan boolean
);

INSERT INTO books VALUES (1, 'Dune', 12.5, '2026-09-01', true);
INSERT INTO books VALUES (2, 'Emma', 7.999, '2026-09-15', false);
INSERT INTO books VALUES (3, 'Kindred', 9, '2026-09-30', 'no');

SELECT * FROM books ORDER BY id;

Ausführen mit

psql -X -q -v ON_ERROR_STOP=1 -f main.sql

Ausgabe

 id |  title  | price |   added    | on_loan
----+---------+-------+------------+---------
  1 | Dune    | 12.50 | 2026-09-01 | t
  2 | Emma    |  8.00 | 2026-09-15 | f
  3 | Kindred |  9.00 | 2026-09-30 | f
(3 rows)
  • numeric(6,2) zeigt immer zwei Nachkommastellen: Aus 12.5 wird 12.50, aus 9 wird 9.00.
  • 7.999 hat drei Nachkommastellen und wird daher ohne Fehler auf 8.00 gerundet.
  • Boolesche Werte erscheinen als t und f; der Text 'no' wurde als false angenommen.
  • Daten kommen in der Form 2026-09-01 zurück, der Form, in der Sie sie auch schreiben sollten.
  • DROP TABLE IF EXISTS gibt keine Zeilen aus; auf einer leeren Datenbank gibt es nur einen Hinweis aus.
Ändern und ausführen

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser PostgreSQL herunter (bis zu 10.1 MB) und speichert es im Cache. Jeder Lauf beginnt mit einer leeren Datenbank. Ihr Code bleibt auf Ihrem Gerät.

Übungen

Übung 1 von 2

Jeder Spalte einen passenden Typ geben

Der Starter legt books mit lauter text-Spalten an, PostgreSQL prüft also nichts. Ändern Sie die Typen: id integer, title varchar(80), price numeric(6,2), added date, on_loan boolean. Lassen Sie die INSERT- und SELECT-Anweisungen, wie sie sind. Beim Ausführen kommen die Preise dann als 12.50 und 8.00 zurück, on_loan als t und f.

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser PostgreSQL herunter (bis zu 10.1 MB) und speichert es im Cache. Jeder Lauf beginnt mit einer leeren Datenbank. Ihr Code bleibt auf Ihrem Gerät.

Hinweise
  1. Hinweis 1

    Nur die Anweisung CREATE TABLE ändert sich: Ersetzen Sie jedes text durch den Typ aus der Aufgabe.

  2. Hinweis 2

    numeric nimmt zwei Zahlen in Klammern: alle Stellen, dann die Stellen nach dem Punkt.

  3. Hinweis 3

    CREATE TABLE books (id integer, title varchar(80), price numeric(6,2), added date, on_loan boolean);

Eine Lösung zeigen

Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.

CREATE TABLE books (
  id integer,
  title varchar(80),
  price numeric(6,2),
  added date,
  on_loan boolean
);

INSERT INTO books VALUES (1, 'Dune', 12.5, '2026-09-01', true);
INSERT INTO books VALUES (2, 'Emma', 8, '2026-09-15', false);

SELECT * FROM books ORDER BY id;
Auf dem eigenen Computer ausführen

Installieren Sie PostgreSQL 18 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.

main.sql

-- Every column is text. Give each one a type that fits.
CREATE TABLE books (
  id text,
  title text,
  price text,
  added text,
  on_loan text
);

INSERT INTO books VALUES (1, 'Dune', 12.5, '2026-09-01', true);
INSERT INTO books VALUES (2, 'Emma', 8, '2026-09-15', false);

SELECT * FROM books ORDER BY id;

test.sql

-- test: id ist eine integer-Spalte
SELECT format_type(atttypid, atttypmod) = 'integer' FROM pg_attribute WHERE attrelid = 'books'::regclass AND attname = 'id';

-- test: title ist varchar(80)
SELECT format_type(atttypid, atttypmod) = 'character varying(80)' FROM pg_attribute WHERE attrelid = 'books'::regclass AND attname = 'title';

-- test: price ist numeric(6,2)
SELECT format_type(atttypid, atttypmod) = 'numeric(6,2)' FROM pg_attribute WHERE attrelid = 'books'::regclass AND attname = 'price';

-- test: added ist eine date-Spalte
SELECT format_type(atttypid, atttypmod) = 'date' FROM pg_attribute WHERE attrelid = 'books'::regclass AND attname = 'added';

-- test: on_loan ist eine boolean-Spalte
SELECT format_type(atttypid, atttypmod) = 'boolean' FROM pg_attribute WHERE attrelid = 'books'::regclass AND attname = 'on_loan';

-- test: Das Skript listet beide Bücher mit typisierten Werten auf
-- output:
--  id | title | price |   added    | on_loan
-- ----+-------+-------+------------+---------
--   1 | Dune  | 12.50 | 2026-09-01 | t
--   2 | Emma  |  8.00 | 2026-09-15 | f
-- (2 rows)

psql führt die Dateien auf Ihrem eigenen PostgreSQL-Server aus. Nehmen Sie eine leere Datenbank, die Sie wegwerfen können: Hängen Sie -d und ihren Namen an den Befehl an.

Programm ausführen:

psql -X -q -v ON_ERROR_STOP=1 -f main.sql

Für die Prüfungen gibt es auf Ihrem Computer noch keinen Befehl. Sie stehen in test.sql: Jede Prüfabfrage gibt t aus, wenn sie besteht.

Übung 2 von 2

Eine Tabelle neu aufbauen

setup.sql hat eine alte Tabelle members mit nur id und name angelegt. Ersetzen Sie sie: Löschen Sie sie mit DROP TABLE IF EXISTS, damit das Skript auch dort läuft, wo es kein members gibt, und legen Sie members (id integer, name varchar(40), city text, joined date) an. Fügen Sie 1, Ada, Berlin, 2025-01-15; 2, Grace, Munich, 2025-03-02; 3, Linus, Berlin, 2026-02-10 ein. Das SELECT listet dann alle drei auf.

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser PostgreSQL herunter (bis zu 10.1 MB) und speichert es im Cache. Jeder Lauf beginnt mit einer leeren Datenbank. Ihr Code bleibt auf Ihrem Gerät.

Hinweise
  1. Hinweis 1

    CREATE TABLE members … allein scheitert: relation "members" already exists. Löschen Sie zuerst die alte Tabelle.

  2. Hinweis 2

    DROP TABLE IF EXISTS members; entfernt die alte Tabelle samt ihrer Zeile, Ada eingeschlossen.

  3. Hinweis 3

    Legen Sie dann die neue Tabelle an und fügen Sie Ada erneut ein: INSERT INTO members VALUES (1, 'Ada', 'Berlin', '2025-01-15');

Eine Lösung zeigen

Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.

DROP TABLE IF EXISTS members;

CREATE TABLE members (
  id integer,
  name varchar(40),
  city text,
  joined date
);

INSERT INTO members VALUES (1, 'Ada', 'Berlin', '2025-01-15');
INSERT INTO members VALUES (2, 'Grace', 'Munich', '2025-03-02');
INSERT INTO members VALUES (3, 'Linus', 'Berlin', '2026-02-10');

SELECT * FROM members ORDER BY id;
Auf dem eigenen Computer ausführen

Installieren Sie PostgreSQL 18 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.

main.sql

-- setup.sql has created an old members table (id, name) with Ada in it.
-- Replace it with the new table, then add the three members.

SELECT * FROM members ORDER BY id;

test.sql

-- test: members hat die vier Spalten id, name, city und joined
SELECT count(*) = 4 FROM pg_attribute WHERE attrelid = 'members'::regclass AND attnum > 0 AND NOT attisdropped;

-- test: joined ist eine date-Spalte
SELECT format_type(atttypid, atttypmod) = 'date' FROM pg_attribute WHERE attrelid = 'members'::regclass AND attname = 'joined';

-- test: Die Tabelle enthält genau drei Mitglieder
SELECT count(*) = 3 FROM members;

-- test: Ada steht einmal in der Tabelle, jetzt mit ihrer Stadt
SELECT (SELECT count(*) FROM members WHERE name = 'Ada') = 1
   AND EXISTS (SELECT 1 FROM members WHERE id = 1 AND city = 'Berlin');

-- test: Das Skript listet die drei Mitglieder auf
-- output:
--  id | name  |  city  |   joined
-- ----+-------+--------+------------
--   1 | Ada   | Berlin | 2025-01-15
--   2 | Grace | Munich | 2025-03-02
--   3 | Linus | Berlin | 2026-02-10
-- (3 rows)

setup.sql

CREATE TABLE members (
  id integer,
  name text
);

INSERT INTO members VALUES (1, 'Ada');

psql führt die Dateien auf Ihrem eigenen PostgreSQL-Server aus. Nehmen Sie eine leere Datenbank, die Sie wegwerfen können: Hängen Sie -d und ihren Namen an den Befehl an.

Programm ausführen:

psql -X -q -v ON_ERROR_STOP=1 -f setup.sql -f main.sql

Für die Prüfungen gibt es auf Ihrem Computer noch keinen Befehl. Sie stehen in test.sql: Jede Prüfabfrage gibt t aus, wenn sie besteht.

Häufige Fehler

Eine Tabelle anlegen, die schon existiert

CREATE TABLE books (
  id integer,
  title text,
  year integer
);

Was psql ausgibt

ERROR:  relation "books" already exists

Warum, und die Lösung

setup.sql (oder ein früherer Lauf auf Ihrer eigenen Datenbank) hat books schon angelegt, und CREATE TABLE ersetzt nie eine Tabelle. Um neu zu beginnen, stellen Sie DROP TABLE IF EXISTS books; davor; das löscht auch die Zeilen. CREATE TABLE IF NOT EXISTS würde den Fehler verbergen, behielte aber die alte Tabelle mit ihren alten Spalten.

Eine Zeichenkette länger als varchar(n)

CREATE TABLE members (id integer, country varchar(2));
INSERT INTO members VALUES (1, 'DEU');

Was psql ausgibt

ERROR:  value too long for type character varying(2)

Warum, und die Lösung

varchar(2) hält höchstens zwei Zeichen, und 'DEU' hat drei. PostgreSQL kürzt den Wert nicht, sondern weist die Zeile zurück. Speichern Sie den Wert, für den die Spalte gedacht ist ('DE'), oder passen Sie die Grenze an die Daten an: varchar(3), oder text, wenn es keine natürliche Grenze gibt.

Eine Zahl zu groß für numeric(p,s)

CREATE TABLE books (title text, price numeric(4,2));
INSERT INTO books VALUES ('Atlas', 120.00);

Was psql ausgibt

ERROR:  numeric field overflow

Warum, und die Lösung

numeric(4,2) hat vier Stellen insgesamt, zwei davon nach dem Punkt; vor dem Punkt bleiben also nur zwei: Der größte Wert ist 99.99. 120.00 braucht drei. Wählen Sie eine Genauigkeit mit Platz für den größten erwarteten Wert, etwa numeric(6,2) für Preise bis 9999.99.

PostgreSQL im Browser: PGlite 0.5.8 (PostgreSQL 18.3), Apache-2.0 und PostgreSQL License. Lizenz und Quellcode

Abschlussquiz

5 Fragen, ohne Hinweise. Ab 80 % ist die Lektion abgeschlossen.

Erledigen Sie zuerst alle Aufgaben oben, um das Abschlussquiz freizuschalten.

Problem melden

Etwas ist falsch oder unklar? Beschreiben Sie es kurz, dann wird es geprüft und korrigiert.

#

Mindestens 20 Zeichen.

Nur, wenn Sie eine Antwort wünschen.

Kernideen

Ein Typ für jede Spalte

Jede Spalte hat genau einen Datentyp, und PostgreSQL prüft jeden Wert daran. integer speichert ganze Zahlen von -2147483648 bis +2147483647 und ist die übliche Wahl; bigint ist für größere, etwa 8100000000. numeric(p,s) rechnet exakt: p Stellen insgesamt, s davon nach dem Punkt. numeric(6,2) fasst also Preise bis 9999.99 und speichert 7.999 als 8.00. text speichert Zeichenketten beliebiger Länge; varchar(n) höchstens n Zeichen und ist nicht schneller als text. boolean speichert true oder false und gibt t oder f aus. date speichert einen Kalendertag, am besten geschrieben als '2026-09-30'. Eine Spalte ohne Wert ist NULL: leer, unbekannt.

Namen und das Leben einer Tabelle

Ein Name beginnt mit einem Buchstaben oder einem Unterstrich, danach folgen Buchstaben, Ziffern oder Unterstriche. Üblich sind Kleinbuchstaben mit Unterstrichen, etwa book_loans. Schlüsselwörter wie order oder user taugen nur in doppelten Anführungszeichen als Tabellenname, und das vermeiden Sie besser. CREATE TABLE scheitert, wenn die Tabelle schon existiert: relation "books" already exists. DROP TABLE books entfernt die Tabelle samt allen Zeilen. DROP TABLE IF EXISTS books tut dasselbe oder gibt nur einen Hinweis (NOTICE) aus, wenn es keine solche Tabelle gibt. Ein Skript, das erst löscht und dann anlegt, läuft so beliebig oft. CREATE TABLE IF NOT EXISTS überspringt die Anweisung, wenn der Name vergeben ist, selbst wenn jene Tabelle andere Spalten hat.

Der Typ als Wächter

Ein Typ weist einen Wert zurück, der nicht passt, und die ERROR-Zeile nennt das Problem. 'DEU' in einer Spalte varchar(2) ergibt value too long for type character varying(2): PostgreSQL kürzt den Wert nicht. 120.00 in numeric(4,2) ergibt numeric field overflow, weil vor dem Punkt nur zwei Stellen Platz haben. '2026-02-30' ergibt date/time field value out of range: Der Februar hat keinen 30. Tag. 3000000000 in einer integer-Spalte ergibt integer out of range. Zu viele Nachkommastellen sind die Ausnahme: numeric(p,s) rundet sie auf s Stellen, und eine integer-Spalte speichert 2.5 als 3, beides ohne Fehler. Wählen Sie jeden Typ also für die Werte, die Sie erwarten.

Quellen

Zuletzt geprüft am 30. September 2026