Upsert in SQLite mit ON CONFLICT DO UPDATE
Einfügen oder aktualisieren in einem einzigen Statement – mit ON CONFLICT ... DO UPDATE. Kein vorheriges SELECT, kein Race Condition zwischen Prüfen und Schreiben.
„Wenn der Eintrag existiert, aktualisiere ihn, sonst füge ihn neu ein." Das nennt man Upsert. Statt erst mit einem SELECT zu prüfen und dann zu entscheiden, macht SQLite das atomar in einem Statement – mit ON CONFLICT ... DO UPDATE. Das spart nicht nur Code, sondern schließt auch die Lücke zwischen Prüfen und Schreiben, in der sonst zwei parallele Zugriffe kollidieren könnten.
Voraussetzung: ein Unique-Constraint
Ein Upsert braucht eine Spalte, an der SQLite den Konflikt erkennt – einen PRIMARY KEY oder UNIQUE-Index.
CREATE TABLE seiten_aufrufe (
pfad TEXT PRIMARY KEY,
treffer INTEGER NOT NULL DEFAULT 0,
zuletzt INTEGER NOT NULL
);Das Upsert
INSERT INTO seiten_aufrufe (pfad, treffer, zuletzt)
VALUES ('/start', 1, unixepoch())
ON CONFLICT(pfad) DO UPDATE SET
treffer = treffer + 1,
zuletzt = excluded.zuletzt;Der Clou ist das Schlüsselwort excluded: Es steht für die Zeile, die eingefügt werden *sollte*. So greifst du im UPDATE-Teil auf die neuen Werte zu – hier setze ich zuletzt auf den gerade übergebenen Zeitstempel, während ich treffer um eins hochzähle.
Nur bei Bedarf aktualisieren
Du kannst den Update-Teil zusätzlich an eine Bedingung knüpfen – etwa nur schreiben, wenn sich wirklich etwas ändert:
INSERT INTO seiten_aufrufe (pfad, treffer, zuletzt)
VALUES ('/start', 1, unixepoch())
ON CONFLICT(pfad) DO UPDATE SET
treffer = treffer + 1,
zuletzt = excluded.zuletzt
WHERE excluded.zuletzt > seiten_aufrufe.zuletzt;Genau dieses Muster nutze ich für die cookielose Aufruf-Statistik in meinem eigenen CMS. Wenn du eine Website mit sauberer, datensparsamer Auswertung brauchst, findest du mich auf bymw.de.
Quellen
Du brauchst mehr als ein Snippet?
Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.
Projekt anfragen →Verwandte Rezepte
PDO mit SQLite – sichere Abfragen per Prepared Statement
SQLite ist eine ganze Datenbank in einer Datei – perfekt für kleine Projekte. Mit PDO und Prepared Statements fragst du sie sicher ab, ganz ohne SQL-Injection.
Robustes Bash-Grundgerüst mit set -euo pipefail
Ein Shell-Skript, das bei Fehlern einfach weiterläuft, ist gefährlich. Mit set -euo pipefail und einem sauberen Grundgerüst bricht dein Skript beim ersten Problem sicher ab.
Responsives Karten-Grid ganz ohne Media Queries
Mit repeat(auto-fill, minmax()) baust du ein Grid, das die Spaltenzahl selbst an die Breite anpasst. Ein einziger Deklarationsblock ersetzt einen Stapel Media Queries.