!
!
!
!
!
!
!
!

NLS


NLS
Préambule
Le cycle de vie des données dans une base Oracle est constitué globalement par leur insertion (saisie), stockage et consultation. Les acteurs concernés sont le client (saisie/consultation) et le serveur (stockage/saisie/consultation). Les jeux de caractères ASCII (7 ou 8 bits) et EBCDIC sont largement utilisés pour représenter l’alphabet latin mais certaines langues utilisent des milliers de caractères qui nécessitent l’utilisation de deux octets (16 bits) ou plusieurs.
Le National Language Support (NLS) d’ORACLE permet d’interagir avec la base de données et d’exécuter des applications dans des environnements linguistiques multiples, que les jeux de caractères soient sur un ou plusieurs octets. NLS permet également d’effectuer des opérations dépendantes de la langue telles que :
  • Les messages ORACLE.
  • Les dates.
  • Les nombres (Unité monétaire, point décimal, séparateur des milliers, etc).
  • Les tris.

Le stockage des données

Le stockage des données se fait de manière binaire (évident), chaque caractère alphanumérique ayant une codification binaire établie une fois pour toutes à la création de la base (character set, national character set pour une deuxième langue). Nous parlons d’une table de caractères de la base de données. Une des requêtes qui montrent la table des caractères utilisée dans base est :
SQL> col name for a25
SQL> col value$ for a15
SQL> col comment$ for a25
SQL> SELECT * FROM sys.props$ WHERE name LIKE 'NLS%CHARACTERSET%';
NAME                      VALUE$          COMMENT$
------------------------- --------------- -------------------------
NLS_CHARACTERSET          WE8MSWIN1252    Character set
NLS_NCHAR_CHARACTERSET    AL16UTF16       NCHAR Character set
Dans le cas présenté, la table de caractères principale est spécifique à l’environnement Windows.

Représentation des codes dans la base

La représentation alphanumérique des codes de la table des caractères de la base est donnée par
set serveroutput on
declare
  i number;
  j number;
  k number;
begin
  for i in 2..15 loop
    for j in 1..16 loop
      k:=i*16+j;
      dbms_output.put((to_char(k,'000'))||':'||chr(k)||' ');
      if k mod 8 = 0 then
        dbms_output.put_line('');
      end if;
    end loop;
  end loop;
end;
Pour une base (set de caractères WE8MSWIN1252) :
NAME                      VALUE$          COMMENT$
------------------------- --------------- -------------------------
NLS_CHARACTERSET          WE8MSWIN1252    Character set
129:  130:‚  131:ƒ  132:„  133:…  134:†  135:‡  136:ˆ
137:‰  138:Š  139:‹  140:Œ  141:  142:Ž  143:  144:
145:‘  146:’  147:“  148:”  149:•  150:–  151:—  152:˜
153:™  154:š  155:›  156:œ  157:  158:ž  159:Ÿ  160: 
161:¡  162:¢  163:£  164:¤  165:¥  166:¦  167:§  168:¨
169:©  170:ª  171:«  172:¬  173:­  174:®  175:¯  176:°
177:±  178:²  179:³  180:´  181:µ  182:¶  183:·  184:¸
185:¹  186:º  187:»  188:¼  189:½  190:¾  191:¿  192:À
193:Á  194:Â  195:Ã  196:Ä  197:Å  198:Æ  199:Ç  200:È
201:É  202:Ê  203:Ë  204:Ì  205:Í  206:Î  207:Ï  208:Ð
209:Ñ  210:Ò  211:Ó  212:Ô  213:Õ  214:Ö  215:×  216:Ø
217:Ù  218:Ú  219:Û  220:Ü  221:Ý  222:Þ  223:ß  224:à
225:á  226:â  227:ã  228:ä  229:å  230:æ  231:ç  232:è
233:é  234:ê  235:ë  236:ì  237:í  238:î  239:ï  240:ð
241:ñ  242:ò  243:ó  244:ô  245:õ  246:ö  247:÷  248:ø
249:ù  250:ú  251:û  252:ü  253:ý  254:þ  255:ÿ  256:
et pour une autre (WE8ISO8859P15) :
NAME                      VALUE$          COMMENT$
------------------------- --------------- -------------------------
NLS_CHARACTERSET          WE8ISO8859P15   Character set
129:¿  130:¿  131:¿  132:¿  133:¿  134:¿  135:¿  136:¿
137:¿  138:¿  139:¿  140:¿  141:¿  142:¿  143:¿  144:¿
145:¿  146:¿  147:¿  148:¿  149:¿  150:¿  151:¿  152:¿
153:¿  154:¿  155:¿  156:¿  157:¿  158:¿  159:¿  160: 
161:¡  162:¢  163:£  164:€  165:¥  166:Š  167:§  168:š
169:©  170:ª  171:«  172:¬  173:­  174:®  175:¯  176:°
177:±  178:²  179:³  180:Ž  181:µ  182:¶  183:·  184:ž
185:¹  186:º  187:»  188:Œ  189:œ  190:Ÿ  191:¿  192:À
193:Á  194:Â  195:Ã  196:Ä  197:Å  198:Æ  199:Ç  200:È
201:É  202:Ê  203:Ë  204:Ì  205:Í  206:Î  207:Ï  208:Ð
209:Ñ  210:Ò  211:Ó  212:Ô  213:Õ  214:Ö  215:×  216:Ø
217:Ù  218:Ú  219:Û  220:Ü  221:Ý  222:Þ  223:ß  224:à
225:á  226:â  227:ã  228:ä  229:å  230:æ  231:ç  232:è
233:é  234:ê  235:ë  236:ì  237:í  238:î  239:ï  240:ð
241:ñ  242:ò  243:ó  244:ô  245:õ  246:ö  247:÷  248:ø
249:ù  250:ú  251:û  252:ü  253:ý  254:þ  255:ÿ  256:
Nous remarquons les différences au delà du code ASCII 128
Attention, le résultat affiché dépend du . . . client qui effectue la requête !


La consultation et la saisie des données (configuration du client)

La consultation et la saisie des données passe par une interprétation (traduction) des caractères en fonction de la table de caractères du client (du poste client). Dans une base gérée par une table de caractères quelconque, des données peuvent être insérées/consultées a partir d’une autre table de caractères, dans quel cas Oracle effectuera une conversion automatique si possible.
Quand un client se connecte à la base, une session qui fonctionne en environnement local/table de caractères dictées par les paramètres d’initialisation de la base. Si le client provient d’une connexion gérée par une variable NLS_LANG (locale au client), un alter session implicite est effectuée par Oracle, ce sont les paramètres NLS du client qui seront utilisés.
Les systèmes d'exploitation de Microsoft utilisent leurs propres jeux de caractères (En Français, l’environnement graphique est géré par le code page 1252, sous DOS par le code page 850. Une conversion doit avoir lieu entre le client et le serveur (Si les deux codes sont identiques, la conversion n’est pas effectuée).
La table de caractères du poste client est gérée par la variable d’environnement NLS_LANG.
Sous Windows 2000, cette variable est située dans la base de registre sous HKLM/Software/Oracle (ou dans chaque ORACLE_HOME). Renseigner la valeur de la clé NLS_LANG avec FRENCH_FRANCE.WE8MSWIN1252 ("Western European 8bit MS Windows Code Page 1252".

Traduction client/serveur/client

Comment tester la validité du couple client/serveur ? En vérifiant que le code du caractère visualisé sur le poste client est le même que le code du caractère transformé client/serveur/client !
La requête suivante convertit un caractère dans le sens client/serveur et ensuite dans le sens serveur/client. Si le résultat final (dans notre cas le symbole EURO) est différent de celui initial, le couple des tables de caractères est inutilisable (le caractère en question sera perdu lors des traductions successives).
select 
dump(convert(convert(chr(128),'WE8ISO8859P15','WE8MSWIN1252'),
             'WE8MSWIN1252','WE8ISO8859P15'))
from dual;

Fonctionnement local

Le NLS Oracle est implémenté avec Oracle NLS Runtime Library (NLSRTL). Cette bibliothèque de fonctions assure une manipulation cohérente des langues gérées par la base. Le comportement spécifique de ces fonctions est assuré par les paramètres régionaux. Quand une base est démarrée, un ensemble de paramètres régionaux est chargé.
L’ensemble des paramètres locaux utilisés dans une base se trouve dans le répertoire indiqué par la variable ORA_NLS (ORA_NLS33 en 8i et 9i). Historiquement, le répertoire est $ORACLE_HOME/ocommon/nls/admin/data.

Tables de caractères

Oracle permet de stocker, saisir et sélectionner les données dans la langue du client. Aujourd’hui la table UNICODE (UTF8) permet de stocker d’une manière unitaire des données de la plupart des alphabets actuels.

Scripts
Influence NLS sur la base, l’instance et la session
Le script suivant montre les divers paramètres NLS présents pour la base, l’instance et la session :
SQL> select
  2  d.parameter
  3  ,d.value "Base"
  4  ,i.value "Instance"
  5  ,s.value "Session"
  6  from nls_database_parameters d
  7  , nls_instance_parameters i
  8  , nls_session_parameters s
  9  where d.parameter=i.parameter(+)
 10  and d.parameter=s.parameter(+)
 11  ;
PARAMETER                 Base            Instance        Session
------------------------- --------------- --------------- ---------------
NLS_CALENDAR              GREGORIAN                       GREGORIAN
NLS_CHARACTERSET          WE8ISO8859P15
NLS_COMP                  BINARY                          BINARY
NLS_CURRENCY              $                               ñ
NLS_DATE_FORMAT           DD-MON-RR                       DD/MM/RR
NLS_DATE_LANGUAGE         AMERICAN                        FRENCH
NLS_DUAL_CURRENCY         $                               ñ
NLS_ISO_CURRENCY          AMERICA                         FRANCE
NLS_LANGUAGE              AMERICAN        AMERICAN        FRENCH
NLS_LENGTH_SEMANTICS      BYTE            BYTE            BYTE
NLS_NCHAR_CHARACTERSET    AL16UTF16
NLS_NCHAR_CONV_EXCP       FALSE           FALSE           FALSE
NLS_NUMERIC_CHARACTERS    .,                              ,.
NLS_RDBMS_VERSION         9.2.0.2.0
NLS_SORT                  BINARY                          FRENCH
NLS_TERRITORY             AMERICA         AMERICA         FRANCE
NLS_TIMESTAMP_FORMAT      DD-MON-RR HH.MI                 DD/MM/RR HH24:M
                          .SSXFF AM                       I:SSXFF
NLS_TIMESTAMP_TZ_FORMAT   DD-MON-RR HH.MI                 DD/MM/RR HH24:M
                          .SSXFF AM TZR                   I:SSXFF TZR
NLS_TIME_FORMAT           HH.MI.SSXFF AM                  HH24:MI:SSXFF
NLS_TIME_TZ_FORMAT        HH.MI.SSXFF AM                  HH24:MI:SSXFF T
                          TZR                             ZR
Les diverses valeurs possibles des paramètres locaux :
SQL> select parameter, value
  2  from   x$ksulv
  3  ;
PARAMETER                 VALUE
------------------------- ------------------------------
LANGUAGE                  AMERICAN
LANGUAGE                  GERMAN
LANGUAGE                  FRENCH
. . .
TERRITORY                 FINLAND
TERRITORY                 ICELAND
. . . 
Modifier les paramètres NLS de la base
Il est possible de aisément modifier au delà de la 8i le set de caractères de la base si le nouveau set de caractères est un 'superset' du vieux:
SQLPLUS> STARTUP MOUNT; 
SQLPLUS> ALTER SYSTEM ENABLE RESTRICTED SESSION; -- (ou equivalent)
SQLPLUS> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0; 
SQLPLUS> ALTER SYSTEM SET AQ_TM_PROCESSES=0; 
SQLPLUS> ALTER DATABASE OPEN; 
SQLPLUS> ALTER DATABASE CHARACTER SET YYYY; 
SQLPLUS> SHUTDOWN IMMEDIATE;   
SQLPLUS> STARTUP;
Bibliographie
Les manuels Oracle
L’excellentissime ouvrage de TRIVADIS :
http://www.trivadis.ch/publikationen/F/eurocomp_fr.pdf
Stats
Compteur


Copyright © 1998-2002 Radu Caulea, TAFORA MAJ 06/11/2006 !
Commentaires et suggestions radu[CHEZ]tafora.fr