Menu

SQLite Views: CREATE VIEW, INSTEAD OF & temporäre Views

Wie Views in SQLite funktionieren – Queries als virtuelle Tabellen speichern, wann temporäre Views sinnvoll sind und warum SQLite-Views standardmäßig schreibgeschützt sind.

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

Eine View ist eine gespeicherte Abfrage

Eine View in SQLite ist im Grunde ein SELECT-Statement mit einem Namen. Sobald du sie angelegt hast, kannst du sie wie eine Tabelle abfragen – gespeichert wird dabei aber nichts. Bei jedem Zugriff auf die View führt SQLite die zugrunde liegende Abfrage neu aus.

paid_orders sieht aus wie eine Tabelle und verhält sich auch so. Es gibt Spalten, du kannst SELECT-Abfragen darauf ausführen und sogar joinen. Im Hintergrund wird aber bei jeder Abfrage wieder der ursprüngliche Filter WHERE status = 'paid' eingesetzt.

Genau das ist das mentale Modell, das du brauchst: Ein View ist nichts anderes als ein Alias für eine Abfrage.

Wozu sind SQLite Views gut?

Der größte Vorteil liegt in der Benennung. Eine komplizierte Abfrage bekommt einen kurzen, sprechenden Namen – und der Rest deines Codes bleibt lesbar:

Ohne den View müsste jede aufrufende Stelle das GROUP BY selbst schreiben — und irgendwer baut den Filter garantiert falsch ein. Mit dem View ist die Aggregation an einer einzigen Stelle definiert. Die Aufrufer fragen einfach customer_totals ab und hängen ihre eigenen Filter oben drauf.

Views funktionieren außerdem wie eine Art Berechtigungsgrenze. Soll eine Abfrage zum Beispiel die Spalte password_hash nicht preisgeben, legt man einen View an, der alle Spalten außer dieser einen auswählt, und lässt den Anwendungscode ausschließlich über diesen View arbeiten.

CREATE VIEW: Syntax im Detail

Die vollständige Form sieht so aus:

CREATE [TEMPORARY] VIEW [IF NOT EXISTS] view_name [(column_aliases)] AS
SELECT ...;

Ein paar Dinge, die man wissen sollte:

  • IF NOT EXISTS überspringt das Anlegen stillschweigend, falls die View schon existiert.
  • TEMPORARY (bzw. TEMP) erzeugt eine View, die beim Schließen der Verbindung wieder verschwindet.
  • Mit Spalten-Aliassen in Klammern lassen sich die Spalten der View umbenennen, ohne das zugrunde liegende SELECT anfassen zu müssen.

Die View stellt sprechendere Namen (item, dollars) bereit, ohne dass du die Spalten in der zugrunde liegenden Tabelle umbenennen musst.

Views ersetzen und löschen

SQLite kennt weder CREATE OR REPLACE VIEW noch ALTER VIEW. Wenn du die Definition einer View ändern willst, musst du sie löschen und neu anlegen:

DROP VIEW IF EXISTS active_orders; ist die sichere Variante – sie wirft keinen Fehler, wenn die View gar nicht existiert. Das Löschen einer View hat übrigens nie Auswirkungen auf die zugrunde liegenden Tabellen; du entfernst lediglich die gespeicherte Abfrage.

Temporäre Views in SQLite

Eine TEMP VIEW lebt nur so lange wie die aktuelle Datenbankverbindung. Sobald die Verbindung geschlossen wird, ist die View weg. Praktisch für spontane Auswertungen, bei denen du keine dauerhaften Definitionen hinterlassen möchtest:

Temporäre Views sind außerdem praktisch, wenn du einen Abfragenamen überschreiben willst, ohne ihn fest ins Schema aufzunehmen — perfekt zum Herumexperimentieren.

Views sind standardmäßig schreibgeschützt

Das ist der wichtigste Stolperstein. Über einen View kannst du nicht direkt INSERT, UPDATE oder DELETE ausführen:

sqlite> INSERT INTO paid_orders (customer, amount) VALUES ('Eve', 50);
Laufzeitfehler: paid_orders kann nicht geändert werden, da es eine View ist

Die Lösung sind INSTEAD OF-Trigger. Du schreibst einen Trigger, der anstelle des Schreibversuchs ausgelöst wird und ihn in eine echte Operation auf der zugrunde liegenden Tabelle umwandelt:

Die View bleibt eine View – Schreibvorgänge dagegen haben jetzt ein Ziel, an das sie weitergereicht werden können. Trigger schauen wir uns auf der nächsten Seite im Detail an.

Keine Materialized Views in SQLite – Marke Eigenbau

Manche Datenbanken bieten an, das Ergebnis einer View auf der Festplatte zwischenzuspeichern und bei Bedarf zu aktualisieren. SQLite kann das nicht. Jeder Zugriff auf eine View führt die zugrunde liegende Abfrage neu aus. Für die meisten Anwendungsfälle ist das völlig okay – SQLite ist schnell und der Query-Planner macht einen guten Job. Bei teuren Aggregationen, die häufig abgefragt werden, legst du dir stattdessen eine echte Tabelle an und hältst sie selbst aktuell:

Den Cache aktualisierst du dann entweder per Zeitplan oder über Trigger auf orders, damit die Daten frisch bleiben. Das ist Handarbeit – aber in SQLite die einzige Möglichkeit.

Vorhandene Views auflisten

Die Metadaten zu Views landen in sqlite_master, zusammen mit Tabellen und Indizes:

Die Spalte sql liefert dir das ursprüngliche CREATE VIEW-Statement zurück – praktisch, wenn du nicht mehr weißt, was eine View eigentlich macht. In der CLI macht .schema view_name dasselbe, nur etwas aufgeräumter.

Wann lohnt sich eine SQLite View?

Views zahlen sich aus, wenn:

  • Eine nicht-triviale Query an drei oder mehr Stellen wiederverwendet wird. Einmal benennen schlägt mehrfaches Copy-Paste.
  • Du einen kuratierten Ausschnitt von Spalten oder Zeilen für einen Teil der Anwendung freigeben willst.
  • Eine Aggregation gedanklich ein einzelnes Ding ist (monthly_sales, active_users), das Aufrufer wie ein Substantiv behandeln sollten.

Lass die View weg, wenn:

  • Die Query nur an genau einer Stelle gebraucht wird. Dann gehört sie inline.
  • Performance entscheidend ist und die zugrundeliegende Query teuer ist – diese Kosten zahlst du bei jedem Lesezugriff. Cache das Ergebnis lieber in einer echten Tabelle.
  • Die View von einer View abhängt, die wiederum von einer View abhängt. SQLite kommt mit der Verschachtelung klar, aber eine Kette aus drei oder vier Views macht das tatsächliche SQL beim Debuggen kaum noch lesbar.

Weiter geht's: Trigger

Views und Trigger tauchen häufig im Doppelpack auf – das Muster mit INSTEAD OF, mit dem sich eine SQLite View beschreibbar machen lässt, ist einer der Hauptgründe, warum es Trigger überhaupt gibt. Trigger sind aber auch für sich genommen nützlich: für Audit-Logging, kaskadierende Updates und das Erzwingen von Invarianten. Genau darum geht es auf der nächsten Seite.

Häufig gestellte Fragen

Was ist ein View in SQLite?

Ein View ist im Grunde ein gespeichertes SELECT, das du wie eine Tabelle abfragen kannst. Daten werden dabei nicht abgelegt – jedes Mal, wenn du den View liest, führt SQLite die zugrundeliegende Query erneut aus. Praktisch ist das, um eine komplexe Abfrage einmal zu benennen und überall wiederzuverwenden, oder um Spalten zu verstecken, die der Aufrufer gar nicht sehen soll.

Kann man über einen View in SQLite INSERT oder UPDATE machen?

Direkt nicht. Views sind in SQLite read-only – INSERT, UPDATE und DELETE auf einen View laufen ins Leere. Schreibbar bekommst du sie nur über INSTEAD OF Trigger, die den Schreibzugriff in entsprechende Operationen auf den darunterliegenden Tabellen übersetzen.

Unterstützt SQLite materialisierte Views?

Nein. SQLite kennt nur klassische (virtuelle) Views – die Query wird bei jedem Zugriff neu ausgeführt. Wenn du Ergebnisse zwischenspeichern willst, leg dir eine echte Tabelle an und aktualisiere sie selbst, oder halte sie per Trigger mit den Quelltabellen synchron.

Wie listet man alle Views in einer SQLite-Datenbank auf?

Per Abfrage auf sqlite_master: SELECT name FROM sqlite_master WHERE type = 'view';. In der CLI zeigt .schema die CREATE VIEW-Statements an, und .tables listet Views zusammen mit den Tabellen.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S