Aspekte zur Character Semantik Tilo Henke Senior Berater Oracle Berlin DOAG Regionaltreffen Berlin Brandenburg 10.12.2003
Motivation Web Clients 5. Response 1. Request LDAP OID + Portal Repository WE8ISO8859P1 4. DB Zugriff via DB Link 2. SSO + 3. Run Portlets 9iAS Portal UTF-8
Motivation E-Mail Zeichensatz Hinweis: Diese Nachricht wurde Ihnen im Unicode-Format (UTF-8) uebermittelt. Sollten bestimmte Zeichen nicht korrekt dargestellt werden, so finden Sie Einstell- bzw. Update-Moeglichkeiten Ihres Mail-Readers unter http://www.unicode.org/unicode/standard/translations/german.html. Auf Wunsch senden wir Ihnen diese Mail auch gerne im "Western"-Format erneut zu. "Unicode gibt jedem Zeichen seine eigene Nummer - platformunabhängig, programmunabhängig, sprachunabhängig" Oracle Magazine otn.oracle.com/oramag March/April 2003
Byte oder Character Ist 'x' ein Byte oder ein Character egal in Single-Byte CharSet Umgebungen nicht egal in Multi-Byte CharSet Umgebungen Byte - Speichereinheit Character - Symbol einer Sprache declare y varchar2(3); begin y := 'äöü'; -- ORA-06502 value error in UTF-8 end; /
Byte- oder Character Semantik Strings fester Länge erscheinen variabel Ursache: Vermengung von Byte- und Character Semantik -- Ergebnis in UTF-8 (WE8ISO8859P1) declare x char(3); -- Deklaration im Sinne von Bytes begin -- Zugriff im Sinne von Character x := 'a'; dbms_output.put_line(length(x)); -- Ergebnis 3 (3) x := 'ä'; dbms_output.put_line(length(x)); -- Ergebnis 2 (3) end; / Konfusion ab 9i beendet VARCHAR2(3 BYTE) -- Byte Semantik VARCHAR2(3 CHAR) -- Char Semantik (UTF-8 z.b. allokiert 9 Byte)
Byte- und Character Semantik SQL> declare 2 x char(9 BYTE); 3 begin 4 x := 'aaaaaaaaa'; 5 dbms_output.put_line(length(x)); -- Ergebnis 9 (9) 6 x := 'ääää'; 7 dbms_output.put_line(length(x)); -- Ergebnis 5 (9) 8 end; 9 / SQL> declare 2 x char(3 CHAR); 3 begin 4 x := 'aaa'; 5 dbms_output.put_line(length(x)); -- Ergebnis 3 (3) 6 x := 'äää'; 7 dbms_output.put_line(length(x)); -- Ergebnis 3 (3) 8 end; 9 /
Character Semantik Wir denken in CHAR: - beim Deklarieren von Strings - bei der Berechnung der Länge - bei der Suche, bei Teilstrings, Stringdeklarationen (Tabellen, PL/SQL - Variablen, embedded SQL - Variablen) in Char Semantik erhöhen die Portabilität der Applikation bzw. des DB - Schemas zwischen den CharSet Welten CHAR(3 CHAR) VARCHAR2(8 CHAR)
L ngen Semantik SQL> declare 2 x char(3); 3 begin 4 x := 'äa'; 5 dbms_output.put_line(instr(x,'a')); -- Ergebnis 2 (2) 6 dbms_output.put_line(length(x)); -- Ergebnis 2 (3) 7 dbms_output.put_line(substr(x,1,1)); -- Ergebnis ä (ä) 8 end; 9 / SQL> declare 2 x char(3); 3 begin 4 x := 'äa'; 5 dbms_output.put_line(instrb(x,'a')); -- Ergebnis 3 (2) 6 dbms_output.put_line(lengthb(x)); -- Ergebnis 3 (3) 7 dbms_output.put_line(substrb(x,3,1)); -- Ergebnis a ( ) 7 dbms_output.put_line(substrb(x,1,2)); -- Ergebnis ä (äa) 8 end; 9 /
Migration / Portierung VARCHAR(n) > VARCHAR(3n) ist genauso trostlos wie VARCHAR(n) > VARCHAR(n CHAR) NLS_LENGTH_SEMANTICS = CHAR/BYTE auf Instanz- oder Sessionebene (sho parameters nls, NLS_INSTANCE_PARAMETERS) Export / Import CHAR(3) wird nun interpretiert als CHAR(3 CHAR) auch für PL/SQL - Code, aber: externes SQL beachten und überhaupt: Sorgfalt
Migration / Portierung Parameter gilt nur für neu erstellte Objekte und wirkt nicht dynamisch SQL> alter session set NLS_LENGTH_SEMANTICS=byte; SQL> create table T_Byte(a varchar2(8)); SQL> alter session set NLS_LENGTH_SEMANTICS=char; SQL> create table T_Char (a varchar2(8)); SQL> desc t_byte A VARCHAR2(8 BYTE) SQL> desc t_char A VARCHAR2(8) SQL> alter session set NLS_LENGTH_SEMANTICS=byte; SQL> desc t_byte A VARCHAR2(8) SQL> desc t_char A VARCHAR2(8 CHAR)
Q U E S T I O N S A N S W E R S