Zum Inhalt springen
OneKitly

SQL-Formatierung und die IN-Klausel, die die Produktion zerlegt

Veröffentlicht am 13.8.2025 · 18 Min. Lesezeit · Entwickler-Tools

Daniel Okonkwo

Daniel OkonkwoFront-end-Entwickler und Tech-Redakteur bei OneKitly

Web-Performance · Dateiformate

Anhand von 7 Quellen geprüft

Profil ansehen
Kurz gesagt

Eine IN-Liste, die durch Einkleben der Werte in eine Zeichenkette entsteht, ist aus zwei unabhängigen Gründen falsch. Der Sicherheitsgrund: Die Werte werden Teil des Anweisungstexts, der Parser kann Daten nicht mehr von Syntax unterscheiden. Parametrisierung beseitigt diese Möglichkeit strukturell statt durch Filtern, denn die Anweisung wird zuerst geparst und geplant, und die Werte werden danach in Slots gebunden, die bereits als Werte typisiert sind. Ein gebundener Parameter kann kein Operator, kein Tabellenname und keine zweite Anweisung werden, egal was er enthält. Escaping ist nicht gleichwertig: Es ist eine Transformation, die in jedem Kontext korrekt angewandt werden muss, und eine einzige übersehene Stelle stellt das ganze Loch wieder her. Der betriebliche Grund ist der, den man tatsächlich trifft. Jede Datenbank deckelt, wie viele Parameter eine Anweisung tragen darf — PostgreSQL und MySQL bei 65 535, SQL Server bei 2 100 Parametern je Prozedur, Oracle bei 1 000 Ausdrücken in einer Liste bis 19c und 65 535 ab 23ai — und eine Anweisung, deren Text sich mit jeder Listenlänge ändert, erzeugt jedes Mal einen anderen Cache-Eintrag. Listenlängen 1 bis 1 000 naiv zu bedienen bedeutet 1 000 verschiedene Pläne statt einem, rund 49 MB Cache bei 50 KB je Plan. Die skalierenden Lösungen sind ein Array-Parameter, ein Join gegen eine VALUES-Liste oder eine temporäre Tabelle.

Eine IN-Liste per Zeichenkettenverkettung zu bauen ist zugleich der klassische Injektionsvektor und eine Leistungsklippe. Parametrisierung behebt das Erste strukturell, weil der Plan kompiliert wird, bevor irgendein Wert eintrifft. Das Zweite verlangt Rechnen: die von den Herstellern dokumentierten Parameterobergrenzen und das, was eine Abfrage, deren Text sich mit jeder Listenlänge ändert, mit einem Plan-Cache anstellt.

Warum Parametrisierung Injektion strukturell behebt

Eine Datenbank erhält eine Anweisung als Text und macht daraus stufenweise einen Plan: Sie tokenisiert, parst zu einem Baum, bindet Namen an Objekte, optimiert und führt erst dann aus. Wenn du Werte in den Text klebst, geschieht all das, nachdem deine Werte bereits mit deiner Syntax verschmolzen sind — der Parser entscheidet also, was deine Daten bedeuten. Das ist die gesamte Schwachstelle. Es geht nicht um Anführungszeichen oder Apostrophe, sondern darum, dass die Grenze zwischen Code und Daten getilgt wird, bevor die Datenbank die Anweisung überhaupt sieht.

Eine parametrisierte Anweisung dreht die Reihenfolge um. Der Text, den du sendest, enthält Platzhalter und überhaupt keine Werte — die Datenbank parst und plant also eine Anweisung, deren Gestalt bereits endgültig ist. Die Platzhalter sind Slots in diesem fertigen Plan, jeder mit deklariertem Typ, und einen Wert zu binden heißt, einen typisierten Slot in einem kompilierten Objekt zu füllen, nicht Zeichen an eine Zeichenkette zu hängen, die später geparst wird. Es gibt kein späteres Parsen. Deshalb ist die Zusicherung strukturell: Ein gebundener Wert hat keinen Weg, zu einem Operator, einem Tabellennamen, einem Kommentar oder einer zweiten Anweisung zu werden, weil die Stufe, die ihn so hätte deuten können, vorbei ist, bevor der Wert in der Welt der Datenbank existiert.

Escaping versucht, dasselbe Ergebnis zu erreichen, indem es den Wert transformiert, statt die Grenze zu verschieben — und ist keine gleichwertige Verteidigung. Es muss in jedem Kontext korrekt sein, und die Kontexte sind nicht dieselben: ein Zeichenkettenliteral, ein Zahlenliteral, eine Kennung, das Muster eines LIKE, ein Wert in einem JSON-Pfadausdruck und ein Wert in einem dynamisch gebauten ORDER BY brauchen jeweils andere Behandlung, und manche lassen sich überhaupt nicht sicher maskieren. Es muss unter jeder Zeichencodierung korrekt sein, denn genau über das Verhältnis von Bytes zu Zeichen argumentiert eine Escaping-Funktion. Und es muss an jeder einzelnen Stelle angewandt werden, für immer, auch an der, die eine Kollegin nächstes Quartal unter Termindruck hinzufügt. Parametrisierung muss einmal richtig sein, in der Form des Codes; Escaping muss jedes Mal richtig sein, in der Disziplin des Teams. Wo der Wert wirklich kein Parameter sein kann — ein Tabellenname, ein Spaltenname, eine Sortierrichtung —, lautet die Antwort nicht Maskieren, sondern Prüfen gegen eine feste Positivliste der Kennungen, die dein Schema tatsächlich enthält.

Die Obergrenzen, die jede Datenbank tatsächlich dokumentiert

Die Zahlen, die dazu in Blogbeiträgen kursieren, sind häufig veraltet — lies sie in den Handbüchern. Die Grenze von PostgreSQL stammt aus dem Netzprotokoll: Die Bind-Nachricht kodiert die Zahl der Parameterwerte in einem Sechzehn-Bit-Feld, und libpq verweigert alles über 65 535 mit einer Meldung, die den Bereich ausdrücklich nennt. MySQL hat aus demselben Grund dieselbe praktische Obergrenze — die Platzhalterzahl im Client-Server-Protokoll belegt zwei Byte — und ein Überschreiten erzeugt Serverfehler 1390, dessen Text besagt, dass die vorbereitete Anweisung zu viele Platzhalter enthält. MySQLs eigener Bugtracker führt einen offenen Wunsch, die 64k-Grenze anzuheben, was gut zeigt, dass es sich um eine reale und nicht um eine theoretische Schranke handelt.

SQL Server ist weit enger, und dieser Fall überrascht Teams. Seine veröffentlichten Kapazitätsangaben nennen 2 100 Parameter je gespeicherter Prozedur und 2 100 je benutzerdefinierter Funktion. Ein parametrisierter Batch aus einem Client-Treiber läuft über sp_executesql, und das ist eine gespeicherte Prozedur — er erbt also genau diese Obergrenze, und einer der Slots wird von der Mechanik verbraucht, weshalb Praktiker meist 2 099 oder 2 098 als Zahl der tatsächlich bindbaren Werte nennen. Zweitausend Kennungen sind nach heutigen Maßstäben kein großer Stapel; auf SQL Server ist die Grenze also kein theoretischer Randfall, sondern eine Entwurfsbedingung, die man von Anfang an einplanen muss.

Oracle begrenzt die Ausdrucksliste selbst statt der Parameterzahl, und die Zahl hat sich kürzlich genug geändert, dass das meiste, was du online liest, falsch ist. Bis 19c besagt die SQL Language Reference, dass eine kommagetrennte Ausdrucksliste höchstens 1 000 Ausdrücke enthalten darf; ein Überschreiten löst ORA-01795 aus. Ab 23ai nennt dieselbe Seite 65 535. Eine Feinheit überlebt den Wechsel: Eine kommagetrennte Liste von Ausdrucksmengen — die mehrspaltige Form von IN — darf beliebig viele Mengen enthalten, aber jede einzelne Menge bleibt auf 1 000 Ausdrücke gedeckelt. Prüfe die tatsächlich laufende Version, bevor du einen Stapel um eine der beiden Zahlen herum bemisst.

Plan-Cache-Verschmutzung, ausgerechnet

Eine Datenbank cacht kompilierte Pläne, um dieselbe Anweisung nicht zweimal zu optimieren, und der Cache-Schlüssel leitet sich aus dem Anweisungstext ab. Eine Abfrage mit drei Platzhaltern und eine mit vier sind verschiedener Text, also verschiedene Schlüssel, also verschiedene Einträge — obwohl es dieselbe Abfrage mit anderer Listenlänge ist. Das ist der ganze Mechanismus, und die Arithmetik folgt unmittelbar: Wenn deine Anwendung je Listenlängen von 1 bis N sendet, erzeugst du N verschiedene Pläne statt einem.

Rechne es für einen realistischen Bereich aus. Ein Endpunkt, der Bestellungen über 500 € für eine Menge von Kundenkennungen holt, sieht vielleicht eine Kennung bis ein paar hundert. Längen 1 bis 100 naiv zu bedienen erzeugt 100 verschiedene Pläne; 1 bis 1 000 erzeugt 1 000; 1 bis 5 000 erzeugt 5 000. Gib einem Plan eine plausible Größe — 50 KB ist ein vernünftiger Mittelwert für eine Abfrage mit ein paar Joins — und der Cache-Fußabdruck liegt bei rund 5 MB für 100 Längen, 49 MB für 1 000 und 244 MB für 5 000. Bei 200 KB je Plan, was eine komplexe analytische Abfrage leicht erreicht, kosten 1 000 Längen 195 MB und 5 000 kosten 977 MB. Dieser Speicher ist nicht gratis: Er stammt aus demselben Pool wie dein Puffercache, und auf Engines mit begrenztem Plan-Cache verdrängt er die Pläne des übrigen Arbeitspensums — das Symptom lautet also, dass unbeteiligte Abfragen langsamer werden.

Auch der Anweisungstext wächst, und er reist bei jeder Anfrage mit. Eine Abfrage der Form SELECT ... WHERE id IN mit nummerierten Platzhaltern liegt bei rund 525 Byte für 100 Werte, 5 926 Byte für 1 000, 68 927 Byte für 10 000 und 513 207 Byte für 65 535. Ein halbes Megabyte SQL-Text je Anfrage, jedes Mal von Grund auf geparst, weil nie wieder ein zwischengespeicherter Plan dazu passt — das ist die Gestalt der Klippe. Bei den zwei Kosten lohnt sich Genauigkeit: Die Parse- und Optimierarbeit fällt bei jedem einzelnen Aufruf an, weil der Cache stets danebengreift, und der Speicher wird von Einträgen belegt, die nie wiederverwendet werden.

Die skalierenden Lösungen: Array, VALUES-Join, temporäre Tabelle

Die beste Lösung faltet die ganze Anweisungsfamilie auf eine zusammen. Übergib die Liste als einen einzigen Parameter eines Array- oder Tabellentyps, und der Anweisungstext hängt nicht mehr von der Listenlänge ab: ein einziger Text, ein zwischengespeicherter Plan, ein Parse, bei jedem Aufruf. PostgreSQL bietet das direkt über einen Array-Parameter im Vergleich mit ANY — und deshalb stoßen PostgreSQL-Anwendungen kaum je an die 65 535: Ein Array-Parameter zählt als ein Parameter, egal wie viele Elemente er hält. SQL Server hat tabellenwertige Parameter, die denselben Zweck erfüllen und die Standardantwort auf seine 2 100 sind. Oracle hat Kollektionstypen, aus denen sich wie aus einer Tabelle lesen lässt.

Die portable Fassung derselben Idee ist ein Join gegen eine VALUES-Liste, den jede verbreitete Engine unterstützt und den der Optimierer als kleine Relation statt als lange Disjunktion behandeln kann. Sie ändert den Anweisungstext weiterhin mit der Zeilenzahl, behebt den Plan-Cache also nicht allein, liefert aber sehr oft einen besseren Plan als ein tausendfaches OR, weil der Optimierer sie per Hash joinen kann. Eine temporäre Tabelle ist die Fassung, die grenzenlos skaliert: Füge die Kennungen in Stapeln ein, joine gegen die Tabelle, und der Anweisungstext bleibt konstant, egal wie viele Kennungen es sind. Sie kostet einen Roundtrip und etwas Schreibarbeit, verdient ihren Platz also oberhalb einiger tausend Werte, nicht darunter.

Steckst du vorerst in einer literalen IN-Liste fest, ist Auffüllen ein billiger Notbehelf, der den meisten Cache-Schaden beseitigt. Runde die Liste auf einen Bucket auf und füll die freien Slots mit einem Wert, der nicht treffen kann — den ersten Bezeichner zu wiederholen ist der einfachste korrekte Kniff, denn am Ergebnis ändert sich nichts. Auf die nächste Zweierpotenz aufzurunden macht aus 1 000 möglichen Längen 11 verschiedene Anweisungen, verschwendet über diesen Bereich aber im Mittel 174 Parameter je Aufruf, ein Aufschlag von 34,8 %. Auf das nächste Vielfache von zehn aufzurunden ergibt 100 verschiedene Anweisungen und verschwendet im Mittel nur 4,5 Parameter, also 0,9 %. Dieser zweite Handel ist meist der richtige: Hundert zwischengespeicherte Pläne sind nichts, und ein Prozent Aufschlag auf die Parameterzahl ist unsichtbar.

Stapeln oberhalb der Obergrenze

Übersteigt die Liste die Obergrenze wirklich, teile sie auf. Die Zahl der Roundtrips folgt unmittelbar aus den Grenzen: 100 000 Kennungen brauchen 2 Aufrufe auf PostgreSQL, MySQL oder Oracle 23ai, 48 Aufrufe auf SQL Server bei 2 100 Parametern und 100 Aufrufe auf Oracle 19c bei 1 000 Ausdrücken. Diese Spanne ist der Grund, warum eine Stapelgröße, die im PostgreSQL-Container einer Entwicklerin bestens läuft, auf dem SQL Server des Kunden umfällt — leite die Blockgröße lieber aus der Datenbank ab, als eine Zahl fest zu verdrahten.

Beim Stückeln zählen zwei Details. Stückle deterministisch — sortiere die Kennungen vor dem Aufteilen —, damit ein Wiederholungsversuch dieselben Blöcke schickt und deine Protokolle über Läufe hinweg vergleichbar sind. Und entscheide ausdrücklich, ob der Lesevorgang konsistent sein muss: Mehrere getrennte Anweisungen sehen mehrere getrennte Snapshots. Können sich die Daten unter dir ändern, umschließe den Stapel mit einer einzigen Transaktion oder akzeptiere, dass die Vereinigung der Ergebnisse der Snapshot von nichts ist. Dieser zweite Punkt erzeugt den Fehler, den niemand nachstellen kann, weil er nur unter nebenläufigen Schreibvorgängen auftritt.

Formatierung ist nicht kosmetisch

Aus der Tatsache, dass der Plan-Cache über den Anweisungstext geschlüsselt wird, folgt zweierlei. Erstens: Formatierung zählt dort, wo du sie schreibst, nicht dort, wo du sie sendest. Eine lesbare Anweisung in deiner Quelldatei, mit Klauseln auf eigenen Zeilen und der Liste über mehrere verteilt, ist der Unterschied zwischen einem Review, das einen Fehler fängt, und einem, das darüber hinwegliest. Zweitens: Formatiere SQL nicht auf dem Weg hinaus um. Wenn eine Hülle zur Laufzeit verschönert, minifiziert oder Leerraum normalisiert, und das uneinheitlich tut — etwa anders unter Last oder anders nach einer Konfigurationsänderung —, erzeugt sie neue Cache-Einträge für eine Anweisung, für die die Engine längst einen Plan hatte. Formatiere für Menschen, im Repository; sende eine stabile Zeichenkette.

Es gibt noch einen Grund, die Anweisung lesbar zu halten, und er ist der Grund für diesen Artikel. Eine lange IN-Liste als eine riesige Zeile verbirgt alles: ob die Werte gebunden oder eingefügt sind, ob die Anzahl die erwartete ist, ob ein fremder Wert aus einer anderen Abfrage hineingerutscht ist. Über Zeilen verteilt und mit sichtbaren Platzhaltern sind alle drei auf einen Blick offensichtlich — ebenso der Moment, in dem die Liste aufhörte, eine Handvoll Kennungen zu sein, und still zu tausend wurde.

Dokumentierte Obergrenzen, im August 2026 aus dem Handbuch jedes Herstellers gelesen
DatenbankObergrenzeWie das Handbuch es nenntWas darüber passiert
PostgreSQL65 535 gebundene ParameterDie Bind-Nachricht trägt die Parameterzahl in einem 16-Bit-Feldlibpq verweigert den Aufruf vor dem Senden
MySQL65 535 PlatzhalterDie Platzhalterzahl belegt zwei Byte im Client-Server-ProtokollFehler 1390: Die vorbereitete Anweisung enthält zu viele Platzhalter
SQL Server2 100 ParameterParameter je gespeicherter Prozedur und je benutzerdefinierter FunktionEin parametrisierter Batch läuft über sp_executesql und erbt das Limit
Oracle, bis 19c1 000 AusdrückeEine kommagetrennte Ausdrucksliste darf höchstens 1000 enthaltenORA-01795
Oracle, ab 23ai65 535 AusdrückeGleicher Wortlaut, erhöhte Zahl; jede Ausdrucksmenge bleibt auf 1000 gedeckeltORA-01795
SQL-IN-Klausel-GeneratorWandle eine Werteliste (eine pro Zeile) in eine SQL-IN-(...)-Klausel um.Tool ausprobieren

Häufige Fragen

Ist Escaping je ein akzeptabler Ersatz fürs Binden?
Nein, und der Grund ist nicht, dass Escaping-Funktionen schlecht geschrieben wären — sie lösen ein anderes Problem. Binden verschiebt die Grenze zwischen Code und Daten so, dass ein Wert keinen Weg in die Syntax hat. Escaping lässt die Grenze, wo sie ist, und versucht jeden Wert zu entschärfen, der sie überschreiten könnte — es muss also in jedem Kontext, unter jeder Zeichencodierung, an jeder Aufrufstelle, für immer korrekt sein. Die Kontexte unterscheiden sich wirklich: ein Zeichenkettenliteral, ein Zahlenliteral, eine Kennung, ein LIKE-Muster und ein Wert in einer dynamisch zusammengesetzten Klausel brauchen jeweils andere Behandlung, und für manche gibt es überhaupt kein sicheres Escaping. Eine einzige übersehene Stelle stellt das ganze Loch wieder her, und übersehene Stellen sind das normale Ergebnis einer Codebasis mit mehr als einer Autorin. Es gibt einen Fall, in dem ein Wert wirklich kein Parameter sein kann, weil die Datenbank dort keinen Platzhalter akzeptiert: ein Tabellenname, ein Spaltenname, eine Sortierrichtung, ein LIMIT in manchen Engines. Auch dort lautet die Antwort nicht Escaping. Prüfe den Wert gegen eine feste Positivliste der Kennungen, die dein Schema tatsächlich enthält, und bilde Benutzereingaben auf eine Konstante ab, statt sie durchzureichen.
Was tue ich, wenn die Liste länger ist, als meine Datenbank erlaubt?
Drei Möglichkeiten, nach Aufwand und Skalierbarkeit aufsteigend. Erstens ein Array- oder tabellenwertiger Parameter, falls deine Engine einen hat: Die gesamte Liste reist als ein einziger Parameter, die Obergrenze greift nicht mehr, und der Anweisungstext wird konstant. Das ist die richtige Antwort auf PostgreSQL und auf SQL Server, wo die 2 100 sonst früh zubeißen. Zweitens eine temporäre Tabelle: Füge die Kennungen in Stapeln ein und joine dann gegen die Tabelle. Der Anweisungstext ist unabhängig von der Listengröße konstant, der Optimierer bekommt echte Kardinalitätsinformationen, und es gibt gar keine Obergrenze — du bezahlst einen Roundtrip und etwas Schreibarbeit dafür. Drittens Stückeln: Teile die Liste, führ die Abfrage je Block einmal aus und führe die Ergebnisse in deiner Anwendung zusammen. Leite die Blockgröße aus dem Limit der Datenbank ab, statt eine Zahl fest zu verdrahten, denn dieselbe Liste braucht auf PostgreSQL 2 und auf SQL Server 48 Roundtrips. Sortiere vor dem Teilen, damit Wiederholungen reproduzierbar sind, und lege den ganzen Stapel in eine Transaktion, wenn das zusammengeführte Ergebnis einen einzigen konsistenten Moment darstellen muss — sonst sehen mehrere getrennte Anweisungen mehrere getrennte Snapshots, und genau daher stammt der sporadische Fehler, den niemand nachstellen kann.
Warum wird die Abfrage langsamer, wenn die Liste wächst, obwohl sie weit unter dem Limit bleibt?
Drei Effekte stapeln sich, und man sollte sie trennen, denn sie haben verschiedene Abhilfen. Der erste ist die Kompilierung: Der Anweisungstext ändert sich mit jeder Listenlänge, der Plan-Cache greift also jedes Mal daneben, und der Optimierer parst und plant bei jedem Aufruf von Grund auf neu. Bei 1 000 Werten liegt der Text bereits bei rund 5 926 Byte, bei 10 000 bei 68 927. Die Optimierzeit wächst mit der Zahl der Prädikate, es ist also kein konstanter Aufschlag. Der zweite ist die Strategie des Optimierers. Eine IN-Liste ist logisch eine Kette von ORs, und ab einer bestimmten Länge behandelt der Optimierer sie nicht mehr als Menge von Indexzugriffen, sondern zieht einen Scan in Betracht — MySQL dokumentiert das ausdrücklich für den Bereichsoptimierer, der den Speicher verfolgt, den eine Bereichszugriffsmethode verbrauchen würde, und sie aufgibt, wenn ein konfiguriertes Limit überschritten würde, mit Rückfall auf einen vollständigen Tabellenscan. Diese Schwelle zu überschreiten ist eine Klippe, kein Hang. Der dritte ist der oben beschriebene Cache-Druck: Deine tausend Einwegpläne verdrängen die Pläne anderer Abfragen, die Verlangsamung zeigt sich also in Abfragen, die du nicht angefasst hast. Ein Array-Parameter oder eine temporäre Tabelle adressiert alle drei auf einmal, weil sie den Anweisungstext konstant macht und dem Optimierer eine joinbare Relation gibt.
Bedeutet ein ORM, dass ich über all das nicht nachdenken muss?
Es erledigt die Sicherheitshälfte und meist nicht die betriebliche. Jedes verbreitete ORM bindet Werte, statt sie einzufügen — das Injektionsrisiko ist für Query-Builder und generierte Anweisungen also wirklich weg, mit Ausnahme jeder Roh-SQL-Notluke, wo du die Parameter wieder selbst schreibst und wo die Schwachstellen in ORM-basierten Codebasen überwiegend wohnen. Die Leistungshälfte ist eine andere Geschichte. Die meisten ORMs rendern eine WHERE-Klausel über eine Sammlung als literale IN-Liste mit einem Platzhalter je Element — genau das Muster, das den Anweisungstext mit jeder Listenlänge ändert und den Plan-Cache flutet. Viele erzeugen zudem bereitwillig eine Liste, die länger ist, als deine Datenbank erlaubt, und scheitern erst bei der Ausführung; deshalb taucht die 2 100er-Grenze von SQL Server als Produktionsvorfall statt als Testfehler auf. Was du in deinem eigenen Stack prüfen solltest, ist konkret: ob dein ORM statt einer IN-Liste einen Array- oder tabellenwertigen Parameter ausgeben kann, ob es automatisch stückelt und mit welcher Blockgröße, und ob es das erzeugte SQL in einem lesbaren Protokoll offenlegt. Tut es nichts davon, ist ein Eager-Loading-Aufruf auf einer großen Sammlung ein Plan-Cache-Problem, das auf seinen Montag wartet.
Ändert das Umformatieren meines SQL sein Laufzeitverhalten?
Den Plan nicht, aber möglicherweise die Cache-Suche — und diese Unterscheidung lohnt sich. Der Optimierer arbeitet auf dem Parse-Baum, Leerraum und Zeilenumbrüche haben also überhaupt keine Wirkung auf den gewählten Plan: Eine über zwanzig Zeilen gesetzte Anweisung und dieselbe auf eine Zeile minifizierte führen identisch aus. Was sie nicht zwingend teilen, ist ein Cache-Eintrag, denn der Plan-Cache wird über den Anweisungstext geschlüsselt, und Engines normalisieren ihn unterschiedlich stark vorab. Die praktische Regel ist deshalb einfach: Formatiere das SQL in deinem Repository, wo ein Mensch es liest, und sende, was dein Treiber erzeugt, ohne Laufzeit-Verschönerer oder -Minifizierer im Pfad. Eine Hülle, die uneinheitlich umformatiert — anders unter Last oder anders, nachdem jemand ein Konfigurationsflag umgelegt hat —, kann einen zweiten Cache-Eintrag für eine Anweisung anlegen, für die die Engine längst einen Plan hatte: eine kleine, stille und sehr lästige Regression. Formatieren im Repository hat einen zweiten, wichtigeren Nutzen: Eine über Zeilen verteilte lange IN-Liste macht auf einen Blick sichtbar, ob die Werte gebunden oder eingefügt sind und ob die Anzahl die erwartete ist.

Artikel, die dich interessieren könnten

Alle Ratgeber
ErklärungJSON ist einfacher, als du denkst — und genau das ist das ProblemJSON hat keinen Ganzzahltyp, keinen Datumstyp, keine Kommentare und kein Schema. Jede dieser Lücken erzeugt einen konkreten Fehler: Eine 19-stellige ID kommt um 21 verfälscht zurück, ein Zeitstempel wird zu einer Zeichenkette, auf die sich niemand geeinigt hat, NaN lässt sich nicht hinschreiben, und doppelte Schlüssel sind erlaubt. Alles ausgeführt, in zwei Sprachen.ErklärungJSON zu CSV bei verschachtelter Struktur: warum es keine richtige Antwort gibtDieselben zwei Bestellungen kommen aus einem Konverter mit fünf Spalten und aus einem anderen mit zehn, und keiner liegt falsch. Punktpfade, Arrays aus Skalaren, Arrays aus Objekten und Datensätze mit unterschiedlichen Schlüsseln — vier Entscheidungen, für dich getroffen, meist stillschweigend.ErklärungSemikolon, Tab, Pipe: ein Trennzeichen wählen, das die Reise überstehtWarum die Sprache des Lesers das Trennzeichen bestimmt, was der Konverter beim Wechsel mit der Zitierung macht, was die erste Zeile sep= wirklich ist, und die Zahl zitierter Zellen bei demselben Export in fünf Schreibweisen.RatgeberHTTP-Statuscodes erklärt: die, die wirklich verwechselt werden301 gegen 308, 302 gegen 307, 401 gegen 403, 404 gegen 410 — dazu, was Retry-After bei einem 429 oder 503 wirklich zusagt. Die Paare, bei denen der falsche Code das Verhalten ändert und nicht nur die Formulierung.AnleitungRegex-Grundlagen: EinsteigerleitfadenEin regulärer Ausdruck ist ein Muster zum Abgleichen von Text. Hier die Bausteine — Zeichenklassen, Quantoren und Anker — mit Beispiel.ErklärungAlle E-Mail-Adressen oder URLs aus einem Textblock ziehenEine URL am Satzende behält den Punkt; eine E-Mail-Adresse am Ende desselben Satzes nicht. Ein akzentuierter Vorname in einer Adresse kommt abgeschnitten zurück. Jeder Fall hier lief durch die Werkzeuge, und die exakte Ausgabe steht dabei.

Ähnliche Tools

Quellen

Hast du einen Fehler in diesem Artikel entdeckt?