Erfahrungsbericht: Unicode in der Datenbank

Werbung
Erfahrungsbericht: Unicode in der
Datenbank
Dierk Lenz
13. Juli 2011
DOAG Regio NRW
Herrmann & Lenz Services GmbH
• Gegründet 1995
• Firmensitz: Burscheid (bei Leverkusen)
• Beratung, Anwendungsentwicklung, Schulung
und Betrieb/Fernwartung rund um das Thema
Oracle Datenbanken
• Schwerpunktthemen: Hochverfügbarkeit, Tuning,
Migrationen und Troubleshooting
• Produkt: Monitoring Module
• Viele DOAG-Aktivitäten
Erfahrungsbericht: Unicode in der
Datenbank
2
Was ist Unicode?
Erfahrungsbericht: Unicode in der
Datenbank
3
Wenn nicht mehr alle Sonderzeichen
in die DB passen…
• …dann nimmt man Unicode!
– Standardisierter Zeichensatz (s.a.
http://www.unicode.org)
• Verschiedende Kodierungen
– Fest oder variabel lang
– Minimallänge 8, 16 oder 32 Bit
• Oft verwendet: UTF-8 (variabel, Minimum
8 Bit, Maximum 32 Bit)
Erfahrungsbericht: Unicode in der
Datenbank
4
Unicode ist KEINE Oracle-Spezialität
• Wird z.B. verwendet
– in der Linux-Shell
– unter Windows (manchmal, z.B. in .Net)
• Verschiedene Kodierungen (UTF-8, UTF-16,
UTF-32) und Versionen:
– UTF8 entspricht ab Oracle 8.1.7 UTF-8 Version 3.0
– AL32UTF8 entspricht mit Oracle 10.2 UTF-8
Version 4.0, mit Oracle 11 Version 5.0
Erfahrungsbericht: Unicode in der
Datenbank
5
Wozu verschiedene Kodierungen?
• UTF-8 ist für Europa sehr gut geeignet: ASCIIZeichen bleiben bei 1 Byte, Umlaute usw.
2 Byte.
• Indische Zeichen (Devanagari) belegen in UTF8 3 Byte, in UTF-16 2 Byte.
Erfahrungsbericht: Unicode in der
Datenbank
6
Wo stellt man das in Oracle ein?
• Datenbank:
CREATE DATABASE
…
CHARACTER SET AL32UTF8;
• Client:
NLS_LANG=American_Germany.AL32UTF8
Erfahrungsbericht: Unicode in der
Datenbank
7
Einige Fakten
• Unicode-DB und Non-Unicode-Client ist
ebenso möglich wie Non-Unicode-DB und
Unicode-Client!
– Es werden immer nur die Zeichen richtig
behandelt, die in beiden Zeichensätzen (DB und
Client) vorkommen.
• Beim Laden von Daten muss als ClientZeichensatz der Zeichensatz des
Datenbestands angegeben werden.
Erfahrungsbericht: Unicode in der
Datenbank
8
Clients an Unicode-DBs
• Wenn der Client z.B. einen WE8-Zeichensatz
nutzt, arbeitet der Client mit Zeichen aus
diesem Zeichensatz korrekt.
• Somit könnte man z.B. für eine
Adressverwaltung Arbeitsplätze für
Westeuropa, Osteuropa usw. einrichten.
• Vorsicht: Osteuropäischer Name und Wohnort
Köln geht dann nicht…
Erfahrungsbericht: Unicode in der
Datenbank
9
Also: Wozu Unicode?
• Mit Unicode kann jedes erdenkliche Zeichen in
den Character-Feldern (VARCHAR2, CHAR,
CLOB) einer Datenbank gespeichert werden!
• Der Preis dafür ist, dass – zumindest einige –
Zeichen länger als 1 Byte sind.
Erfahrungsbericht: Unicode in der
Datenbank
10
Eigentlich alles ganz einfach…
Erfahrungsbericht: Unicode in der
Datenbank
11
Kann man den Zeichensatz einer
Datenbank auf Unicode ändern?
• Ja, wenn Unicode eine strikte Obermenge des
vorhandenen Zeichensatzes ist!
• Wann ist Zeichensatz B eine strikte Obermenge
von Zeichensatz A? Zwei Bedingungen:
1. Jedes in A kodierte Zeichen muss in B ebenfalls
vorhanden sein (B Obermenge von A)
2. Jedes in A kodierte Zeichen muss in B den gleichen
Codepoint haben.
• Damit fallen praktisch alle Zeichensätze außer
US7ASCII durch!
• Eine Migration (Export/Import) ist notwendig!
Erfahrungsbericht: Unicode in der
Datenbank
12
Was heißt eigentlich VARCHAR2(n)?
• CREATE TABLE uctab1
( c VARCHAR2(6))
/
• Antwort könnte sein: Bytes oder Zeichen!
• Standard: Bytes (!)
• Explizite Angabe möglich
– VARCHAR2(6 BYTE)
– VARCHAR2(6 CHAR)
Erfahrungsbericht: Unicode in der
Datenbank
13
Standardverhalten (NLSLängensemantik)
• Ohne Angabe:
NLS_LENGTH_SEMANTICS = BYTE | CHAR
• Bestimmt lediglich Längensemantik beim
Anlegen von Objekten.
• Kein Einfluss auf Laufzeitverhalten
Erfahrungsbericht: Unicode in der
Datenbank
14
Was passiert bei Export/Import (von
Non-Unicode nach Unicode)?
• Die verwendete Längensemantik wird
übernommen!
• Z.B. Data Pump Import:
ORA-02374: conversion error loading table
"UC"."UCTAB1"
ORA-12899: value too large for column C (actual:
7, maximum: 6)
ORA-02372: data for row: C : 0X'4DDC4C4C4552'
• Bei Byte-Semantik werden eventuell
Datensätze nicht übernommen
Erfahrungsbericht: Unicode in der
Datenbank
15
Mögliche Auswege
1. Ändern der Längensemantik in der Quell-DB
– Evtl. Auswirkungen auf laufende Anwendungen
– Widerspricht dem Motto
Never change a running system!
2. Importieren in modifizierte Tabellen
–
–
–
–
–
Z.B. Generieren von CREATE TABLE-Skripten
Modifikation der Längensemantik
Einspielen der Skripte
Import in modifizierte Tabellen
Erstellen der restlichen Strukturen (Indizes,
Constraints, …)
Erfahrungsbericht: Unicode in der
Datenbank
16
Zweites Problem
• CHAR-Längensemantik angegeben
• Trotzdem wieder ORA-12899: value too large
for column…
• Grund: Harte Maximallänge (4000 Bytes für
VARCHAR2, 2000 Bytes für CHAR)
• Kreative Lösungen gefragt:
– Kürzen von Feldinhalten
– Umstieg auf CLOB
Erfahrungsbericht: Unicode in der
Datenbank
17
Hat meine Datenbank solche
Probleme?
• Antworten liefert u.a. das Database Character
Set Scanner Utility CSSCAN.
• Die besten Antworten liefert eine
Testmigration.
Erfahrungsbericht: Unicode in der
Datenbank
18
CLOB und Unicode
• CLOB- (und NCLOB-) Daten sind bei Multi-ByteZeichensätzen immer UCS-2-kompatibel kodiert
(wenn DB-Zeichensatz UTF8 oder AL32UTF8)
• UCS-2: 16 Bit-Kodierung, feste Länge, Vorgänger
von UTF-16
• CLOBS verdoppeln ihre Größe bei der UnicodeMigration!
• Apropos NCLOB: N-Datentypen werden nicht
mehr benötigt!
Erfahrungsbericht: Unicode in der
Datenbank
19
Programmieren mit Unicode
Erfahrungsbericht: Unicode in der
Datenbank
20
Programmierte Objekte
• Prozedur mit folgendem Code:
CREATE OR REPLACE PROCEDURE ucproc1
AS
vc VARCHAR2(6);
BEGIN
FOR r IN (SELECT c FROM uctab1)
LOOP
vc := r.c;
END LOOP;
END;
/
• Lässt man das auf einer Unicode-Umgebung laufen, passiert u.U.
folgendes:
ORA-06502: PL/SQL: numeric or value error:
character string buffer too small
ORA-06512: at "UC.UCPROC1", line 7
Erfahrungsbericht: Unicode in der
Datenbank
21
PL/SQL Lösung
• Fortgeschrittene PL/SQL-Programmierer
kennen zur Deklaration
vc VARCHAR2(6);
die – sehr empfehlenswerte – Alternative
vc uctab1.c%TYPE;
Damit erbt der PL/SQL-Code die CHAR-Semantik der
Tabelle – keine Anpassung notwendig!
• Eine Überarbeitung des Codes ist oft
notwendig.
Erfahrungsbericht: Unicode in der
Datenbank
22
Server-Einstellung
NLS_LENGTH_SEMANTICS
BYTE
• Sollte bei Patches/Upgrades
immer eingestellt sein.
• Somit die gefahrlosere
Einstellung.
CHAR
• Setzt den Standard für
Sessions auf den Unicodekompatiblen Wert.
• Besser für vergessliche
Entwickler.
Erfahrungsbericht: Unicode in der
Datenbank
23
Entwicklungsumgebungen
• Umgebungsvariable NLS_LENGTH_SEMANTICS
auf CHAR
• Session-Voreinstellung auf CHAR
• Skripte immer mit
ALTER SESSION SET
nls_length_semantics = char;
erzeugen!
• Größter Aufwand bei besten Ergebnissen:
Explizites Setzen der CHAR-Semantik bei jeder
Deklaration!
Erfahrungsbericht: Unicode in der
Datenbank
24
Allgemeine Hinweise
• Dokumentation: Globalization Support Guide
• Neu auf Oracle Technology Network: Oracle
Migration Assistant for Unicode
http://www.oracle.com/technetwork/database/globalization/dmu/overview/index.html
Erfahrungsbericht: Unicode in der
Datenbank
25
Noch Fragen?
• http://www.hl-services.de
• [email protected]
Erfahrungsbericht: Unicode in der
Datenbank
26
Herunterladen