Problematiche di nazionalizzazione in Oracle

Oracle fornisce molteplici funzionalita' relative alla gestione dei set di caratteri nazionalizzati ed all'uso in multilingua. L'insieme delle funzionalita' e' garantito dal NLS (National Language Support) ed e' uno dei piu' avanzati e complessi presenti tra i diversi RDBMS poiche' Oracle ha sempre seguito con molta attenzione tutte le problematiche dell'i18n e della L10n.

Tra le diverse funzionalita' e' opportuno ricordare:

Quando viene creata una base dati oracle deve essere scelto il character set (detto anche Code Page) utilizzato per la memorizzazione dei dati. Inoltre possono essere scelti il linguaggio ed il territorio di default. Tali settaggi consentono il trattamento delle informazioni in modo consistente come dati e formati. In pratica questo vuol dire che le funzioni di gestione dei caratteri come la UPPER(), gli ordinamenti, la conversione delle date, ... funzionano esattamente come ci si aspetta!

Oracle effettua tutte le necessarie trasformazioni di dati necessarie se le impostazioni presenti sul client e sul server (RDBMS) sono differenti.

Oracle consente la definizione di differenti elementi:

Scelta dei parametri di nazionalizzazione

La scelta sui parametri di nazionalizzazione puo' essere effettuata a diversi livelli:

Ad esempio con il seguente settaggio di una variabile d'ambiente (su Unix in sh/ksh):

NLS_LANG=AMERICAN_AMERICA.WE8DEC
export NLS_LANG

si dichiara che si vuole utilizzare il linguaggio americano relativo al terriorio dell'america con il character set WE8DEC (che supporta i diversi caratteri speciali europei).
La definizione della variabile e' naturalmente specifica del sistema operativo (eg. setenv su Unix in cs, DEFINE su Digital VMS, valori nel registry HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\ORACLE_HOME\NLS_LANG su MS-Windows NT/95/98, , ...).

L'impostazione della variabile e' di notevole importanza poiche', se non impostata correttamente, Oracle effettua conversioni sui caratteri per garantire la consistenza delle informazioni.

Il modo in cui poi su terminale, su PC sull'applicazione vengono poi presentati i caratteri nazionalizzati e' simpaticamente sempre diverso!! Dipende appunto dalla configurazione dell'emulatore di terminale, dall'applicazione, ... (non tutti infatti trattano in modo corretto i caratteri a 8 o piu' bit).
Per controllare quanto effettivamente presente sulla base dati conviene percio' utilizzare le funzioni ASCII e CHR, scaricare gli output su un file e controllarli con un editor esadecimale, ... Tabelline ASCII e di decodifica sono anche molto comode.

Creazione di una base dati con uno specifico character set

Il caracter set di un'istanza viene definito al momento della creazione. In tal modo vengono definiti i tipi di caratteri che l'RDBMS supporta.

Ad esempio con:

create database "demo"
maxinstances 16
maxlogfiles  32
maxdatafiles 64
character set "WE8ISO8859P1"
datafile
 '/usr/oracle/dbs/sys01.dbf'        size 200M
logfile
 '/usr/oracle/dbs/log01.dbf'       size 20M,                             
 '/usr/oracle/dbs/log02.dbf'       size 20M,                             
 '/usr/oracle/dbs/log03.dbf'       size 20M,                             
 '/usr/oracle/dbs/log04.dbf'       size 20M;                    

viene creata la base dati "demo" che utilizza il character set latin1 come definito dallo standard ISO 8859 (tale character set copre la maggioranza dei linguaggi dell'europa occidentale). I "dettagli" sulla creazione di una nuova istanza esulano dal contenuto di questo documento.

Il caracter set e' una definizione a livello di istanza e non puo' essere variata (una eccezione e' riportata in Variazione del character set su un'istanza Oracle).

Versioni di Oracle

Oracle gestisce da sempre la nazionalizzazione dei caratteri, deve pero' essere sottolineato che con il cambiare di versione le modalita' e le funzionalita' possono cambiare in modo significativo. Le versioni piu' recenti sono ovviamente molto piu' complete delle prime versioni di Oracle.

Il supporto dell'NSL e' completamente differente tra la versione 6 e 7 dell'RDBMS Oracle. Per effettuare operazioni di import da una versione 6 della base dati puo' essere necessario utilizzare il parametro CHARSET.
Un significativo supporto delle funzioni di NLS e' stato introdotto dalla versione 7.0. Nella versione 7.3 sono state introdotte ulteriori funzionalita' ed il supporto per ulteriori character set (tra cui l'unicode).

Nelle versioni piu' recenti (9i R2) il National Language Support diventa il Database Globalization Support. A parte il nome sono parecchi gli aggiornamenti rispetto alle precenti versioni. Ecco l'elenco di quelle maggiormente significative, senza distinguere tra le versioni in cui sono state introdotte:

Variazione del character set su un'istanza Oracle

La definizione del character set deve essere effettuata al momento della creazione della base dati. E' tuttavia possibile, anche se la procedura non e' supportata e relativamente rischiosa (se si fa un errore si perde l'intera base dati) variare il character set di un'istanza gia' creata.

Per cambiare il character set e' sufficiente un'update come:

update sys.props$
set value$='WE8ISO8859P1'
where name='NLS_CHARACTERSET';
E quindi effettuare un reboot di Oracle.

Opportuno un salvataggio fisico completo della base dati prima dell'attivita' poiche' se si commette un errore o se vi sono incompatibilita' il DB non riparte piu'!!

ORDER BY ed NLS

L'ORDER BY di Oracle lavora in modo un po' piu' complesso di un semplice ordinamento basato sui codici ASCII. La ragione e' nel supporto completo della nazionalizzazione. Lettere come le vocali accentate (eg e ...) non possono essere ordinate utilizzando la codifica binaria ma in modo differente.

Per impostare l'ordinamento si utilizza la variabile d'ambiente NLS_SORT. Se questa non e' impostata il suo valore deriva dalla variabile NLS_LANGUAGE.
Se NLS_LANGUAGE e' AMERICAN NLS_SORT di default vale BINARY, quindi la sequenza (collation sequence) dipende dall'encoding (eg. ASCII o EBCDIC). Per molti altri linguaggi (eg. GERMAN, ITALIAN) vi e' una sequenza che prevede tutti i caratteri in ordine "alfabetico" ma case-insensitive e quindi i numeri. Per alcuni linguaggi esistono anche sequenze estese (eg. XGERMAN).
Un trucco semplice?

	SELECT 	*
	FROM 		TABELLA
	order by NLSSORT(ATTR, 'NLS_SORT = ASCII7');
oppure
	order by NLSSORT(ATTR, 'NLS_SORT = EBCDIC') ;
Una stranezza? Il GROUP BY lavora con NLS_SORT=BINARY a meno che non sia definito un ORDER BY. Per una descrizione tecnica completa un buon riferimento e' ML 29301.1

Linguaggi, territori e character set supportati

Il numero di linguaggi, territori e character set supportati da Oracle e' molto elevato (ed in continua crescita versione dopo versione). E' quindi opportuno far riferimento alla documentazione di prodotto per un riferimento preciso.

Sono infine supportati alcuni sistemi di calendario (eg. Thai Buddha).

Solo a titolo di esempio:
Linguaggio
American
English
Italian

Character SetNote
US7ASCIIASCII a 7 bit con caratteri nazionalizzati American
WE8DECDEC a 8 bit Europa occidentale
WE8ISO8859P1CP Standard ISO 8859 per l'Europa occidentale
EE8ISO8859P2CP Standard ISO 8859 per l'Europa orientale
CL8ISO8859P5CP Standard ISO 8859 cirillico
EL8ISO8859P7CP Standard ISO 8859 greco
AL16UTF16 Unicode a lunghezza fissa (nella versione 7.3 AL24UTFFSS)
UTF8Unicode con codifica a byte variabili.

Le funzioni che Oracle fornisce per la gestione della nazionalizzazione sono parecchie (basti pensare che anche i sort, tutte le funzioni di gestione delle date, ... sono interessati) e non e' il caso di riportarle singolarmente. Utile puo' essere la funzione di CONVERT che "traduce" tra character set differenti.

Standard, convenzioni e riferimenti

Sui character set sono stati definiti molteplici standard di diritto e/o di fatto.

Di sicuro interesse sono:

Vi sono parecchie altre versioni di character set. Tra gli altri non potevano certo mancare le innumerevoli tabelle utilizzate da Microsoft in Windows ed in tutti gli altri ambienti (eg. CP-1252). Le differenze rispetto a quanto definito dagli standard sono comunque limitate.

Sulla pagina UTF8 e' possibile trovare qualche ulteriore indicazione sulla codifica Unicode UTF-8. La pagina ufficiale che riporta tutte le code page di Unicode puo' essere consultata in Unicode 3.1. Una chiara documentazione ricca di riferimenti si trova in The ISO 8859 Alphabet Soup e Codepages & C. che sono un buon punto di partenza per ulteriori ricerche su Internet. [NdE questo documento e' stato scritto prima che nascesse wikipedia...]


Ecco qualche utile tabellina raccolta dalle sorgenti citate:

ASCII US

ISO 8859 P1 Latin1: West Europe

ISO 8859 P2 Latin2: East Europe

EBICDIC US

Code Page 437: IBM su PC

Code Page 850: IBM su PC con estensioni Latin1

Code Page 1252: MS Windows

 


Testo: Nazionalizzazione in Oracle

Data: 7 Febbraio 1999

Versione: 1.0.11 - 1 Maggio 2012

Autore: mail@meo.bogliolo.name