Tipps & Tricks: November 2005 Bereich: DBA, SQL Erstellung: 11/2005 CK Versionsinfo: 8.1, 9.2, 10.2, 11.1 Letzte Überarbeitung: 06/2009 HW Zeichensätze im Wandel (National Language Support) Daten werden auf unterster Ebene als Bitmuster verarbeitet und gespeichert. Da macht auch die Oracle-Datenbank keine Ausnahme. Ein Bitmuster ist eine Folge aus Nullen und Einsen. Verschiedene Arten von Nutzdaten, z. B. Zahlen oder Zeichenketten, werden auf unterschiedliche Weise in solche Bitmuster umgesetzt. Für jeden so genannten Datentyp wird festgelegt, wie Werte auf der Bit-Ebene dargestellt werden sollen. Betrachten wir die alphanummerischen Zeichen, aus denen Zeichenketten (Strings) zusammengesetzt werden. Jedem Zeichen wird zunächst willkürlich ein eindeutiges Bitmuster zugeordnet. Diese Zuordnung nennt man Character-Set. Weil diese Zuordnung willkürlich ist, gibt es natürlich viele verschiedene solcher Character-Sets mit den unterschiedlichsten Namen (z. B. WE8ISO8859P1, WE8MSWIN1252 etc.). Bereits beim Erzeugen einer Datenbank wird festgelegt, welcher Character-Set für die Speicherung von Zeichen zu verwenden ist. Diese Festlegung gilt für die gesamte Lebensdauer der Datenbank und kann nur unter bestimmten Voraussetzungen nachträglich noch einmal geändert werden. Weil nun verschiedene Datenbank-Clients von ganz unterschiedlichen Plattformen auf unsere Datenbank zugreifen, ist bei Ein- und Ausgabe von Zeichen möglicherweise eine Umsetzung erforderlich. Auch auf den Client-Plattformen werden Bitmuster für die darzustellenden Zeichen verwendet, die in einem Character-Set definiert sind. Vor der Übertragung eines Zeichens vom Client zur Datenbank wird das Client-Bitmuster durch das für dieses Zeichen in der Datenbank verwendete Datenbank-Bitmuster ersetzt. Umgekehrt wird nach der Übertragung eines Zeichens von der Datenbank zum Client das Datenbank-Bitmuster durch das zugehörige Client-Bitmuster ersetzt. Nur wenn Oracle-Client und Oracle-Datenbank exakt denselben Character-Set verwenden, entfällt die Umsetzung. Diese Umsetzung führt der Oracle-Client durch. Voraussetzung für die richtige Umsetzung ist, dass der Oracle-Client weiß, mit welchem Character-Set sein System arbeitet. Diese Information entnimmt der Client einer Umgebungsvariablen mit dem Namen NLS_LANG. Ist diese Variable nicht definiert oder mit einem falschen Character-Set belegt, kommt es zu fehlerhaften Umsetzungen. Das führt im harmloseren Fall des Lesezugriffs zu einer unkorrekten Darstellung von Zeichen. Umlaute sind z.B. nicht mehr lesbar. Werden dagegen falsch umgesetzte Zeichen in die Datenbank geschrieben, entstehen Fehler, die nur noch manuell korrigierbar sind. Die in diesem Fall in der Datenbank gespeicherten Bitmuster sind nicht mehr von denen zu unterscheiden, die von korrekt arbeitenden Clients eingetragen worden sind. Deshalb ist es absolut notwendig, die korrekte NLS_LANG-Einstellung auf jedem Client vorzunehmen. Das kann im Environment geschehen (Unix-Systeme) oder in der Registry (Windows-Systeme). NLS_LANG Ein NLS_LANG-Eintrag besteht aus mehreren Komponenten: NLS_LANG=<Language>_<Territory>.<clients characterset> Muniqsoft GmbH Schulungszentrum, Grünwalder Weg 13a, 82008 Unterhaching, Tel. 089 / 679090-40 IT-Consulting & Support, Witneystraße 1, 82008 Unterhaching, Tel. 089 / 6228 6789-0 Seite 1 von 3 Language Steuert die Sprache, in welcher Meldungen ausgegeben werden, beeinflusst die Sortierreihenfolge sowie Monatsund Tagesbezeichnungen. Hat jedoch keinerlei Einfluss auf die speicherbaren Zeichen. Territory Steuert Währung, Datums- und Zeitformat, Dezimaltrennzeichen, ebenfalls keinerlei Einfluss auf die speicherbaren Zeichen. Clients characterset Hier wird der vom Client verwendete Character-Set eingetragen. Beispiel: NLS_LANG=GERMAN_GERMANY.WE8MSWIN1252 NLS_LANG auf Windows-Systemen NLS_LANG kann unter Windows entweder als Environment-Variable oder in der Registry unter HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE/HOMEn/NLS_LANG gesetzt werden. Die eigene "Quelle" kann folgendermaßen geprüft werden (auch ohne Zugriff auf die Registry): a) Environment-Variable Im DOS-Fenster (MS-DOS Eingabeaufforderung): C:\>echo %NLS_LANG% Falls NLS_LANG als Environment-Variable definiert wurde, wird nun der Inhalt angezeigt, ansonsten nur %NLS_LANG% b) Registry Man startet ein sqlplus-Fenster (z.B. mit sqlplus /nolog) und führt dort z.B. folgenden Befehl aus: SQL> @.[%NLS_LANG%] Jetzt kommt eine Fehlermeldung, die in etwa so aussieht: SP2-0310: Datei ".[GERMAN_GERMANY.WE8MSWIN1252]" konnte nicht geöffnet werden Dieser Wert ist dann aus der Registry gekommen. Welche Zeichensätze sind nun empfehlenswert? Wichtig ist vor allen Dingen, dass man auf seinem Client den Zeichensatz (per NLS_LANG) einstellt, der dort auch vom OS verwendet wird. Denn nur dann macht Oracle die Umsetzung korrekt. Es gibt übrigens die Möglichkeit, abzufragen, welche Zeichensätze aus Sicht der Datenbank VALID sind. Muniqsoft GmbH Schulungszentrum, Grünwalder Weg 13a, 82008 Unterhaching, Tel. 089 / 679090-40 IT-Consulting & Support, Witneystraße 1, 82008 Unterhaching, Tel. 089 / 6228 6789-0 Seite 2 von 3 Das SQL-Statement dazu lautet: select unique VALUE from V$NLS_VALID_VALUES where PARAMETER ='CHARACTERSET'; Welcher Zeichensatz auf dem Server beim Erstellen der Datenbank verwendet wird, ist eine andere Frage. Wird nur mit einer Sorte Clients gearbeitet, kann man den Zugriff etwas beschleunigen, indem man die Datenbank mit dem Client-Zeichensatz anlegt. Wird dann die NLS_LANG wiederum richtig eingestellt, so erkennt Oracle, dass es hier nichts konvertieren muss und spart sich den Schritt und uns die Zeit. Wie kann man den Zeichensatz wechseln? a) Serverseitiger Datenbank-Zeichensatz Prinzipiell wird der Zeichensatz bereits beim Erzeugen der Datenbank festgelegt und dann auch lebenslänglich verwendet. Wollte man ihn später ändern, so müssten dazu alle Datenbestände aktualisiert werden. Das geht über Export, Neuanlegen der Datenbank mit dem neuen Zeichensatz und dann Import. Zeichensatzwechsel auf Datenbankseite ist mit Einschränkungen auch mit folgenden Anweisungen möglich: ALTER DATABASE CHARACTER SET AL32UTF8; ALTER DATABASE NATIONAL CHARACTER SET AL32UTF8; Wenn nur Zeichen der gleichen Code-Page verwendet werden, kein Problem, sonst ... NO RISK NO FUN ... But NO SUPPORT! Das Oracle Utility cscan unterstützt bei der Konvertierung. b) Client-seitig Hier gibt es keinen "Wechsel" in dem Sinn. Wie oben beschrieben muss die NLS_LANG-Einstellung zu der tatsächlich auf dem Client verwendeten Codepage passen. Fazit Bevor ein Datenbank-Client in Betrieb genommen wird, muss unbedingt die korrekte NLS_LANG-Einstellung ermittelt und vorgenommen werden. Sie enthält den im Client verwendeten Character-Set, nicht den der Datenbank. Versäumnisse an dieser Stelle führen zu Fehlern im Datenbestand (logische Datenkorruptionen), die nur noch mühsam manuell korrigiert werden können. Mit noch offenen Fragen wenden Sie sich bitte vertrauensvoll an uns. Muniqsoft GmbH Schulungszentrum, Grünwalder Weg 13a, 82008 Unterhaching, Tel. 089 / 679090-40 IT-Consulting & Support, Witneystraße 1, 82008 Unterhaching, Tel. 089 / 6228 6789-0 Seite 3 von 3