Strings sind das, womit echte Queries arbeiten
Mit Zahlen umzugehen ist einfach. Bei Strings wird's haarig – Namen mit überflüssigen Leerzeichen, E-Mails in gemischter Groß-/Kleinschreibung, IDs, die mit Bindestrichen zusammengeklebt sind, und Freitextfelder, die fast (aber eben nicht ganz) passen. SQLite bringt eine kompakte, gut durchdachte Sammlung an String-Funktionen mit, die den Großteil davon abdecken, ohne dass du extra Anwendungscode schreiben musst.
Auf dieser Seite gehe ich die SQLite String Funktionen durch, zu denen du am häufigsten greifst: Strings verketten, Teilstrings extrahieren, suchen, ersetzen, trimmen und formatieren.
Strings verketten mit dem || Operator (kein CONCAT)
Ein CONCAT gibt es in SQLite nicht. Zum Verketten von Strings nutzt du den || Operator:
Zahlen und andere Datentypen werden automatisch in Text umgewandelt. Der Haken dabei: Sobald auch nur ein Operand NULL ist, wird der gesamte Ausdruck zu NULL. Das ist Standardverhalten in SQL, sorgt aber regelmäßig für Überraschungen:
Pack nullable Spalten in COALESCE(col, '') oder COALESCE(col, 'default') ein, wenn ein fehlender Wert nicht den ganzen String zerschießen soll.
Länge, Groß- und Kleinschreibung
Die drei String-Funktionen, die du in SQLite ständig brauchst:
LENGTH liefert die Anzahl der Zeichen eines Texts, nicht der Bytes. Brauchst du wirklich die Byteanzahl (selten, aber bei Speicheranalysen ganz praktisch), nimm OCTET_LENGTH. UPPER und LOWER wandeln standardmäßig nur ASCII-Buchstaben um – Umlaute und Akzentzeichen bleiben unverändert, solange du nicht die ICU-Erweiterung geladen hast.
SUBSTR: sqlite substring extrahieren
Mit SUBSTR(text, start, length) schneidest du einen Teil aus einem String heraus. Wichtig: die Indizes starten bei 1, nicht bei 0 – das erste Zeichen ist also 1:
Ein paar Dinge solltest du dir merken:
- Das dritte Argument ist optional. Lässt du es weg, bekommst du alles ab
startbis zum Ende des Strings. - Ein negatives
startzählt vom Ende des Strings rückwärts. - Liegt
starthinter dem Ende, gibt es einen leeren String zurück – keinen Fehler.
SUBSTRING funktioniert als Synonym, falls dein Muskelgedächtnis aus einer anderen Datenbank kommt.
INSTR: Position eines Substrings finden
INSTR(haystack, needle) gibt die 1-basierte Position des ersten Vorkommens von needle in haystack zurück – oder 0, wenn nichts gefunden wurde:
Genau das ist die typische SQLite-Redewendung für "alles vor dem @": Mit INSTR das Trennzeichen finden und dann mit SUBSTR herausschneiden. Diese Kombination wirst du noch oft schreiben. Aber Achtung: Wenn INSTR nichts findet, gibt es 0 zurück – das solltest du vor dem Schneiden abfangen, denn eine 0 an SUBSTR zu übergeben liefert klammheimlich seltsame Ergebnisse.
REPLACE: Teilstrings ersetzen mit der sqlite REPLACE Funktion
REPLACE(text, old, new) ersetzt jedes Vorkommen von old durch new:
Die Funktion ist case-sensitive und akzeptiert keine Regex – nur einen literalen Teilstring. Für komplexere Transformationen lassen sich mehrere REPLACE-Aufrufe verschachteln, aber spätestens ab der dritten Verschachtelung gehört die Logik in die Anwendung statt in SQL.
TRIM, LTRIM, RTRIM
Daten aus Nutzereingaben bringen gerne Whitespace an den Rändern mit. Genau dafür gibt es TRIM:
Standardmäßig werden Leerzeichen entfernt. Mit einem zweiten Argument legst du fest, welche Zeichen abgeschnitten werden sollen — wobei jedes Zeichen im zweiten Argument als Teil einer "Entfernungsmenge" behandelt wird, nicht als zusammenhängender Teilstring. TRIM('xxxhelloxx', 'x') liefert also 'hello'.
printf: Zahlen und Strings formatieren mit sqlite printf Format
Wenn du einen formatierten String brauchst — feste Nachkommastellen, aufgefüllte Zahlen, Hex-Ausgabe — ist printf (auch unter dem Namen format bekannt) genau das richtige Werkzeug:
Die Format-Spezifizierer folgen den C-Konventionen, also %d, %s, %f, %x, Auffüllen mit 0 oder Leerzeichen und so weiter. Das ist deutlich sauberer, als Strings mit || und einem Haufen CASTs zusammenzubauen.
LIKE vs GLOB: Pattern Matching in SQLite
Zwei Operatoren, zwei verschiedene Welten.
LIKE arbeitet mit den klassischen SQL-Wildcards — % für eine beliebige Zeichenfolge, _ für ein einzelnes Zeichen — und ist bei ASCII-Zeichen unabhängig von Groß- und Kleinschreibung:
GLOB arbeitet mit den klassischen Unix-Shell-Wildcards — * für eine beliebige Zeichenfolge, ? für ein einzelnes Zeichen und [abc] für Zeichenklassen — und unterscheidet dabei zwischen Groß- und Kleinschreibung:
Die Faustregel für die Wahl: LIKE nimmst du für die typischen Mustervergleiche wie „beginnt mit", „enthält" oder „endet auf". GLOB ist dann dran, wenn die Groß-/Kleinschreibung relevant ist oder du Zeichenklassen brauchst. Beide können Indexe nutzen — allerdings nur, wenn das Muster am Anfang verankert ist ('foo%', nicht '%foo'). Ein führender Wildcard zwingt SQLite zum kompletten Table Scan.
Strings splitten in SQLite: SPLIT gibt's nicht
SQLite bringt keine SPLIT_STRING-Funktion mit. In der Praxis bleiben dir zwei Wege:
Wenn du an einem Trennzeichen aufteilen und mehrere Zeilen erzeugen willst, ist der sauberste Weg json_each über ein JSON-Array oder ein rekursives CTE. Beides schauen wir uns in späteren Kapiteln noch genauer an — für den Moment reicht es zu wissen: "Gib mir jedes Wort einzeln" ist in SQLite kein Einzeiler.
Praxisbeispiel: Namen aufräumen
Jetzt setzen wir die sqlite string funktionen zusammen. Stell dir eine users-Tabelle mit chaotischen Anzeigenamen vor — überflüssige Leerzeichen, gemischte Groß-/Kleinschreibung und optionale Anreden wie "Dr. " oder "Mr. ", die du loswerden möchtest:
Der Ausdruck liest sich von innen nach außen: außen Whitespace abschneiden, kleinschreiben, die Titel entfernen und nochmal trimmen, falls durch das Entfernen des Titels ein Leerzeichen am Anfang stehengeblieben ist. Jeder Schritt ist eine einzelne Funktion — die Komplexität entsteht erst durchs Stapeln. Sobald der Stapel über drei oder vier Ebenen hinauswächst, ist das ein Wink, entweder eine Generated Column zu nutzen (Kapitel: Fortgeschrittene Features) oder die Bereinigung schon beim Datenimport zu erledigen.
Das Wichtigste auf einen Blick
||zum Verketten von Strings;NULLvergiftet das Ergebnis, alsoCOALESCEeinsetzen.SUBSTRundINSTRdecken zusammen die meisten "Finden und Ausschneiden"-Aufgaben ab.REPLACEtauscht jedes Vorkommen eines literalen Teilstrings aus.TRIMund Konsorten akzeptieren auch eine eigene Zeichenmenge, nicht nur Whitespace.printfist das richtige Werkzeug für formatierte Ausgabe.LIKEfür SQL-Wildcards ohne Beachtung der Groß-/Kleinschreibung,GLOBfür Shell-Pattern mit Beachtung der Groß-/Kleinschreibung.
Weiter geht's: Numerische Funktionen
Strings sind abgehakt, der nächste logische Halt sind Zahlen — Runden, Absolutwerte, Eigenheiten bei der Division und die Mathe-Funktionen, die SQLite in den letzten Versionen ergänzt hat. Genau darum geht es auf der nächsten Seite.
Häufig gestellte Fragen
Wie verkettet man Strings in SQLite?
Mit dem Operator ||, nicht mit CONCAT. Eine Funktion CONCAT gibt es in SQLite standardmäßig nämlich gar nicht. 'Hallo, ' || name hängt die beiden Strings einfach aneinander. Aufpassen: Sobald einer der Operanden NULL ist, ist auch das Ergebnis NULL – wenn das nicht erwünscht ist, packt man die nullable Spalten in COALESCE ein.
Wie bekomme ich einen Teilstring (Substring) in SQLite?
Über SUBSTR(text, start, length) – SUBSTRING funktioniert als Alias genauso. Die Indizes sind 1-basiert, SUBSTR('hello', 1, 3) liefert also 'hel'. Ein negativer Startwert zählt vom Ende her, und das length-Argument ist optional: lässt man es weg, wird alles bis zum Ende des Strings genommen.
Hat SQLite eine SPLIT_STRING-Funktion?
Nein, eine eingebaute Split-Funktion gibt es in SQLite nicht. In den meisten Fällen kommt man mit der Kombination aus INSTR und SUBSTR ans gewünschte Teilstück, oder man baut sich mit einer rekursiven CTE einen Splitter über ein Trennzeichen. Wer das öfter braucht, fährt meistens besser, indem er den String als JSON-Array ablegt und mit json_each darüber iteriert – das ist deutlich sauberer als jede Eigenbau-Lösung.
Was ist der Unterschied zwischen LIKE und GLOB in SQLite?
LIKE ist bei ASCII-Zeichen standardmäßig case-insensitive und arbeitet mit % und _ als Platzhaltern. GLOB dagegen unterscheidet zwischen Groß- und Kleinschreibung und nutzt die Wildcards aus der Unix-Shell (*, ?, [abc]). Kurz gesagt: GLOB nimmt man, wenn man auf Case-Sensitivity oder Zeichenklassen angewiesen ist – LIKE ist die Wahl für das klassische SQL-Matching.