Menu

SQLite UPDATE: WHERE, mehrere Spalten & UPDATE FROM

So änderst du bestehende Zeilen in SQLite: UPDATE-Syntax, die rettende WHERE-Klausel, mehrere Spalten in einem Rutsch und UPDATE ... FROM für tabellenübergreifende Änderungen.

Diese Seite enthält ausführbare Editoren — bearbeiten, ausführen und Ausgabe sofort sehen.

UPDATE ändert vorhandene Zeilen

Während INSERT neue Zeilen anlegt, ändert UPDATE Zeilen, die bereits in der Tabelle stehen. Die SQLite-UPDATE-Syntax ist kurz und lohnt sich auswendig zu lernen:

UPDATE table_name
SET column = value
WHERE condition;

Ein praxisnahes Beispiel:

SET legt fest, was sich ändert. WHERE legt fest, welche Zeilen betroffen sind. Alles andere in der Tabelle bleibt unangetastet.

Warum die WHERE-Klausel in der Praxis Pflicht ist

Rein technisch ist WHERE optional. In der Praxis ist das Weglassen aber der schnellste Weg, sich als Junior-Entwickler den Nachmittag zu ruinieren:

UPDATE users SET status = 'inactive';
-- jeder einzelne Benutzer ist jetzt inaktiv

Ohne Filter trifft die Bedingung auf jede Zeile zu. SQLite zieht das klaglos durch. Schreib darum immer zuerst das WHERE und danach erst das SET – allein diese Angewohnheit erspart dir jede Menge Ärger.

Wenn du dir bei deinem WHERE nicht sicher bist, prüf die Bedingung vorher mit einem SELECT:

Gleiche Bedingung, zwei Statements. Das SELECT ist dein Trockenlauf.

SQLite Update mehrere Spalten gleichzeitig

Trenne die Zuweisungen einfach per Komma innerhalb eines einzigen SET. Ein SET, viele Spalten:

Eine einzige Runde zur Datenbank, eine Zeile geändert, drei Spalten aktualisiert. Schreib keine drei einzelnen UPDATE-Statements, wenn eines reicht.

Ausdrücke rechts vom =

Der Wert hinter = muss kein Literal sein. Es kann jeder beliebige Ausdruck stehen — auch einer, der auf den aktuellen Wert der Spalte zugreift:

price * 1.10 liest den aktuellen Preis aus, multipliziert ihn und schreibt das Ergebnis zurück. Bei der rechten Seite greift SQLite auf die aktuellen Werte der Zeile zu, bevor irgendeine Zuweisung dieses Statements wirksam wird – du kannst also problemlos mehrere Spalten gleichzeitig referenzieren:

UPDATE products SET price = price * 1.10, stock = stock + price;
-- 'price' auf der rechten Seite ist hier der ALTE Preis, nicht der gerade aktualisierte.

UPDATE ... FROM: Werte aus einer anderen Tabelle übernehmen

Seit SQLite 3.33 unterstützt UPDATE eine FROM-Klausel für tabellenübergreifende Updates. Das ist die sauberste Variante, um Daten zwischen Tabellen abzugleichen – quasi das SQLite-Pendant zu einem UPDATE JOIN:

Die Subquery berechnet die Summen pro Kunde, und das äußere UPDATE führt diese Ergebnisse über id wieder mit customers zusammen. Ohne UPDATE ... FROM müsstest du für jede Spalte eine korrelierte Subquery schreiben – das wird schnell unübersichtlich.

Ein paar Regeln, die du im Hinterkopf behalten solltest:

  • Die Zieltabelle steht nach UPDATE, nicht in der FROM-Liste.
  • Der Join passiert in der WHERE-Klausel – ein ON-Schlüsselwort gibt es hier nicht.
  • Falls der Join mehr als eine Zeile im FROM treffen könnte, ist das Ergebnis nicht definiert. Sorge dafür, dass deine Join-Schlüssel höchstens einen Treffer pro Zielzeile liefern.

SQLite UPDATE RETURNING: Geänderte Zeilen direkt zurückgeben

Ab SQLite 3.35 kann UPDATE die geänderten Zeilen direkt im selben Statement zurückgeben. Praktisch, wenn deine Anwendung die aktualisierten Werte braucht, ohne danach noch ein SELECT abzusetzen:

Du bekommst die tatsächlich geänderten Zeilen samt ihrer neuen Werte zurück. Das spart einen zusätzlichen Roundtrip und beseitigt eine ganze Klasse von Race Conditions in nebenläufigem Code. Später in diesem Kapitel gibt es eine eigene Seite zu RETURNING.

UPDATE OR REPLACE: Konflikte mit Constraints abfangen

Verletzt dein UPDATE einen UNIQUE-Constraint, bricht SQLite das Statement standardmäßig mit einem Fehler ab. Über die OR-Klausel kannst du stattdessen eine andere Strategie festlegen:

Die Optionen sind OR ABORT (Standard), OR REPLACE, OR IGNORE, OR FAIL und OR ROLLBACK. Heikel ist vor allem REPLACE – die Variante löscht nämlich die kollidierende Zeile, was sich über Foreign Keys auch noch weiter durchziehen kann. Greif nur dann dazu, wenn du wirklich sagen willst: „Falls es schon eine Zeile mit diesem eindeutigen Wert gibt, weg damit."

Für klassisches Upsert-Verhalten ist die spezielle Syntax INSERT ... ON CONFLICT deutlich übersichtlicher. Dazu gibt es eine eigene Seite.

Riskante Updates in eine Transaktion packen

Wenn du viele Zeilen änderst oder mehrere UPDATE-Anweisungen ausführst, die nur gemeinsam Sinn ergeben, solltest du sie in eine Transaktion einschließen. Geht irgendwo etwas schief, kannst du den Zustand davor per Rollback wiederherstellen:

Schlägt die zweite Anweisung fehl (etwa weil ein Constraint zuschlägt), macht ROLLBACK die erste rückgängig. Ohne Transaktion bliebe ein halber Transfer übrig — Ada hat 25 weniger, Boris steht unverändert da. Transaktionen bekommen später ihr eigenes Kapitel; vorerst reicht es zu wissen, dass es sie gibt und dass größere Updates fast immer in eine Transaktion gehören.

Typische Stolperfallen

Eine kurze Liste der Klassiker, über die viele stolpern:

  • WHERE vergessen — dann wird jede Zeile aktualisiert. Sprich dein Statement einmal laut durch, bevor du es ausführst.
  • Falscher Operator im WHEREWHERE status = NULL trifft auf nichts zu. Richtig ist IS NULL. Mehr dazu auf der Seite zu den Operatoren.
  • Update mit einer Subquery, die mehr als eine Zeile liefert, obwohl du genau eine erwartest. Setze LIMIT 1 ein oder aggregiere die Subquery — sonst gibt es Fehler oder unerwartete Ergebnisse.
  • UPDATE OR REPLACE mit UPSERT verwechseln. OR REPLACE löscht die kollidierenden Zeilen. INSERT ... ON CONFLICT DO UPDATE ändert sie an Ort und Stelle. Zwei verschiedene Operationen.

Als Nächstes: DELETE

UPDATE ändert Zeilen, DELETE entfernt sie. Dieselbe Disziplin beim WHERE gilt auch hier — und dieselbe Gewohnheit, vorher ein SELECT laufen zu lassen, bewahrt dich vor denselben Katastrophen. Das ist Thema der nächsten Seite.

Häufig gestellte Fragen

Wie sieht die UPDATE-Syntax in SQLite grundsätzlich aus?

UPDATE tabellenname SET spalte = wert WHERE bedingung;. Im SET-Teil legst du fest, welche Spalten welchen neuen Wert bekommen. Mit WHERE bestimmst du, welche Zeilen betroffen sind — lässt du die Klausel weg, schreibt SQLite jede Zeile der Tabelle um.

Wie aktualisiere ich mehrere Spalten in einem einzigen Statement?

Du trennst die Zuweisungen einfach mit Komma innerhalb von SET: UPDATE users SET name = 'Ada', email = 'ada@x.com' WHERE id = 1;. Ein Statement, ein Datenbankzugriff, eine Zeile geändert. SET darf dabei nur einmal stehen — nicht pro Spalte wiederholen.

Kann SQLite eine Tabelle anhand einer anderen Tabelle aktualisieren?

Ja, dafür gibt es seit SQLite 3.33 das UPDATE ... FROM. Damit kannst du eine zweite Tabelle oder eine Subquery in dein UPDATE einbinden: UPDATE ziel SET spalte = quelle.spalte FROM quelle WHERE ziel.id = quelle.id;. Das ist der sauberste Weg, um Werte tabellenübergreifend zu übernehmen.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S