Inhaltsverzeichnis

Informix: Codeset, Collation und deutsche Umlaute

Ziel und Rahmen

Diese Notiz beschreibt die operative Ursache von Problemen mit deutschen Umlauten in Informix aus Sicht eines System- oder Datenbankadministrators. Der Schwerpunkt liegt nicht auf der Sprachtheorie, sondern auf den tatsächlichen Betriebsebenen:

Wichtig: In Informix sind Codeset und Collation getrennte Konzepte. Eine falsche Annahme, sie seien identisch oder austauschbar, erzeugt die typischen Umlaut-Fehler.


1. Locale-Architektur in GLS

Informix verwendet GLS (Global Language Support). Eine Locale hat die Form:

Sprache_Territorium.Codeset[@Modifikator]

Typische Beispiele:

Die Bestandteile bedeuten:

Das Entscheidende:


2. Codeset vs. Collation: die zentrale Trennung

2.1 Codeset

Der Codeset beschreibt, welche Bytes in der Datenbank für ein Zeichen verwendet werden. Beispiel für ISO-8859-1 / IBM CCSID 819:

In UTF-8 dagegen sind dieselben Zeichen mehrere Bytes, beispielsweise:

Das bedeutet: Die logische Rune „ü“ kann in verschiedenen Codesets als unterschiedliche Bytefolge erscheinen. Deshalb ist der tatsächliche Fehler oft ein Encoding-Mismatch, nicht ein Unicode-Problem der Datenbank selbst.

2.2 Collation

Die Collation beschreibt, wie Zeichen verglichen und sortiert werden. Sie betrifft SQL-Regeln wie:

Ein Modifikator wie @dict ändert nicht das gespeicherte Byte für ü, sondern nur die Reihenfolge, in der Zeichen als vergleichbar bzw. sortierbar behandelt werden.

Praktisch:


3. DB_LOCALE und CLIENT_LOCALE

Der Ablauf ist immer:

Anwendung → CLIENT_LOCALE → GLS-Konvertierung → DB_LOCALE → Datenseite / Chunk

3.1 CLIENT_LOCALE

CLIENT_LOCALE beschreibt die Zeichenkodierung, mit der die Anwendung die Zeichen an den Server sendet. Ein Client kann Latin-1, UTF-8, UCS-2 oder ein anderer von GLS unterstützter Codeset verwenden.

3.2 DB_LOCALE

DB_LOCALE beschreibt den Codeset der Datenbank selbst. Sobald die Daten in die Datenbank gelangen, werden sie im DB-Codeset gespeichert. Die Datenbank selbst kennt nur diese interne Byte-Repräsentation.

3.3 Konvertierung

Wenn Client und Datenbank unterschiedliche Codesets verwenden, führt Informix eine Konvertierung durch. Das ist genau die Stelle, an der viele Fehler entstehen.

Beispiele:

Das ist genau die Ursache, wenn im Feld plötzlich „ü“ oder andere verzerrte Zeichen auftauchen.


4. Warum @dict kein Encoding-Problem ist

Der häufigste Fehler im operativen Umgang ist die falsche Gleichsetzung von Collation und Encoding.

Korrekt:

Falsch:

Diese Annahmen sind technisch falsch.

Beispiel:

Wenn Umlaute in einer Datenbank falsch erscheinen, ist der Fehler in der Regel nicht @dict, sondern:


5. Was auf der Platte wirklich liegt

Informix speichert im Regelfall keine abstrakten „Buchstaben“, sondern Bytefolgen im DB-Codeset. Für 819 gilt:

Wer in einer 819-DB einen Ausdruck wie 'Müller' speichert, speichert in Wirklichkeit eine Bytefolge wie:

Das ist nicht UTF-8, keine kombinierende Darstellung und kein „U+00FC plus Trema“ in einem Zeichensatz-Container. Es ist einfach das DB-Byte.

Das ist der Kernpunkt für Betrieb und Diagnose:


6. Einfluss auf Länge, LIKE, Substring und Unique

Die Collation beeinflusst nicht die physische Bytefolge, aber sie wirkt auf die Semantik.

6.1 LENGTH und Substring

Bei 819 ist ein deutsches Zeichen ein einzelnes Byte. Ein Wert wie 'Müller' hat in einer 819-DB eine andere Byte-Länge als in einer UTF-8-DB.

Das ist operational wichtig:

6.2 LIKE und Vergleichslogik

Collation beeinflusst, wie SQL-Engines Zeichen als „gleich“ oder in einer Reihenfolge behandeln. Damit können Werte in WHERE, ORDER BY, BETWEEN und Unique-Prüfungen unterschiedlichen Vergleichsergebnissen unterliegen, obwohl die gespeicherten Bytes identisch sind.

Dieser Effekt ist besonders deutlich bei:

Bei CHAR und VARCHAR richtet sich die normale Vergleichsreihenfolge grundsätzlich nach der Codeset-Reihenfolge; ein in der Locale definierter Modifikator wie @dict kann die Sortierregeln beeinflussen. NCHAR und NVARCHAR verwenden die lokalisierte Kollationsreihenfolge der Datenbank-Locale. Die genaue Wirkung hängt von DB_LOCALE und dessen Collation ab; deshalb sollten Sortierung und Vergleiche mit den tatsächlich verwendeten Datentypen getestet werden.

Je nach Locale und Kollationsregeln können ß und ss beziehungsweise Ä und Ae oder A beim Sortieren ähnlich oder gleich gewichtet werden. Eine ähnliche Sortierposition bedeutet jedoch nicht automatisch, dass die Werte bei = oder in einem Unique-Index als gleich gelten. Diese Fälle separat mit ORDER BY, Gleichheitsvergleichen und gegebenenfalls einem Test-Unique-Index prüfen.

6.3 Unique-Index und Replikation

Wenn die Collation zwei Werte als gleich behandelt, kann ein Unique-Index den zweiten Datensatz ablehnen, obwohl die Bytefolgen auf den ersten Blick unterschiedlich aussehen. Das ist ein Kollationsproblem, kein Codepage-Problem.

Dasselbe gilt bei Replikation und ER: Die Vergleichssemantik und die lokale DB-Locale der beteiligten Kataloge und Tabellen müssen für die beteiligten Datenbanken konsistent sein. Eine scheinbar reine Sortierfrage kann sich als Vergleichs-/Katalogproblem zeigen.

Ändert eine logische Migration die Locale oder die zugrunde liegenden Vergleichsregeln, müssen die Indizes in der Zieldatenbank unter diesen Regeln angelegt werden. Vorhandene Indexstrukturen nicht ungeprüft übernehmen: nach dem Import die betroffenen B-Tree-Indizes und Unique-Bedingungen kontrollieren und sie bei Bedarf mit dem für die Informix-Version vorgesehenen Verfahren neu aufbauen, notfalls durch Löschen und erneutes Anlegen. Eine physische Wiederherstellung derselben Datenbank-Locale ist davon zu unterscheiden.


7. Typische Betriebssymptome

7.1 Mojibake

Beispiel: Ein Client sendet UTF-8-C3-BC, der Server erwartet 819, und die Daten werden als zwei falsche Latin-1-Bytes interpretiert. Ergebnis: Zeichen wie ü, ä, ö oder ähnliches.

Typische Ursache:

7.2 Abgeschnittene Strings

Wenn UTF-8-Sequenzen in einen 819-Server oder umgekehrt in die falsche Definition geraten, können die Zeichen als ungültig oder unvollständig interpretiert werden. Das führt zu:

7.3 Falscher Sortier-/Eindeutigkeitsfehler

Diese Fälle sind häufig ein Kollationsproblem:


8. Relevante operative Regeln

8.1 Die Besonderheit: Collation wird beim CREATE DATABASE fixiert

Die entscheidende Eigenschaft von Informix-GLS ist: Die Locale der Datenbank, inklusive der Collation, wird beim CREATE DATABASE in die Datenbankstruktur eingepflanzt und bleibt für die Existenz der Datenbank relevant. Das gilt nicht nur für den Sprach-Default, sondern auch für die Vergleichs- und Sortiersemantik der DB.

Das bedeutet praktisch:

Dies ist der Grund, warum eine „Collation-Korrektur“ nachträglich nicht einfach über eine Environment-Variable oder einen einmaligen SET-Block erfolgen kann. Sobald die DB mit einem bestimmten Codeset und einer bestimmten Collation angelegt wurde, ist die physische und semantische Grundlage der Datenbank damit fixiert.

8.2 Warum Environment-Änderungen keine Korrektur sind

Die häufige falsche Annahme lautet: „Ich ändere DB_LOCALE oder CLIENT_LOCALE und die DB sortiert dann anders.“ Das ist nur für neue Verbindungen und neue Konvertierungen relevant, nicht für die bereits in der Datenbank gespeicherten Bytes und nicht für die bereits definierte DB-Locale.

Das ist ein wichtiger Punkt:

Kurz gesagt: Environment-Variablen sind nur die Konvertierungs- und Verbindungslogik; sie sind keine Definition der bereits gespeicherten DB-Semantik.

8.3 Die Abhängigkeit zwischen CLIENT_LOCALE, DB_LOCALE und Collation

Die operative Abhängigkeit ist:

Wenn diese drei Seiten nicht zusammenpassen, ist der Effekt:

8.4 Warum eine Korrektur oft nur über neue DB oder Migration geht

Wenn eine DB mit dem falschen Codeset oder falscher Collation erstellt wurde, dann ist das Problem nachträglich nicht nur eine Frage der aktuellen Umgebung. Die logische Ursache liegt in der zu früh festgelegten DB-Locale und im fehlenden konsistenten Client-/Server-Codepfad.

In der Praxis ist die saubere Korrektur meist:

Bei dbexport/dbimport die erzeugte Schema-Datei im Exportverzeichnis vor dem Import prüfen. Sie kann das ursprüngliche CREATE DATABASE-Statement und damit die bisherige Locale enthalten; nicht ungeprüft annehmen, dass dbimport automatisch die gewünschte Ziel-Locale verwendet. Falls nötig, den Datenbankkopf in der Schema-Datei auf die Zieldefinition anpassen. DB_LOCALE muss zur Ziel-Datenbank passen; CLIENT_LOCALE muss beim Export und Import jeweils zur tatsächlichen Kodierung der Textdateien passen. Nach dem Import Daten, Collation-Verhalten und neu angelegte Indizes verifizieren.

8.5 Praktischer DBA-Check: Host, Client und DB

Ein valider Admin-Workflow für die Diagnose sieht typischerweise so aus:

  1. Host-Umgebung prüfen
  1. Client-Umgebung prüfen
  1. DB-Locale prüfen
  1. Reale Daten prüfen
  1. Semantik prüfen

8.6 Diagnostische Unterscheidung: Codeset-Problem vs. Collation-Problem

Ein typischer Entscheidungsbaum:

→ wahrscheinliches Codeset-/Konvertierungsproblem

→ wahrscheinliches Collation-Problem

→ Collation oder Locale-Semantik ist die Ursache

→ codeset-/CLIENT_LOCALE-/DB_LOCALE-Mismatch

8.7 Zielgerichtete Korrekturstrategie

Im Betrieb sollte die Korrektur immer dem Ursachepfad folgen:

8.8 Betriebsregel in Kurzform

Wenn zwei dieser Ebenen nicht zusammenpassen, entstehen die typischen Probleme mit ä, ö, ü, ß und anderen Sonderzeichen.

8.9 Runbook: Symptom → Ursache → Prüfung → Korrektur

Symptom A: Zeichen werden als ü, ä, ö dargestellt

Ursache:

Prüfung:

locale
env | grep -E 'LANG|LC_|CLIENT_LOCALE|DB_LOCALE'
SELECT name, LENGTH(name) FROM TABLE_NAME WHERE name LIKE '%M%';

Korrektur:

export CLIENT_LOCALE=en_US.819
export DB_LOCALE=en_US.819

Falls die Datenbank bereits im falschen Codeset steht, keine reine Laufzeitkorrektur, sondern neue DB oder sauberer Transfer planen.

Symptom B: ORDER BY oder Unique zeigt falsche Reihenfolge

Ursache:

Prüfung:

SELECT col FROM tab ORDER BY col;
SELECT col, COUNT(*) FROM tab GROUP BY col HAVING COUNT(*) > 1;

Korrektur:

Symptom C: Import/Export zeigt Umlaute erst nach Transfer falsch

Ursache:

Prüfung:

file datafile
hexdump -C datafile | head

Korrektur:


9. Interner Runbook-Block

Problem

Umlaute oder Sonderzeichen werden im Informix-System falsch dargestellt, sortieren falsch oder erzeugen Unique-/Vergleichsfehler.

Ursache

Die häufigste Ursache ist keine fehlende Informix-Funktionalität, sondern ein Mismatch zwischen:

Prüfung

locale
env | grep -E 'LANG|LC_|CLIENT_LOCALE|DB_LOCALE'
SELECT name, VALUE
FROM sysmaster:sysdbslocale
WHERE name IN ('dbs_collate', 'dbs_cset');
SELECT col,
       LENGTH(col),
       col = 'Müller' AS eq_mueller,
       col = 'Muller' AS eq_muller
FROM tab
LIMIT 10;
SELECT col
FROM tab
ORDER BY col;
file exportfile
hexdump -C exportfile | head

Diagnose

Lösung

export CLIENT_LOCALE=en_US.819
export DB_LOCALE=en_US.819

Oder mit UTF-8:

export CLIENT_LOCALE=en_US.utf8
export DB_LOCALE=en_US.utf8

Wenn die Datenbank bereits mit einem falschen Codeset oder falscher Collation angelegt wurde:

CREATE DATABASE db_new WITH LOG
   DB_LOCALE = 'en_US.819@dict'
   CLIENT_LOCALE = 'en_US.819';

Danach Daten mit konsistenter Locale transferieren und die Ergebnisse erneut prüfen.

Verifikation

SELECT col,
       LENGTH(col),
       col = 'Müller' AS eq_mueller,
       col = 'Muller' AS eq_muller
FROM tab
ORDER BY col;
locale

Erwartung:


10. Diagnostik im Betrieb

Für den Admin ist die wichtigste Frage nicht „Ist @dict aktiv?“, sondern:

9.1 Richtige Prüfungen

Checkliste:

  1. DB-Locale mit Informationen zur Datenbank ermitteln.
  2. Client-Umgebung prüfen: Locale, Codeset, Terminal-/Applikationskette.
  3. Daten vor und nach Export/Import hexadezimal prüfen.
  4. Relevante String-Operationen gegen erwartete Bytewerte prüfen.
  5. Wenn die Datenbank ein Latin-1-Codeset verwendet, nachsehen, ob der Client tatsächlich Latin-1 liefert oder fälschlich UTF-8 behauptet.
  6. Sortier- und Vergleichsregeln separat prüfen, da @dict die Sortierung ändern kann, aber nicht das physische Zeichen selbst.

9.2 Beispielhafte Logik

Wenn ein ü in der Datenbank anstelle von UTF-8-C3-BC als FC auftaucht, ist der Speicher korrekt für 819. Wenn der Client aber UTF-8-Strings liefert und der Server 819 erwartet, entsteht ein Konvertierungsfehler. Das muss am Übergang korrigiert werden, nicht durch einen Collation-Wechsel.


10. 1-Seiten-Checkliste für den Betrieb

Kurzfassung

Schnellprüfung

locale
env | grep -E 'LANG|LC_|CLIENT_LOCALE|DB_LOCALE'
SELECT name, VALUE
FROM sysmaster:sysdbslocale
WHERE name IN ('dbs_collate', 'dbs_cset');

Entscheidungsregel

Korrektur

export CLIENT_LOCALE=en_US.819
export DB_LOCALE=en_US.819

Oder:

export CLIENT_LOCALE=en_US.utf8
export DB_LOCALE=en_US.utf8

Wenn die DB bereits falsch angelegt wurde:

CREATE DATABASE db_new WITH LOG
   DB_LOCALE = 'en_US.819@dict'
   CLIENT_LOCALE = 'en_US.819';

Verifikation

SELECT col,
       LENGTH(col),
       col = 'Müller' AS eq_mueller,
       col = 'Muller' AS eq_muller
FROM tab
ORDER BY col;

Erwartung:


11. IBM-Referenzen

Die folgenden IBM-Dokumentationsstellen sind die maßgeblichen offiziellen Referenzen für die Kernregeln von Informix GLS und Locales:

Hinweis: IBM-Dokumentation kann je nach Version und Produktseite leicht verlinkt werden; die oben genannten Referenzen sind die offiziellen Einstiegspunkte für die hier beschriebenen Funktionen.


11. Schlussfolgerung

Das entscheidende technische Ergebnis lautet:

Nur wenn Codeset, Collation und Client-Locale zusammenpassen, funktionieren ä, ö, ü, ß korrekt in Informix.


12. Konkrete Konfigurationsbeispiele

12.1 Typische Umgebungsvariablen

Beispiel für eine Linux-/bash-Umgebung, in der der Client als UTF-8 arbeitet und die DB als 819 erwartet:

export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
export CLIENT_LOCALE=en_US.utf8
export DB_LOCALE=en_US.819

Beispiel für eine Latin-1-/819-Spezifikation im Client:

export LANG=en_US.ISO8859-1
export LC_ALL=en_US.ISO8859-1
export CLIENT_LOCALE=en_US.819
export DB_LOCALE=en_US.819

Wichtig: Diese Werte sind nur richtig, wenn die Anwendung wirklich exakt in diesem Codeset arbeitet. Ein falscher oder „nur vermuteter“ Wert erzeugt echte Byte-Verzerrungen.

12.2 Beispiel für CREATE DATABASE mit fixierter Locale

CREATE DATABASE dbname WITH LOG
   IN dbspace1
   DB_LOCALE = 'en_US.819@dict'
   CLIENT_LOCALE = 'en_US.819'
   MODE ANSI;

Oder ebenfalls üblich:

CREATE DATABASE dbname WITH LOG
   DB_LOCALE = 'en_US.819'
   CLIENT_LOCALE = 'en_US.utf8';

Das ist der kritische Punkt: Nach dem CREATE DATABASE ist diese Locale für die DB fest. Ein späteres Setzen von CLIENT_LOCALE oder DB_LOCALE in der Shell ändert die bereits vorhandenen Daten nicht.

12.3 Beispiel für eine sichere SQL-Prüfung der DB-Locale

SELECT name, VALUE
FROM sysmaster:sysdbslocale
WHERE name IN ('dbs_collate', 'dbs_cset');

Wenn die DB definiert ist, zeigt die Datenbankkataloginformation, welcher Codeset und welche Collation für die DB gelten. Das ist der richtige Nachweis, nicht die aktuelle Shell-Umgebung.

12.4 Beispiel für einen Host-/Client-Check

echo "$LANG"
echo "$LC_ALL"
echo "$CLIENT_LOCALE"
echo "$DB_LOCALE"
locale

Prüfungen, die in der Praxis sinnvoll sind:

locale charmap
iconv --list | grep -Ei 'UTF-8|ISO-8859-1|IBM-819'

Wenn der Client als UTF-8 deklariert ist, aber tatsächlich Latin-1-Bytes ausliefert, ist die Konvertierung falsch, obwohl die Shell-Umgebung „gut“ aussieht.

12.5 Testbeispiele für Codeset und Umlaut

Beispiel A: Datenbank ist 819, Client ist korrekt als 819 gesetzt.

CREATE TABLE test_umlaut (
    id SERIAL,
    name VARCHAR(50)
);
 
INSERT INTO test_umlaut(name) VALUES ('Müller');
SELECT name, LENGTH(name) FROM test_umlaut;

Erwartung:

Beispiel B: Client liefert UTF-8, DB erwartet 819.

SET CLIENT_LOCALE 'en_US.utf8';
INSERT INTO test_umlaut(name) VALUES ('Müller');

Wenn die Client-Umgebung nicht exakt mit den tatsächlich gesendeten Bytes übereinstimmt, kann der String als falsche Bytefolge interpretiert werden. Der Gefahrensignal: sichtbare Verzerrung, Spracheingang fehlerhaft, Abweichungen bei LENGTH oder ORDER BY.

12.6 Test für Sortierung ohne Encoding-Wechsel

CREATE TABLE test_sort (
    id SERIAL,
    name VARCHAR(20)
);
 
INSERT INTO test_sort(name) VALUES ('Muller'), ('Müller'), ('Muller2');
SELECT name FROM test_sort ORDER BY name;

Erwartung:

12.7 Test für sichere Konvertierung bei Export/Import

Beispiel für einen Import-Workflow mit festem Client-Codeset:

export CLIENT_LOCALE=en_US.819
export DB_LOCALE=en_US.819
 
# Beispiel: Export mit konsistentem Format
# Danach Import in die Ziel-DB mit derselben DB_LOCALE

Wenn Import/Export mit widersprüchlichen Locales läuft, wird das Zeichenmaterial falsch geordnet oder verfälscht.

12.8 Typischer Verifikations-Block nach einer Änderung

SELECT name,
       LENGTH(name),
       name = 'Müller' AS match_1,
       name = 'Muller' AS match_2
FROM test_umlaut;
 
SELECT name
FROM test_sort
ORDER BY name;

Ziel dieser Prüfung:

12.9 Praktischer Entscheidungsbaum

1. Werden Zeichen verzerrt dargestellt?
   Ja -> Codeset-/Konvertierungsproblem prüfen
   Nein -> Sortier-/Collation-Problem prüfen
 
2. Sind Daten in DB bereits gespeichert?
   Ja -> DB_LOCALE und DB-Definition prüfen, kein bloßes SET erwartet
   Nein -> CREATE DATABASE / locale-Definition erneut prüfen
 
3. Ist CLIENT_LOCALE konsistent mit den tatsächlich gelieferten Bytes?
   Nein -> Client- oder Import-Fehler
   Ja -> DB_LOCALE prüfen
 
4. Ist ORDER BY / LIKE / Unique inkonsistent?
   Ja -> Collation und @dict prüfen
   Nein -> auf Export/Import oder Anwendungskodierung schauen

12.10 Betriebskorrektur in der Praxis

Minimaler, robuster Ablauf:

# 1. Umgebung prüfen
locale
env | grep -E 'LANG|LC_|CLIENT_LOCALE|DB_LOCALE'
 
# 2. Ziel-DB mit korrekter Locale anlegen
# CREATE DATABASE ... DB_LOCALE = 'en_US.819@dict'
 
# 3. Client auf dieselbe Semantik stellen
export CLIENT_LOCALE=en_US.819
 
# 4. Daten transferieren, danach Byte- und Vergleichsprüfungen durchführen

Wichtig: Wenn die vorhandene DB bereits im falschen Codeset bzw. mit falscher Collation erstellt wurde, ist eine reine Laufzeit-Umstellung meistens keine saubere Lösung. Dann ist eine neue, korrekt definierte DB oder eine glasklare Migration die belastbare Korrektur.


13. Schlagwörter

Informix, GLS, Locale, DB_LOCALE, CLIENT_LOCALE, Codeset, Collation, @dict, ISO-8859-1, CCSID-819, Latin-1, UTF-8, Unicode, deutsche Umlaute, äöüß, Byte-Repräsentation, Datenbankspeicher, ORDER BY, BETWEEN, LIKE, Unique-Index, String-Länge, Substring, Mojibake, dbload, UNLOAD, Import, Export, Replication, ER, Encoding, Character Conversion, Client-Server-Konvertierung, Datenbankadministrator, Troubleshooting, CREATE DATABASE, locale-check, hex-dump, shell-environment