Seite wählen

Nachgestellte Leerzeichen und String-Vergleiche in Datenbanken

von | Apr 9, 2015 | MySQL, PostgreSQL, MariaDB

Für Datenbanken die sich an den SQL-92-Standard halten, gilt für Vergleiche von character strings nach Abschnitt 8.2 Generals Rules #3, dass die zu vergleichenden Strings, vor dem Vergleich auf die selbe Länge gebracht werden müssen. Der eventuell kürzere String wird demnach nach rechts auf die Länge des zu vergleichenden Strings mit Hilfe eines pad character, meist dem Leerzeichen, aufgefüllt.
Unter character strings fallen die Typen char (character) und varchar (character varying). Diese Typen ähneln einander, werden aber auf unterschiedliche Weise gespeichert und abgerufen.
char-Werte werden beim Speichern nach rechts mit Leerzeichen bis auf die deklarierte Länge aufgefüllt, welche beim Abrufen aber wieder entfernt werden. Bei char-Werten mit einer maximalen Anzahl von vier Zeichen beispielweise, kann man deshalb nicht zwischen 'abc' und 'abc ' unterscheiden.
Im Gegensatz dazu werden varchar-Werte nur mit so vielen Zeichen wie erforderlich zuzüglich der Information über die Länge gespeichert. varchar-Werte werden beim Speichern nicht aufgefüllt. Somit werden auch Leerzeichen beim Speichern und Abrufen beibehalten.
Und jetzt? Jetzt wollen wir versuchen aus den varchar-Werten 'abc' und 'abc ' nur 'abc ' zu selektieren.
Als Erstes brauchen wir natürlich eine Datenbank mit den gewünschten Daten (hier in MySQL):

CREATE DATABASE playground;
USE playground;
CREATE TABLE pad (string varchar(5));
INSERT INTO pad VALUES('abc');
INSERT INTO pad VALUES('abc ');
INSERT INTO pad VALUES('abc  ');

Als Nächstes überprüfen wir, ob – wie im Standard definiert – bei varchar-Werten Leerzeichen beim Speichern und Abrufen beibehalten werden:

SET sql_mode = PIPES_AS_CONCAT;
SELECT '"' || string || '"', LENGTH(string) FROM pad;
+----------------------+----------------+
| '"' || string || '"' | LENGTH(string) |
+----------------------+----------------+
| "abc"                |              3 |
| "abc "               |              4 |
| "abc  "              |              5 |
+----------------------+----------------+

Das sieht doch gut aus. Nun zurück zur eigentlichen Aufgabe: Wir wollen aus diesen Daten nur 'abc ' selektieren:

SELECT '"' || string || '"', LENGTH(string) FROM pad WHERE string = 'abc ';
+----------------------+----------------+
| '"' || string || '"' | LENGTH(string) |
+----------------------+----------------+
| "abc"                |              3 |
| "abc "               |              4 |
| "abc  "              |              5 |
+----------------------+----------------+

Irgendwie nicht richtig. Oder doch? Wie eingangs erwähnt, tritt hier die Regel für Vergleiche von character strings aus dem SQL-92-Standard in Kraft: Der kürzere zu vergleichende String wird nach rechts mit Leerzeichen aufgefüllt. Wenn 'abc' mit 'abc ' verglichen wird, wird eigentlich 'abc ' mit 'abc ' verglichen, oder 'abc' mit 'abc' – wer weiß das schon so genau :).
Kommt man trotzdem auf das gewünschte Ergebnis? Klar, mit einem Zaubertrick:

SELECT '"' || string || '"', LENGTH(string) FROM pad WHERE BINARY string = 'abc ';
+----------------------+----------------+
| '"' || string || '"' | LENGTH(string) |
+----------------------+----------------+
| "abc "               |              4 |
+----------------------+----------------+

Gibt’s Ausnahmen? Ja! Bei PostgreSQL sind bei Vergleichen von varchar-Werten nachgestellte Leerzeichen signifikant.

Eric Lippmann
Eric Lippmann
CTO

Eric kam während seines ersten Lehrjahres zu NETWAYS und hat seine Ausbildung bereits 2011 sehr erfolgreich abgeschlossen. Seit Beginn arbeitet er in der Softwareentwicklung und dort an den unterschiedlichen NETWAYS Open Source Lösungen, insbesondere inGraph und im Icinga Team an Icinga Web. Darüber hinaus zeichnet er für viele Kundenentwicklungen in der Finanz- und Automobilbranche verantwortlich.

0 Kommentare

Einen Kommentar abschicken

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Mehr Beiträge zum Thema MySQL | PostgreSQL | MariaDB

PostgreSQL Einstieg unter openSUSE-Leap 15.2

da die meisten User sich zwar mit MySQL oder MariaDB auskennen, werde ich heute mal auf PostgreSQL eingehen, wie man dieses Paket installiert und ein paar Kommandos zur Verwaltung einer Datenbank. PostgeSQL ist von den Kommandos ähnlich wie zum Beispiel MariaDB. Sie...

Encoding „leicht gemacht“ mit PostgreSQL

In der Urzeit der Computerei passierte das alles in den USA. Und die Vereinigten Amerikaner haben seinerzeit wie üblich nicht über den Tellerrand geschaut, sondern ihren Zeichensatz an ihre Sprache angepasst (ASCII). Irgendwann "durften" dann auch die Alliierten ran,...

Alle User in MySQL anzeigen

Oftmals wachsen Datenbankinstallationen im Laufe der Zeit und man legt immer wieder für neue Projekte neue Datenbanknutzer an. Um hier den Überblick zu behalten, zeige ich kurz, wie man sich die jeweiligen Nutzer anzeigen lassen kann. Voraussetzungen: Command...