Caractère é transformé en é avec SAS/ACCESS interface to SQL Server
Tout développeur SAS a, au moins une fois dans sa vie, été confronté à l’affichage d’un é là où il s’attendait à voir un é.
Vous utilisez le module SAS/ACCESS interface to SQL server avec SAS dans un environnement linux ?
Vos données contiennent des caractères accentués (àéèçù) ?
Vos données apparaissent correctement dans SQL Server ?
Dans votre session SAS, les àéèçù sont transformés en à éÚçù ?
Pourquoi et comment résoudre cet problème ?
Mon champ Name contient bien "élémentaire"
Maintenant, affichons le contenu de cette table dans SAS Enterprise Guide :
On commence par soumettre une instruction libname pour créer la connexion à la base de données :
Puis affichons le contenu de la table :
Ce qui donne :
LANG=en_US.UTF-8
Voici quelques exemples de valeurs pour LANG :
Dans notre exemple :
Notre base de données utilise une page de code basé sur l'alphabet latin. Hors, Notre système Linux utilise l'enconding UTF-8.
Hors la table de codage UTF-8 n'est pas la même que la table de codage Latin.
En hexadécimale, ma chaîne de test "élémentaire" est la suivante :
e9 6c e9 6d 65 6e 74 61 69 72 65
Si j'utilise
la table de codage latin pour convertir cette chaîne Hexa, j'obtiens :
Maintenant si j’utilise la table de codage de ma session Linux, c'est à dire UTF-8, voici le résultat :
Il n'existe pas de caractère UTF-8 associé au code hexa "e9.
En UTF-8, l'accent é est codé sous c3 a9 (LETTRE MINUSCULE LATINE E AIGU). UTF-8 encode certains caractères, dont les lettres accentuées, sur deux octets (0xC3 et 0xA9)
Aussi, dans une session UTF-8, sans transcodage, l'affichage de l'accent n'est pas possible.
La séquence d’octets 0xE9.0x6C, qui code
Examinons maintenant le résultat dans SAS Enterprise Guide :
élémentaire, non ?
Convertisseur hexadécimal en utf8
Une histoire de "page de code"
Votre base de données utilise une page de code basé sur l'alphabet latin (contenant les 191 caractères de l’alphabet latin, chacun d’entre eux étant codé sur un octet, soit 8 bits). Une page de code est un standard informatique qui vise à donner un numéro à chaque caractère d'une langue, ou de quelques langues proches. Elle constitue donc une méthode simple de pratiquer du codage des caractères. J'ai abordé ce sujet à plusieurs reprises sur ce site (SAS et UTF-8 – L’option DBCLIENT_MAX_BYTES) Pour comprendre, nous allons partir d'un exemple simple. Comme indiqué en introduction, votre base de donnée utilise une page de code basé sur l'alphabet latin. :
1 |
select * from oldservices; |
1 |
libname sql17dbo odbc dsn="MSQLSERVER17" user="utilisateurSQL" password="password" schema=dbo; |
Pourquoi ?
Question simple. Réponse simple. Regardons les paramètres régionaux de l'os sur lequel est exécuté la session SAS. La plupart des systèmes UNIX ou Linux utilisent la variable LANG pour spécifier les paramètres régionaux souhaités. Affichons la valeur de cette variable dans notre sessions Linux (via du code SAS) :
1 |
%put LANG=%sysfunc(sysget (LANG)); |
1 2 3 |
fr_CH.utf8 # Langue française, Suisse, codage UTF-8 fr_CA.utf8 # Langue française, Canada, codage UTF-8 en_US.utf8 # Langue anglaise, États-Unis, codage UTF-8 |
e9 | 6c | e9 | 6d | 65 | 6e | 74 | 61 | 69 | 72 | 65 |
é | l | é | m | e | n | t | a | i | r | e |
e9 | 6c | e9 | 6d | 65 | 6e | 74 | 61 | 69 | 72 | 65 |
l | m | e | n | t | a | i | r | e |
él
en latin-1, est invalide en UTF-8.
Quelle solution ?
Pour résoudre ce problème, vous l'avez compris, il faut que votre session soit dans la même page de code que votre base de données. Dans notre cas, nous allons positionner la variable d'environnement LANG à fr_FR.ISO-8859-1 (Latin1). Il faut bien sûr également utiliser SAS en français. Pour cela, ajoutons l'export de cette variable dans le fichier sasenv_local de SAS (install/SASFoundation/9.4/bin/sasenv_local) :
1 |
export LANG=fr_FR.ISO-8859-1 |