Zum Inhalt springen
aviral gupta

// B4.1 · ca. 30 Min. · Einstieg

UPDATE und DELETE

Nach dieser Lektion ändern Sie genau die Zeilen, die Sie meinen, entfernen Zeilen, die nicht mehr gebraucht werden, und prüfen das Ergebnis, bevor Sie ihm trauen.

Lektion 1 von 5 in B4 Daten und Schema ändern

Anfang des Moduls

Danach können Sie

  • Gewählte Zeilen mit UPDATE … SET … WHERE ändern, mehrere Spalten zugleich und aus ihren alten Werten
  • Vorhersagen, welche Zeilen eine Änderung trifft: keine, einige oder alle, und warum = NULL nichts trifft
  • Zeilen mit DELETE … WHERE entfernen, eine Tabelle mit DELETE oder TRUNCATE leeren und aus einer anderen Tabelle ändern
  1. Aufwärmen · Aufgabe 1 von 7

    Aufwärmen: Linus bringt Dune zurück. Welche Anweisung hält das in loans fest, wo seine Ausleihe die id 4 hat?

  2. Vorhersagen · Aufgabe 2 von 7

    Sagen Sie es voraus, bevor Sie weiterlesen. Margaret will nach Hamburg ziehen, aber das WHERE wurde vergessen. Ada und Linus wohnen in Berlin, Grace in München (Munich), Margarets Stadt ist NULL. Wie viele Mitglieder wohnen danach in Hamburg?

    UPDATE members
    SET city = 'Hamburg';
  3. Üben · Aufgabe 3 von 7

    Neuromancer (id 6) hat 1 Exemplar. Ergänzen Sie die Lücke, damit die Bibliothek ein Exemplar mehr davon bekommt.

    UPDATE books
    SET copies = ____ + 1
    WHERE id = 6;
    UPDATE books SET copies = + 1 WHERE id = 6;
  4. Üben · Aufgabe 4 von 7

    Ordnen Sie jeder Anweisung zu, was sie mit der Tabelle loans macht.

  5. Üben · Aufgabe 5 von 7

    Bringen Sie die Zeilen dieser Änderung in die richtige Reihenfolge: Linus (id 3) zieht nach Hamburg und bekommt die E-Mail-Adresse linus@example.com.

    1. 1.WHERE id = 3;
    2. 2. email = 'linus@example.com'
    3. 3.SET city = 'Hamburg',
    4. 4.UPDATE members
  6. Denksport · Aufgabe 6 von 7

    Knobelaufgabe. Ada und Linus wohnen in Berlin, Grace in München (Munich), Margarets Stadt ist NULL. Wie viele Mitglieder wohnen danach in Hamburg?

    UPDATE members
    SET city = 'Hamburg'
    WHERE city <> 'Berlin';
  7. Anwenden · Aufgabe 7 von 7

    Mini-Aufgabe. Drei Änderungen am Schalter, je eine Anweisung: Grace gibt Neuromancer (Ausleihe 5) am 2026-10-03 zurück; Linus (id 3) bekommt die E-Mail-Adresse linus@example.com und zieht nach München (Munich); danach werden Graces zurückgegebene Ausleihen entfernt. Schreiben Sie vor jeder Anweisung auf, welche Zeilen sie treffen soll, und prüfen Sie danach mit einem SELECT.

    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

Ein Tag am Ausleihschalter

setup.sql lädt die Bibliothek aus Modul B1: Bücher, Mitglieder und Ausleihen. main.sql hält eine Rückgabe fest, fügt Exemplare hinzu, ändert zwei Spalten eines Mitglieds und entfernt die zurückgekommenen Ausleihen, mit einem SELECT nach jeder Änderung, das ihre Wirkung zeigt. Auf Ihrem Computer: psql -X -q -v ON_ERROR_STOP=1 -f setup.sql -f main.sql.

main.sql

-- 1. Linus brings Dune back (loan 4).
UPDATE loans
SET returned_on = '2026-10-01'
WHERE id = 4;

-- 2. One more copy of every sci-fi book.
UPDATE books
SET copies = copies + 1
WHERE genre = 'sci-fi';

SELECT id, title, copies
FROM books
ORDER BY id;

-- 3. Two columns at once: Margaret moves and changes her address.
UPDATE members
SET city = 'Hamburg', email = 'maggie@example.com'
WHERE id = 4;

SELECT id, name, email, city
FROM members
ORDER BY id;

-- 4. Remove the loans that have come back.
DELETE FROM loans
WHERE returned_on IS NOT NULL;

SELECT id, book_id, member_id, loaned_on
FROM loans
ORDER BY id;

setup.sql

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

INSERT INTO books VALUES
  (1, 'Dune', 'Frank Herbert', 1965, 'sci-fi', 2),
  (2, 'Emma', 'Jane Austen', 1815, 'classic', 1),
  (3, 'Kindred', 'Octavia E. Butler', 1979, 'sci-fi', 1),
  (4, 'Beloved', 'Toni Morrison', 1987, 'fiction', 1),
  (5, 'The Hobbit', 'J. R. R. Tolkien', 1937, 'fantasy', 3),
  (6, 'Neuromancer', 'William Gibson', 1984, 'sci-fi', 1);

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

INSERT INTO members VALUES
  (1, 'Ada', 'ada@example.com', 'Berlin', '2025-01-15'),
  (2, 'Grace', 'grace@example.com', 'Munich', '2025-03-02'),
  (3, 'Linus', NULL, 'Berlin', '2026-02-10'),
  (4, 'Margaret', 'margaret@example.com', NULL, '2026-05-20');

CREATE TABLE loans (
  id integer,
  book_id integer,
  member_id integer,
  loaned_on date,
  returned_on date
);

INSERT INTO loans VALUES
  (1, 1, 1, '2026-09-01', '2026-09-10'),
  (2, 3, 1, '2026-09-12', NULL),
  (3, 2, 2, '2026-09-05', '2026-09-20'),
  (4, 1, 3, '2026-09-15', NULL),
  (5, 6, 2, '2026-09-18', NULL);

Ausführen mit

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

Ausgabe

 id |    title    | copies
----+-------------+--------
  1 | Dune        |      3
  2 | Emma        |      1
  3 | Kindred     |      2
  4 | Beloved     |      1
  5 | The Hobbit  |      3
  6 | Neuromancer |      2
(6 rows)

 id |   name   |       email        |  city
----+----------+--------------------+---------
  1 | Ada      | ada@example.com    | Berlin
  2 | Grace    | grace@example.com  | Munich
  3 | Linus    |                    | Berlin
  4 | Margaret | maggie@example.com | Hamburg
(4 rows)

 id | book_id | member_id | loaned_on
----+---------+-----------+------------
  2 |       3 |         1 | 2026-09-12
  5 |       6 |         2 | 2026-09-18
(2 rows)
  • UPDATE und DELETE geben hier nichts aus, weil psql still läuft (-q); ohne -q druckte es Tags wie UPDATE 3.
  • copies = copies + 1 liest den alten Wert jedes sci-fi-Buchs: Dune geht von 2 auf 3, Kindred und Neuromancer von 1 auf 2. Die anderen Bücher behalten ihre.
  • Ein UPDATE ändert Margarets city und email, durch ein Komma getrennt; die NULL-E-Mail von Linus bleibt NULL, weil seine Zeile nicht zu WHERE id = 4 passt.
  • Schritt 1 hat Ausleihe 4 zurückgegeben, also entfernt Schritt 4 die Ausleihen 1, 3 und 4: Nur die zwei offenen bleiben.
Ä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

Drei Änderungen am Schalter

Schreiben Sie drei UPDATE-Anweisungen. Erstens zieht Margaret (id 4) nach Hamburg. Zweitens gibt Grace Neuromancer zurück: Ausleihe 5 bekommt das Rückgabedatum 2026-10-02. Drittens kauft die Bibliothek ein Exemplar mehr von jedem Buch, das vor 1950 erschienen ist. Ändern Sie sonst nichts.

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

    Jedes UPDATE braucht ein WHERE, das genau die gemeinten Zeilen wählt: id = 4 für Margaret, id = 5 für die Ausleihe.

  2. Hinweis 2

    Datum und Text stehen in einfachen Anführungszeichen: SET returned_on = '2026-10-02'.

  3. Hinweis 3

    Für die Bücher verwenden Sie den alten Wert: SET copies = copies + 1 WHERE year < 1950.

Eine Lösung zeigen

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

UPDATE members
SET city = 'Hamburg'
WHERE id = 4;

UPDATE loans
SET returned_on = '2026-10-02'
WHERE id = 5;

UPDATE books
SET copies = copies + 1
WHERE year < 1950;
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 loaded books, members and loans.
-- Write the three UPDATE statements here.
SELECT id, name, city FROM members ORDER BY id;

test.sql

-- test: Margaret wohnt in Hamburg, und die anderen Mitglieder behalten ihre Städte
SELECT string_agg(coalesce(city, '-'), ',' ORDER BY id) = 'Berlin,Munich,Berlin,Hamburg' FROM members;

-- test: Ausleihe 5 wurde am 2026-10-02 zurückgegeben
SELECT count(*) = 1 FROM loans WHERE id = 5 AND returned_on = '2026-10-02';

-- test: Die Ausleihen 2 und 4 sind weiter offen
SELECT string_agg(id::text, ',' ORDER BY id) = '2,4' FROM loans WHERE returned_on IS NULL;

-- test: Emma und The Hobbit haben ein Exemplar mehr, die anderen Bücher sind unverändert
SELECT string_agg(copies::text, ',' ORDER BY id) = '2,2,1,1,4,1' FROM books;

setup.sql

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

INSERT INTO books VALUES
  (1, 'Dune', 'Frank Herbert', 1965, 'sci-fi', 2),
  (2, 'Emma', 'Jane Austen', 1815, 'classic', 1),
  (3, 'Kindred', 'Octavia E. Butler', 1979, 'sci-fi', 1),
  (4, 'Beloved', 'Toni Morrison', 1987, 'fiction', 1),
  (5, 'The Hobbit', 'J. R. R. Tolkien', 1937, 'fantasy', 3),
  (6, 'Neuromancer', 'William Gibson', 1984, 'sci-fi', 1);

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

INSERT INTO members VALUES
  (1, 'Ada', 'ada@example.com', 'Berlin', '2025-01-15'),
  (2, 'Grace', 'grace@example.com', 'Munich', '2025-03-02'),
  (3, 'Linus', NULL, 'Berlin', '2026-02-10'),
  (4, 'Margaret', 'margaret@example.com', NULL, '2026-05-20');

CREATE TABLE loans (
  id integer,
  book_id integer,
  member_id integer,
  loaned_on date,
  returned_on date
);

INSERT INTO loans VALUES
  (1, 1, 1, '2026-09-01', '2026-09-10'),
  (2, 3, 1, '2026-09-12', NULL),
  (3, 2, 2, '2026-09-05', '2026-09-20'),
  (4, 1, 3, '2026-09-15', NULL),
  (5, 6, 2, '2026-09-18', NULL);

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.

Übung 2 von 2

Die Ausleihen aufräumen

Schreiben Sie drei Anweisungen, in dieser Reihenfolge. Erstens löschen Sie die zurückgegebenen Ausleihen. Zweitens nimmt die Bibliothek Beloved aus dem Bestand: Löschen Sie das Buch mit id 4. Drittens gibt Ada (Mitglied 1) alles zurück, was sie noch hat: Ihre offenen Ausleihen bekommen das Rückgabedatum 2026-10-03.

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

    Zurückgegebene Ausleihen haben ein Rückgabedatum: DELETE FROM loans WHERE returned_on IS NOT NULL.

  2. Hinweis 2

    Löschen Sie das Buch über seine id, damit kein anderes Buch passt: DELETE FROM books WHERE id = 4.

  3. Hinweis 3

    Adas offene Ausleihen: WHERE member_id = 1 AND returned_on IS NULL. Halten Sie die Reihenfolge ein: Liefe dieses UPDATE zuerst, entfernte das DELETE auch Ausleihe 2.

Eine Lösung zeigen

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

DELETE FROM loans
WHERE returned_on IS NOT NULL;

DELETE FROM books
WHERE id = 4;

UPDATE loans
SET returned_on = '2026-10-03'
WHERE member_id = 1 AND returned_on IS NULL;
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 loaded books, members and loans.
-- Write the three statements here.
SELECT id, member_id, returned_on FROM loans ORDER BY id;

test.sql

-- test: Nur die Ausleihen 2, 4 und 5 bleiben
SELECT string_agg(id::text, ',' ORDER BY id) = '2,4,5' FROM loans;

-- test: Beloved ist weg, und die anderen fünf Bücher sind noch da
SELECT string_agg(id::text, ',' ORDER BY id) = '1,2,3,5,6' FROM books;

-- test: Adas Ausleihe 2 wurde am 2026-10-03 zurückgegeben
SELECT count(*) = 1 FROM loans WHERE id = 2 AND returned_on = '2026-10-03';

-- test: Die Ausleihen 4 und 5 der anderen Mitglieder sind weiter offen
SELECT string_agg(id::text, ',' ORDER BY id) = '4,5' FROM loans WHERE returned_on IS NULL;

setup.sql

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

INSERT INTO books VALUES
  (1, 'Dune', 'Frank Herbert', 1965, 'sci-fi', 2),
  (2, 'Emma', 'Jane Austen', 1815, 'classic', 1),
  (3, 'Kindred', 'Octavia E. Butler', 1979, 'sci-fi', 1),
  (4, 'Beloved', 'Toni Morrison', 1987, 'fiction', 1),
  (5, 'The Hobbit', 'J. R. R. Tolkien', 1937, 'fantasy', 3),
  (6, 'Neuromancer', 'William Gibson', 1984, 'sci-fi', 1);

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

INSERT INTO members VALUES
  (1, 'Ada', 'ada@example.com', 'Berlin', '2025-01-15'),
  (2, 'Grace', 'grace@example.com', 'Munich', '2025-03-02'),
  (3, 'Linus', NULL, 'Berlin', '2026-02-10'),
  (4, 'Margaret', 'margaret@example.com', NULL, '2026-05-20');

CREATE TABLE loans (
  id integer,
  book_id integer,
  member_id integer,
  loaned_on date,
  returned_on date
);

INSERT INTO loans VALUES
  (1, 1, 1, '2026-09-01', '2026-09-10'),
  (2, 3, 1, '2026-09-12', NULL),
  (3, 2, 2, '2026-09-05', '2026-09-20'),
  (4, 1, 3, '2026-09-15', NULL),
  (5, 6, 2, '2026-09-18', NULL);

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

Ein Textwert ohne Anführungszeichen

UPDATE books
SET copies = copies + 1
WHERE title = Dune;

Was psql ausgibt

ERROR:  column "dune" does not exist

Warum, und die Lösung

Ohne Anführungszeichen wird Dune als Name gelesen, in Kleinbuchstaben umgewandelt und als Spalte gesucht. Text und Datum sind Werte in einfachen Anführungszeichen: WHERE title = 'Dune'. Dasselbe gilt in SET: SET city = 'Hamburg'.

AND zwischen zwei Zuweisungen

UPDATE books
SET copies = 2 AND year = 1966
WHERE id = 1;

Was psql ausgibt

ERROR:  argument of AND must be type boolean, not type integer

Warum, und die Lösung

In SET trennt AND keine Zuweisungen; es wird Teil des Werts, copies = (2 AND year = 1966), und 2 ist kein boolescher Wert. Trennen Sie Zuweisungen durch ein Komma: SET copies = 2, year = 1966. AND gehört in WHERE, wo es Bedingungen verknüpft.

Der Tabellenname vor einer SET-Spalte

UPDATE books
SET books.copies = 3
WHERE id = 1;

Was psql ausgibt

ERROR:  column "books" of relation "books" does not exist

Warum, und die Lösung

Die Spalte nach SET gehört immer zur geänderten Tabelle und bekommt deshalb keinen Tabellennamen; PostgreSQL liest books.copies als Feld copies einer Spalte books. Schreiben Sie SET copies = 3. In WHERE und in den Ausdrücken rechts sind qualifizierte Namen wie books.copies in Ordnung.

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

UPDATE ändert Werte in bestehenden Zeilen

UPDATE loans SET returned_on = '2026-10-01' WHERE id = 4; nennt die Tabelle, die Spalte mit ihrem neuen Wert und die Zeilen, die sich ändern. Spalten, die Sie in SET nicht nennen, behalten ihre Werte. Für mehrere Spalten trennen Sie die Zuweisungen durch Kommas: SET city = 'Hamburg', email = 'maggie@example.com'. Der neue Wert kann jeder Ausdruck sein, auch einer mit dem alten Wert: SET copies = copies + 1 fügt ein Exemplar hinzu. Jeder Ausdruck in SET sieht die Zeile so, wie sie vor der Änderung war, also tauscht SET name = city, city = name die beiden. Text und Datum stehen in einfachen Anführungszeichen, wie bei INSERT.

WHERE entscheidet, wie viele Zeilen sich ändern

Nur Zeilen, für die die WHERE-Bedingung wahr ist, ändern sich. Das kann eine Zeile sein, mehrere oder keine: Ein UPDATE, das nichts trifft, ist kein Fehler, es ändert einfach nichts. Lassen Sie WHERE weg, ändert sich jede Zeile der Tabelle, was selten gemeint ist. Eine Bedingung, die nie wahr ist, ist das stille Gegenstück: city = NULL ist für jede Zeile NULL, also ändert WHERE city = NULL nichts; schreiben Sie city IS NULL. psql meldet einen Tag wie UPDATE 3 mit der Zahl der Zeilen, im stillen Modus (-q) aber nicht. Führen Sie also zuerst ein SELECT mit demselben WHERE aus und sehen Sie sich danach die Zeilen an.

DELETE entfernt ganze Zeilen

DELETE FROM loans WHERE returned_on IS NOT NULL; entfernt die passenden Zeilen, immer ganze Zeilen; um einen einzelnen Wert zu leeren, setzen Sie ihn stattdessen per UPDATE auf NULL. Ohne WHERE entfernt DELETE FROM loans; jede Zeile, und die Tabelle bleibt, gültig und leer. TRUNCATE loans; macht dasselbe schneller, weil es die Tabelle nicht durchsucht; DROP TABLE entfernte die Tabelle selbst. Keines davon lässt sich nach dem Lauf rückgängig machen (außer in einer Transaktion, die in Modul I4 kommt). Änderungen können auch von einer anderen Tabelle abhängen: UPDATE loans SET … FROM members WHERE members.id = loans.member_id AND members.city = 'Berlin' ändert die Ausleihen der Berliner Mitglieder.

Quellen

Zuletzt geprüft am 3. Oktober 2026