SAS et UTF-8 – L’option DBCLIENT_MAX_BYTES
Lorsque vous travaillez dans une session SAS UTF-8 et que vous récupérez des données depuis une base de données distante elle-même en UTF-8, vous avez sans doute constaté que l’espace alloué pour stocker les données de type varchar est plus important que la taille du champ varchar source. Ce qui n'est pas le cas, si votre session est, par exemple, en LATIN.
Ce comportement est en rapport avec le codage des données UTF-8.
Le codage des données consiste en un jeu de caractères, c’est-à-dire la liste des caractères susceptibles d'être représentés par le codage. Il peut être :
Si j’accède à cette table dans une session SAS dont l’enconding est en latin (ANSI) , nous constatons que l’espace alloué pour le champs transaction_id est de 32 octets :
Avec l’encoding latin, chaque caractère est encodé sur 1 seul octet. Dans la mesure où ANSI utilise uniquement un octet ou 8 bits, il ne peut représenter qu’un maximum de 256 caractères.
Maintenant, si j’accède à cette table dans une session SAS UTF-8, nous constatons que l’espace alloué pour le champ transaction_id est de 96 octets. SAS alloue 3 octets par caractères :
En effet , lorsque SAS accède à une base de données dont le codage est en UTF-8., SAS va allouer 3 octets par caractère UTF-8 afin de s’assurer qu’il pourra accéder à la chaîne complète. L’allocation se fait au moment de la création de la table. SAS ne connait pas les données qu’il va devoir charger dans cette table. Il a donc besoin d’allouer suffisamment d’espace pour pouvoir stocker l’intégralité des données encodé en UTF-8.
Cette valeur peut toutefois être modifiée pour certaines bases de données (Amazon Redshift, Aster, DB2 under UNIX and PC Hosts, Impala, MySQL, Oracle, PostgreSQL, Teradata, Vertica) . Cela peut être intéressant si vous êtes certains que vos données, malgré l’UTF-8, ne contiennent que des données dont les caractères ne sont codés que sur 1 octet unique.
Il est donc possible d'utiliser l'option DBCLIENT_MAX_BYTES. Cette option est à positionner au niveau de l'instruction LIBNAME.
Si DBCLIENT_MAX_BYTES = 1, seuls les caractères à un octet sont pris en charge. Pour les caractères multi-octets, il est recommandé de définir une valeur supérieure à 1. Pour le codage de session SAS UTF-8, définissez DBCLIENT_MAX_BYTES = 3.
Attention, ces deux options doivent être testée pour déterminer quelle valeur est la plus judicieuse par rapport aux caractères stockés : si certains dépassent l’octet (comme le symbole euro par exemple) alors il faut garder 3 octets pour s’assurer d’afficher tous les caractères.
Dans le cas de mon exemple, si je positionne l'option DBCLIENT_MAX_BYTES à 1, mon champ transaction_id n'utilise plus qu'un octet par caractère :
Sources :
Implementing a Unicode Solution in the Database ( documentation Oracle)
The Impact of Change from wlatin1 to UTF-8 Encoding in SAS Environment
SAS® and UTF-8: Ultimately the Finest.
COMPRENDRE L’OPTION ENCODING DANS SAS
Problématique encoding : Traiter les données en provenance de tables SGBD, via un module SAS/Access
- Simple (Single Byte Character Set – SBCS ). Le SBCS prend en charge un maximum de 256 symboles. Il est utilisé par les langues ne comportant pas beaucoup de symboles ou de lettres accentuées, tels que les latin, grec ou cyrillique.
- Double (Double Byte Character Set – DBCS ). Le DBCS est utilisé pour stocker du texte dans une langue asiatique utilisant des idéogrammes. Par exemple, le codage de caractères Shift-JIS pour la langue japonaise utilise de Double Byte Character Set.
- Multiple (Multi Byte Character Set – MBCS ou appelé aussi Variable-width encoding)



