Suite

Erreur d'encodage ASCII lors de la mise à jour du contenu du champ dans la table SQL Server


Je sais qu'il existe de nombreux articles et explications de blog sur les erreurs Unicode, mais je n'arrive toujours pas à comprendre comment les gérer dans mon cas particulier. Voici donc mon problème : j'écris un script Python pour mettre à jour des enregistrements dans une table SQL Server, avec le contenu de champ d'un fichier de formes qui a été modifié dans ArcPad.

j'utilise unarcpy.da.UpdateCursorpour mettre à jour les enregistrements existants.

j'ai mis# -*- codage : cp1252 -*-en plus de mon script car je travaille avec des personnages français. En faisant cela, j'obtiens l'erreur d'encodage ASCII :

Le codec 'ascii' ne peut pas coder les caractères en position 0-1 : l'ordinal n'est pas dans la plage (128)

j'ai essayé de mettrevousavant le contenu du champ :

… avec arcpy.da.UpdateCursor(DBtable, DBFields, where_clause) comme DBCur : pour DBrow dans DBCur :… DBrow[8] = u"{} - {}: {}".format(DBrow[8], date , AProw [8]) # AProw provient d'un SearchCursor qui lit le shapefile.

Je peux ensuite imprimer un message avec le contenu du texte, et il ne renvoie pas de message d'erreur, mais tous les caractères sont remplacés (j'obtiens quelque chose comme???4???5????????>???5???dans mon champ de base de données).

Tout caractère accentué ou de ponctuation peut être présent dans les champs (il y a un champ de commentaire de texte libre) donc je ne veux pas vérifier tous les caractères non ASCII possibles et les remplacer.

Je travaille avec ArcGIS 10.2.2, le shapefile est édité dans ArcPad 10.2 et la base de données est SQL Server 2008 R2.

Qu'est-ce que je rate?

EDIT : cela ne se produit que si la base de données de destination est SQL Server. Pas de problème avec un fichier gdb. Je dois ajouter que la table SQL Server contient déjà des caractères non-ASCII.


Enfin, j'ai trouvé une solution en apportant toutes les modifications suivantes à mon code :

  • utiliserarcpy.ArcSDESQLExecute()à la place dearcpy.da Insertion/Mise à jour des curseurspour mettre à jour/remplir la table (je devais faire les deux opérations et les deux types de curseurs ne fonctionnaient pas vraiment dans toutes les situations).

  • utiliser# -*- codage:utf8 -*-au début du script, ce qui est de toute façon censé être une bonne pratique (# -*- codage : cp1252 -*-me permet d'avoir des accents dans les messages mais ne fonctionne pas pour éditer la table de base de données). Maintenant, les accents dans mes messages sont remplacés, mais l'édition de ma base de données fonctionne.

  • il y avait également un problème avec les guillemets simples reconnus comme délimiteurs de chaîne dans ma requête SQL. Pour faire face à cela, j'ai dû les remplacer par double Guillemets simples.

Alors maintenant, mon code ressemble à ceci:

new_comment = "{} - {} : {}".format(DBrow[8].replace("'", """).encode('utf-8'), date , AProw[8]replace("' ", """).encode('utf-8')) # DBrow[8] est le commentaire déjà présent dans le tableau et AProw[8] est le nouveau commentaire de mon shapefile édité dans ArcPad… sde_conn = arcpy.ArcSDESQLExecute (DB) sql="update {} set {} = '{}".format(DBtable, DBcomment_field, new_comment)

J'espère qu'un jour cela pourra aider quiconque rencontre ce genre de casse-tête unicode/SQL Server.


Pas de valeur NULL, mais séquence d'octets non valide pour l'encodage &ldquoUTF8&rdquo : 0x00

J'ai passé les 8 dernières heures à essayer d'importer la sortie de 'mysqldump --compatible=postgresql' dans PostgreSQL 8.4.9, et j'ai déjà lu au moins 20 fils de discussion différents ici et ailleurs sur ce problème spécifique, mais je n'ai trouvé aucun vraie réponse utilisable qui fonctionne.

Serveur PostgreSQL 8.4.9 comme destination

Le chargement des données avec 'psql -U rt_user -f foo' génère un rapport (beaucoup d'entre eux, voici un exemple) :

Selon ce qui suit, il n'y a aucun caractère NULL (0x00) dans le fichier d'entrée.

De même, une autre vérification avec Perl ne montre aucun NULL :

Comme le "CONSEIL" dans l'erreur le mentionne, j'ai essayé toutes les manières possibles de définir "client_encoding" sur "UTF8", et j'y parviens, mais cela n'a aucun effet sur la résolution de mon problème.

À moins de la bonne réponse "Selon Hoyle", ce qui serait fantastique à entendre, et sachant que je ne me soucie vraiment pas de conserver des caractères non ASCII pour ces données rarement référencées, quelles suggestions avez-vous ?

Mise à jour : j'obtiens la même erreur avec une version ASCII uniquement du même fichier de vidage au moment de l'importation. Vraiment époustouflant :

L'une des tables en question est définie comme :

Je n'ai pas la liberté de changer le type pour n'importe quelle partie du schéma DB. Cela interromprait probablement les futures mises à niveau du logiciel, etc.

La colonne à problème probable est « contenu » de type « texte » (peut-être d'autres dans d'autres tables également). Comme je le sais déjà d'après des recherches précédentes, PostgreSQL n'autorisera pas NULL dans les valeurs 'texte'. Cependant, veuillez voir ci-dessus où sed et Perl n'affichent aucun caractère NULL, puis plus bas où je supprime tous les caractères non ASCII de l'intégralité du fichier de vidage, mais cela continue de bourdonner.


1 réponse 1

SQL Server ne stocke en aucun cas UTF-8. Vous obtenez soit UTF-16 Little Endian (LE) via NVARCHAR (y compris NCHAR et NTEXT , mais n'utilisez jamais NTEXT ) et XML , soit un codage 8 bits, basé sur une page de code, via VARCHAR (y compris CHAR et TEXT , mais n'utilisez jamais TEXT ).

Le problème ici est que votre code traduit mal ce caractère 0x82, pensant que c'est UTF-8, mais ce n'est pas le cas. Il n'y a pas de "caractère" UTF-8 ayant une valeur de 0x82, c'est pourquoi vous obtenez le symbole "inconnu" / de remplacement de " ". Veuillez consulter le tableau UTF-8 suivant qui montre qu'il n'y a pas de caractère pour un seul octet de 0x82 :

Comme indiqué par l'OP, le classement de la colonne en question est SQL_Latin1_General_CP1_CI_AS , ce qui signifie que le codage 8 bits utilise la page de code 1252, qui est Windows Latin 1 (ANSI). Et en vérifiant ce graphique (faites défiler jusqu'au graphique du bas car il contient les noms de caractères) la valeur 0x82 (recherchez "82" dans la colonne "Code Point") est en fait le guillemet unique Low-9 que vous voyez dans SSMS. Ce caractère, en UTF-8, est une séquence de 3 octets : E2 80 9A .

Ce que tout cela signifie, c'est que votre code Python doit soit définir le codage client pour la connexion SQL Server sur la page de code 1252, soit modifier/convertir le codage de la chaîne renvoyée. de Page de codes 1252 à UTF-8.

Bien sûr, si cela est affiché sur une page Web, alors vous pourrait changez le jeu de caractères déclaré de la page en Windows-1252 , mais cela pourrait interférer avec d'autres caractères de la page s'il y a déjà des caractères UTF-8.


Injection SQL via Unicode

Mon équipe utilise actuellement ASP.NET avec MS SQL Server pour notre logiciel. La sécurité n'est devenue importante que depuis que j'ai commencé, dans laquelle il y a des vulnérabilités d'injection partout.

En raison de l'intégration actuelle avec Oracle et MS SQL, la décision commerciale a été de ne jamais utiliser de requêtes paramétrées. Cela a bien sûr été un problème.

La mise en œuvre de la fonction Rechercher et remplacer ainsi que la liste blanche des paramètres ont fortement réduit ce problème.

Mon seul problème est que j'ai beaucoup lu sur l'unicode et d'autres encodages qui sont à l'origine de l'injection SQL. Je ne comprends pas bien cela. Actuellement, nous désinfectons tout comme ceci :

Quelqu'un a-t-il un exemple où l'injection unicode/codée pourrait être utilisée, ou juste un exemple simple où cette expression régulière ne parviendrait pas à empêcher l'injection SQL.

Puis-je s'il vous plaît ne pas avoir de réponses liées à l'injection SQL standard. Je suis déjà très familier avec cela. AUSSI, veuillez arrêter de publier en disant de ne pas utiliser la désinfection des chaînes. Il n'y a aucune ressource dans l'entreprise pour déplacer toutes les requêtes vers des requêtes paramétrées avec ADO.NET tout en intégrant également une logique pour qu'elle utilise ODP.NET si le client utilise Oracle. L'OWASP mentionne l'utilisation de la liste blanche des caractères si le paramétrage est hors de question, donc comme dans le regex, seuls quelques caractères sont autorisés. Je ne mets pas les personnages sur une liste noire, car c'est stupide.

Aucune conformité n'est requise pour les données que nous détenons. La sécurité est pour l'intégrité de la base de données, car ce serait un cauchemar si le contenu était modifié.

Notre logiciel est une très grande application cloud CMS et DMS en un, où 99% du logiciel est utilisé en interne, et seule une minorité est externe et n'est utilisée que pour l'examen public et les commentaires sur les documents.

De ma nouvelle compréhension de l'injection Unicode. Cela ne peut se produire que si les données sont encodées avant d'être placées dans la requête, et donc l'injection Unicode ne se produit vraiment que dans les applications avec globalisation des données. Je passe des champs de chaîne bruts directement dans la requête de chaîne après la désinfection ci-dessus.

Puis-je s'il vous plaît n'avoir qu'une réponse d'un expert en injection, qui peut appuyer mon affirmation selon laquelle Unicode ne s'appliquera pas dans ma situation ?


4 réponses 4

D'après les commentaires, le problème ne vient pas exactement de la table ou de la façon dont SQLCMD importe les caractères spéciaux. Habituellement, les importations problématiques sont liées au format du script lui-même.

Management Studio lui-même offre la possibilité d'enregistrer avec un encodage spécifique, ce qui devrait résoudre le problème à l'avenir. Lorsque vous enregistrez un fichier pour la première fois (ou utilisez enregistrer sous), vous devez cliquer sur la petite flèche près du Sauvegarder bouton, pour utiliser l'option Enregistrer avec encodage.

Par défaut, il enregistre le fichier dans Europe occidentale (1252). Chaque fois que j'ai des caractères spéciaux, j'utilise UTF8 (bien qu'un autre codage restrictif convienne peut-être) car c'est généralement la solution la plus rapide.

Je ne suis pas sûr (d'après la photo) que vous utilisez SSMS, alors assurez-vous que votre propre éditeur a la possibilité d'enregistrer le fichier dans un encodage différent. Sinon, la conversion du fichier dans un éditeur intelligent (comme vous l'avez déjà essayé dans Notepad++) fonctionne généralement. Bien que cela puisse ne pas fonctionner si vous passez d'un codage large à un codage plus étroit, puis de nouveau à un codage large (par exemple, d'Unicode à ANSI et de nouveau à Unicode).

Une autre option, que je viens d'apprendre, vient de la documentation sqlcmd. Vous devez définir la page de codes de sqlcmd pour qu'elle corresponde à celle du codage du fichier. Dans le cas de l'UTF-8, la page de codes est 65001, vous voudrez donc :

SQLCMD -S .MSSQLSERVER08 -V 17 -E -i %

dp0databaseCreationLog.log -f 65001

Ce genre de chose est très délicat parce que tant de choses se font sans vous le dire.

La première chose que je ferais serait d'utiliser sqlcmd pour afficher la chaîne. S'il s'affiche correctement dans la fenêtre cmd.exe, c'est un fait utile. Ensuite, je sélectionnerais la ligne convertissant la chaîne en varbinary pour voir quels octets s'y trouvent réellement. je pense cartographie apparaîtra sous la forme 0x636172746f67726166c3ad61 , où le "i" accentué est représenté par les octets c3ad, qui est l'encodage UTF-8 pour ce caractère. Ce n'est pas bon d'avoir UTF-8 dans une colonne espagnole moderne (Windows 1252). La valeur d'octet dans Windows 1252 pour ce caractère est 237 décimal (hex ED).

Si la colonne contient des données mal codées, l'erreur réside dans la façon dont elle a été insérée. Peut-être que la suppression du N de tête dans les constantes de chaîne - N'string' indique à SQL Server de générer une chaîne Unicode, mais 'string' brut indique que les caractères utilisent l'encodage du client - insèrerait l'espagnol moderne au lieu d'Unicode.

Si la colonne contient des données correctement codées, je dirais que vous avez trouvé un bogue dans l'affichage de l'interface graphique.

Si vous ne parvenez pas à obtenir que sqlcmd insère correctement les données (N en tête ou non), vous devez vous plaindre auprès de Microsoft. Lorsque vous le faites, être capable d'afficher les octets tels qu'ils sont stockés dans la colonne - en utilisant convert(colname as varbinary) - sera essentiel pour expliquer ce qui ne va pas.


Termes de classement

Collation

Un classement spécifie les modèles de bits qui représentent chaque caractère d'un ensemble de données. Les classements déterminent également les règles qui trient et comparent les données. SQL Server prend en charge le stockage d'objets ayant des classements différents dans une seule base de données. Pour les colonnes non Unicode, le paramètre de classement spécifie la page de codes des données et les caractères pouvant être représentés. Les données que vous déplacez entre les colonnes non Unicode doivent être converties de la page de codes source vers la page de codes de destination.

Les résultats de l'instruction Transact-SQL peuvent varier lorsque l'instruction est exécutée dans le contexte de différentes bases de données ayant des paramètres de classement différents. Si possible, utilisez un classement standardisé pour votre organisation. De cette façon, vous n'avez pas besoin de spécifier le classement dans chaque caractère ou expression Unicode. Si vous devez travailler avec des objets qui ont des paramètres de classement et de page de codes différents, codez vos requêtes pour prendre en compte les règles de priorité de classement. Pour plus d'informations, consultez Priorité de classement (Transact-SQL).

Les options associées à un classement sont la sensibilité à la casse, la sensibilité aux accents, la sensibilité au kana, la sensibilité à la largeur et la sensibilité du sélecteur de variation. SQL Server 2019 (15.x) introduit une option supplémentaire pour l'encodage UTF-8.

Vous pouvez spécifier ces options en les ajoutant au nom du classement. Par exemple, le classement Japanese_Bushu_Kakusu_100_CS_AS_KS_WS_UTF8 est sensible à la casse, sensible aux accents, sensible au kana, sensible à la largeur et codé en UTF-8. Autre exemple, la collation Japanese_Bushu_Kakusu_140_CI_AI_KS_WS_VSS est insensible à la casse, aux accents, au kana, à la largeur, au sélecteur de variation et il utilise un codage non Unicode.

Le comportement associé à ces différentes options est décrit dans le tableau suivant :

1 Si Binaire ou Point de code binaire est sélectionné, les options Sensible à la casse (_CS), Sensible à l'accent (_AS), Sensible à Kana (_KS) et Sensible à la largeur (_WS) ne sont pas disponibles.

Exemples d'options de classement

Chaque classement est combiné en une série de suffixes pour définir la sensibilité à la casse, aux accents, à la largeur ou au kana. Les exemples suivants décrivent le comportement de l'ordre de tri pour diverses combinaisons de suffixes.

Suffixe de classement Windows Description de l'ordre de tri
_BIN 1 Tri binaire
_BIN2 1, 2 Ordre de tri des points de code binaire
_CI_AI 2 Insensible à la casse, insensible aux accents, insensible au kana, insensible à la largeur
_CI_AI_KS 2 Insensible à la casse, insensible aux accents, sensible au kana, insensible à la largeur
_CI_AI_KS_WS 2 Insensible à la casse, insensible aux accents, sensible au kana, sensible à la largeur
_CI_AI_WS 2 Insensible à la casse, insensible aux accents, insensible au kana, sensible à la largeur
_CI_AS 2 Insensible à la casse, sensible aux accents, insensible au kana, insensible à la largeur
_CI_AS_KS 2 Insensible à la casse, sensible aux accents, sensible au kana, insensible à la largeur
_CI_AS_KS_WS 2 Insensible à la casse, sensible aux accents, sensible au kana, sensible à la largeur
_CI_AS_WS 2 Insensible à la casse, sensible aux accents, insensible au kana, sensible à la largeur
_CS_AI 2 Sensible à la casse, insensible aux accents, insensible au kana, insensible à la largeur
_CS_AI_KS 2 Sensible à la casse, insensible aux accents, sensible au kana, insensible à la largeur
_CS_AI_KS_WS 2 Sensible à la casse, insensible aux accents, sensible au kana, sensible à la largeur
_CS_AI_WS 2 Sensible à la casse, insensible aux accents, insensible au kana, sensible à la largeur
_CS_AS 2 Sensible à la casse, sensible aux accents, insensible au kana, insensible à la largeur
_CS_AS_KS 2 Sensible à la casse, sensible aux accents, sensible au kana, insensible à la largeur
_CS_AS_KS_WS 2 Sensible à la casse, sensible aux accents, sensible au kana, sensible à la largeur
_CS_AS_WS 2 Sensible à la casse, sensible aux accents, insensible au kana, sensible à la largeur

1 Si Binaire ou Point de code binaire est sélectionné, les options Sensible à la casse (_CS), Sensible à l'accent (_AS), Sensible à Kana (_KS) et Sensible à la largeur (_WS) ne sont pas disponibles.

2 L'ajout de l'option UTF-8 (_UTF8) vous permet d'encoder des données Unicode en utilisant UTF-8. Pour plus d'informations, consultez la section Support UTF-8 dans cet article.

Ensembles de classement

SQL Server prend en charge les ensembles de classement suivants :

Classements Windows

Les classements Windows définissent des règles de stockage des données de caractères basées sur les paramètres régionaux du système Windows associés. Pour un classement Windows, vous pouvez implémenter une comparaison de données non Unicode en utilisant le même algorithme que celui des données Unicode. Les règles de classement de base de Windows spécifient quel alphabet ou quelle langue est utilisé lorsque le tri par dictionnaire est appliqué. Les règles spécifient également la page de codes utilisée pour stocker les données de caractères non Unicode. Le tri Unicode et non-Unicode est compatible avec les comparaisons de chaînes dans une version particulière de Windows. Cela assure la cohérence entre les types de données dans SQL Server et permet aux développeurs de trier les chaînes dans leurs applications en utilisant les mêmes règles que celles utilisées par SQL Server. Pour plus d'informations, consultez Nom de classement Windows (Transact-SQL).

Classements binaires

Les classements binaires trient les données en fonction de la séquence de valeurs codées définies par les paramètres régionaux et le type de données. Ils sont sensibles à la casse. Un classement binaire dans SQL Server définit les paramètres régionaux et la page de codes ANSI utilisés. Cela applique un ordre de tri binaire. Parce qu'ils sont relativement simples, les classements binaires contribuent à améliorer les performances des applications. Pour les types de données non Unicode, les comparaisons de données sont basées sur les points de code définis sur la page de codes ANSI. Pour les types de données Unicode, les comparaisons de données sont basées sur les points de code Unicode. Pour les classements binaires sur les types de données Unicode, les paramètres régionaux ne sont pas pris en compte dans les tris de données. Par example, Latin_1_General_BIN et Japonais_BIN donnent des résultats de tri identiques lorsqu'ils sont utilisés sur des données Unicode. Pour plus d'informations, consultez Nom de classement Windows (Transact-SQL).

Il existe deux types de classements binaires dans SQL Server :

L'héritage POUBELLE classements, qui ont effectué une comparaison incomplète de point de code à point de code pour les données Unicode. Ces anciens classements binaires comparaient le premier caractère à WCHAR, suivi d'une comparaison octet par octet. Dans un classement BIN, seul le premier caractère est trié en fonction du point de code et les caractères restants sont triés en fonction de leurs valeurs d'octet.

Le plus récent BIN2 collations, qui implémentent une pure comparaison de points de code. Dans un classement BIN2, tous les caractères sont triés en fonction de leurs points de code. Parce que la plate-forme Intel est une architecture un peu endian, les caractères du code Unicode sont toujours stockés avec un échange d'octets.

Classements SQL Server

Les classements SQL Server (SQL_*) assurent la compatibilité de l'ordre de tri avec les versions antérieures de SQL Server. Les règles de tri du dictionnaire pour les données non Unicode sont incompatibles avec toute routine de tri fournie par les systèmes d'exploitation Windows. Cependant, le tri des données Unicode est compatible avec une version particulière des règles de tri Windows. Étant donné que les classements SQL Server utilisent des règles de comparaison différentes pour les données non Unicode et Unicode, vous voyez des résultats différents pour les comparaisons des mêmes données, selon le type de données sous-jacent. Pour plus d'informations, consultez Nom de classement SQL Server (Transact-SQL).

Lors de l'installation de SQL Server, le paramètre de classement d'installation par défaut est déterminé par les paramètres régionaux du système d'exploitation (SE). Vous pouvez modifier le classement au niveau du serveur pendant l'installation ou en modifiant les paramètres régionaux du système d'exploitation avant l'installation. Pour des raisons de compatibilité descendante, le classement par défaut est défini sur la plus ancienne version disponible associée à chaque paramètre régional spécifique. Par conséquent, ce n'est pas toujours le classement recommandé. Pour tirer pleinement parti des fonctionnalités de SQL Server, modifiez les paramètres d'installation par défaut pour utiliser les classements Windows. Par exemple, pour les paramètres régionaux du système d'exploitation "English (United States)" (page de codes 1252), le classement par défaut lors de l'installation est SQL_Latin1_General_CP1_CI_AS, et il peut être remplacé par son équivalent de classement Windows le plus proche, Latin1_General_100_CI_AS_SC.

Lorsque vous mettez à niveau une instance de langue anglaise de SQL Server, vous pouvez spécifier des classements SQL Server (SQL_*) pour la compatibilité avec les instances existantes de SQL Server. Étant donné que le classement par défaut d'une instance de SQL Server est défini lors de l'installation, assurez-vous de spécifier soigneusement les paramètres de classement lorsque les conditions suivantes sont remplies :

  • Votre code d'application dépend du comportement des classements SQL Server précédents.
  • Vous devez stocker des données de caractères qui reflètent plusieurs langues.

Niveaux de classement

Les classements de paramètres sont pris en charge aux niveaux suivants d'une instance de SQL Server :

Classements au niveau du serveur

Le classement par défaut du serveur est déterminé lors de l'installation de SQL Server et devient le classement par défaut des bases de données système et de toutes les bases de données utilisateur.

Le tableau suivant présente les désignations de classement par défaut, telles que déterminées par les paramètres régionaux du système d'exploitation (OS), y compris leurs identificateurs de code de langue Windows et SQL (LCID) :

Paramètres régionaux Windows LCID Windows LCID SQL Classement par défaut
Afrikaans (Afrique du Sud) 0x0436 0x0409 Latin1_General_CI_AS
Albanais (Albanie) 0x041c 0x041c Albanais_CI_AS
Alsacien (France) 0x0484 0x0409 Latin1_General_CI_AS
Amharique (Éthiopie) 0x045e 0x0409 Latin1_General_CI_AS
Arabe (Algérie) 0x1401 0x0401 Arabe_CI_AS
Arabe (Bahreïn) 0x3c01 0x0401 Arabe_CI_AS
Arabe (Egypte) 0x0c01 0x0401 Arabe_CI_AS
Arabe (Irak) 0x0801 0x0401 Arabe_CI_AS
Arabe (Jordanie) 0x2c01 0x0401 Arabe_CI_AS
Arabe (Koweït) 0x3401 0x0401 Arabe_CI_AS
Arabe (Liban) 0x3001 0x0401 Arabe_CI_AS
Arabe (Libye) 0x1001 0x0401 Arabe_CI_AS
Arabe (Maroc) 0x1801 0x0401 Arabe_CI_AS
Arabe (Oman) 0x2001 0x0401 Arabe_CI_AS
Arabe (Qatar) 0x4001 0x0401 Arabe_CI_AS
Arabe (Arabie saoudite) 0x0401 0x0401 Arabe_CI_AS
Arabe (Syrie) 0x2801 0x0401 Arabe_CI_AS
Arabe (Tunisie) 0x1c01 0x0401 Arabe_CI_AS
Arabe (EAU) 0x3801 0x0401 Arabe_CI_AS
Arabe (Yémen) 0x2401 0x0401 Arabe_CI_AS
Arménien (Arménie) 0x042b 0x0419 Latin1_General_CI_AS
Assamais (Inde) 0x044d 0x044d Non disponible au niveau du serveur
azerbaïdjanais (Azerbaïdjan, cyrillique) 0x082c 0x082c Obsolète, non disponible au niveau du serveur
azerbaïdjanais (Azerbaïdjan, latin) 0x042c 0x042c Obsolète, non disponible au niveau du serveur
Bachkir (Russie) 0x046d 0x046d Latin1_General_CI_AI
Basque (basque) 0x042d 0x0409 Latin1_General_CI_AS
Biélorusse (Biélorussie) 0x0423 0x0419 Cyrillique_Général_CI_AS
Bangla (Bangladesh) 0x0845 0x0445 Non disponible au niveau du serveur
Bengali (Inde) 0x0445 0x0439 Non disponible au niveau du serveur
bosniaque (Bosnie-Herzégovine, cyrillique) 0x201a 0x201a Latin1_General_CI_AI
bosniaque (Bosnie-Herzégovine, latin) 0x141a 0x141a Latin1_General_CI_AI
Breton (France) 0x047e 0x047e Latin1_General_CI_AI
Bulgare (Bulgarie) 0x0402 0x0419 Cyrillique_Général_CI_AS
Catalan (catalan) 0x0403 0x0409 Latin1_General_CI_AS
Chinois (RAS de Hong Kong, RPC) 0x0c04 0x0404 Chinese_Taiwan_Stroke_CI_AS
Chinois (RAS de Macao) 0x1404 0x1404 Latin1_General_CI_AI
Chinois (Macao) 0x21404 0x21404 Latin1_General_CI_AI
Chinois (RPC) 0x0804 0x0804 Chinois_PRC_CI_AS
Chinois (RPC) 0x20804 0x20804 Chinese_PRC_Stroke_CI_AS
Chinois (Singapour) 0x1004 0x0804 Chinois_PRC_CI_AS
Chinois (Singapour) 0x21004 0x20804 Chinese_PRC_Stroke_CI_AS
Chinois (Taïwan) 0x30404 0x30404 Chinese_Taiwan_Bopomofo_CI_AS
Chinois (Taïwan) 0x0404 0x0404 Chinese_Taiwan_Stroke_CI_AS
Corse (France) 0x0483 0x0483 Latin1_General_CI_AI
Croate (Bosnie-Herzégovine, latin) 0x101a 0x041a Croate_CI_AS
Croate (Croatie) 0x041a 0x041a Croate_CI_AS
Tchèque (République tchèque) 0x0405 0x0405 Tchèque_CI_AS
Danois (Danemark) 0x0406 0x0406 Danish_Norwegian_CI_AS
Dari (Afghanistan) 0x048c 0x048c Latin1_General_CI_AI
Divehi (Maldives) 0x0465 0x0465 Non disponible au niveau du serveur
Néerlandais (Belgique) 0x0813 0x0409 Latin1_General_CI_AS
Néerlandais (Pays-Bas) 0x0413 0x0409 Latin1_General_CI_AS
Anglais (Australie) 0x0c09 0x0409 Latin1_General_CI_AS
Anglais (Belize) 0x2809 0x0409 Latin1_General_CI_AS
Anglais (Canada) 0x1009 0x0409 Latin1_General_CI_AS
Anglais (Caraïbe) 0x2409 0x0409 Latin1_General_CI_AS
Anglais (Inde) 0x4009 0x0409 Latin1_General_CI_AS
Anglais (Irlande) 0x1809 0x0409 Latin1_General_CI_AS
Anglais (Jamaïque) 0x2009 0x0409 Latin1_General_CI_AS
Anglais (Malaisie) 0x4409 0x0409 Latin1_General_CI_AS
Anglais (Nouvelle-Zélande) 0x1409 0x0409 Latin1_General_CI_AS
Anglais (Philippines) 0x3409 0x0409 Latin1_General_CI_AS
Anglais (Singapour) 0x4809 0x0409 Latin1_General_CI_AS
Anglais (Afrique du Sud) 0x1c09 0x0409 Latin1_General_CI_AS
Anglais (Trinité-et-Tobago) 0x2c09 0x0409 Latin1_General_CI_AS
Royaume Uni Anglais) 0x0809 0x0409 Latin1_General_CI_AS
États Unis Anglais) 0x0409 0x0409 SQL_Latin1_General_CP1_CI_AS
Anglais (Zimbabwe) 0x3009 0x0409 Latin1_General_CI_AS
Estonien (Estonie) 0x0425 0x0425 Estonien_CI_AS
Féroé (Îles Féroé) 0x0438 0x0409 Latin1_General_CI_AS
Philippin (Philippines) 0x0464 0x0409 Latin1_General_CI_AS
finnois (Finlande) 0x040b 0x040b Finland_Swedish_CI_AS
Français (Belgique) 0x080c 0x040c French_CI_AS
Français (Canada) 0x0c0c 0x040c French_CI_AS
France francaise) 0x040c 0x040c French_CI_AS
Français (Luxembourg) 0x140c 0x040c French_CI_AS
Français (Monaco) 0x180c 0x040c French_CI_AS
Français (Suisse) 0x100c 0x040c French_CI_AS
Frison (Pays-Bas) 0x0462 0x0462 Latin1_General_CI_AI
galicien 0x0456 0x0409 Latin1_General_CI_AS
Géorgien (Géorgie) 0x10437 0x10437 Georgian_Modern_Sort_CI_AS
Géorgien (Géorgie) 0x0437 0x0419 Latin1_General_CI_AS
Allemand - Tri du répertoire téléphonique (DIN) 0x10407 0x10407 German_PhoneBook_CI_AS
Allemand (Autriche) 0x0c07 0x0409 Latin1_General_CI_AS
Allemand Allemagne) 0x0407 0x0409 Latin1_General_CI_AS
Allemand (Liechtenstein) 0x1407 0x0409 Latin1_General_CI_AS
Allemand (Luxembourg) 0x1007 0x0409 Latin1_General_CI_AS
Allemand (Suisse) 0x0807 0x0409 Latin1_General_CI_AS
Grec (Grèce) 0x0408 0x0408 Grec_CI_AS
Groenlandais (Groenland) 0x046f 0x0406 Danish_Norwegian_CI_AS
Gujarati (Inde) 0x0447 0x0439 Non disponible au niveau du serveur
Haoussa (Nigéria, latin) 0x0468 0x0409 Latin1_General_CI_AS
Hébreu (Israël) 0x040d 0x040d Hébreu_CI_AS
Hindi (Inde) 0x0439 0x0439 Non disponible au niveau du serveur
Hongrois (Hongrie) 0x040e 0x040e Hongrois_CI_AS
Tri technique hongrois 0x1040e 0x1040e Hongrois_Technical_CI_AS
Islandais (Islande) 0x040f 0x040f Islandais_CI_AS
Igbo (Nigéria) 0x0470 0x0409 Latin1_General_CI_AS
Indonésien (Indonésie) 0x0421 0x0409 Latin1_General_CI_AS
Inuktitut (Canada, latin) 0x085d 0x0409 Latin1_General_CI_AS
Inuktitut (Syllabique) Canada 0x045d 0x045d Latin1_General_CI_AI
Irlandais (Irlande) 0x083c 0x0409 Latin1_General_CI_AS
Italien (Italie) 0x0410 0x0409 Latin1_General_CI_AS
Italien (Suisse) 0x0810 0x0409 Latin1_General_CI_AS
Japonais (Japon XJIS) 0x0411 0x0411 Japonais_CI_AS
Japonais (Japon) 0x040411 0x40411 Latin1_General_CI_AI
Kannada (Inde) 0x044b 0x0439 Non disponible au niveau du serveur
Kazakh (Kazakhstan) 0x043f 0x043f Kazakh_90_CI_AS
Khmer (Cambodge) 0x0453 0x0453 Non disponible au niveau du serveur
K'iche (Guatemala) 0x0486 0x0c0a Modern_Spanish_CI_AS
Kinyarwanda (Rwanda) 0x0487 0x0409 Latin1_General_CI_AS
Konkani (Inde) 0x0457 0x0439 Non disponible au niveau du serveur
Coréen (Tri par dictionnaire de Corée) 0x0412 0x0412 Coréen_Wansung_CI_AS
Kirghize (Kirghizistan) 0x0440 0x0419 Cyrillique_Général_CI_AS
Lao (RDP lao) 0x0454 0x0454 Non disponible au niveau du serveur
Letton (Lettonie) 0x0426 0x0426 Letton_CI_AS
Lituanien (Lituanie) 0x0427 0x0427 Lituanien_CI_AS
Bas-sorabe (Allemagne) 0x082e 0x0409 Latin1_General_CI_AS
Luxembourgeois (Luxembourg) 0x046e 0x0409 Latin1_General_CI_AS
Macédonien (Macédoine du Nord, ARYM) 0x042f 0x042f Macédonien_FYROM_90_CI_AS
Malais (Brunéi Darussalam) 0x083e 0x0409 Latin1_General_CI_AS
Malais (Malaisie) 0x043e 0x0409 Latin1_General_CI_AS
Malayalam (Inde) 0x044c 0x0439 Non disponible au niveau du serveur
Maltais (Malte) 0x043a 0x043a Latin1_General_CI_AI
Maori (Nouvelle-Zélande) 0x0481 0x0481 Latin1_General_CI_AI
Mapudungun (Chili) 0x047a 0x047a Latin1_General_CI_AI
Marathi (Inde) 0x044e 0x0439 Non disponible au niveau du serveur
Mohawk (Canada) 0x047c 0x047c Latin1_General_CI_AI
Mongol (Mongolie) 0x0450 0x0419 Cyrillique_Général_CI_AS
Mongol (RPC) 0x0850 0x0419 Cyrillique_Général_CI_AS
Népalais (Népal) 0x0461 0x0461 Non disponible au niveau du serveur
Norvégien (Bokmål, Norvège) 0x0414 0x0414 Latin1_General_CI_AI
Norvégien (Nynorsk, Norvège) 0x0814 0x0414 Latin1_General_CI_AI
Occitan (France) 0x0482 0x040c French_CI_AS
Odia (Inde) 0x0448 0x0439 Non disponible au niveau du serveur
Pashto (Afghanistan) 0x0463 0x0463 Non disponible au niveau du serveur
Persan (Iran) 0x0429 0x0429 Latin1_General_CI_AI
Polonais (Pologne) 0x0415 0x0415 Polonais_CI_AS
Portugais (Brésil) 0x0416 0x0409 Latin1_General_CI_AS
Portugais (Portugal) 0x0816 0x0409 Latin1_General_CI_AS
Pendjabi (Inde) 0x0446 0x0439 Non disponible au niveau du serveur
Quechua (Bolivie) 0x046b 0x0409 Latin1_General_CI_AS
Quechua (Équateur) 0x086b 0x0409 Latin1_General_CI_AS
Quechua (Pérou) 0x0c6b 0x0409 Latin1_General_CI_AS
Roumain (Roumanie) 0x0418 0x0418 Roumain_CI_AS
romanche (Suisse) 0x0417 0x0417 Latin1_General_CI_AI
Russe (Russie) 0x0419 0x0419 Cyrillique_Général_CI_AS
Sahka (Russie) 0x0485 0x0485 Latin1_General_CI_AI
Sami (Inari, Finlande) 0x243b 0x083b Latin1_General_CI_AI
Sami (Lule, Norvège) 0x103b 0x043b Latin1_General_CI_AI
Sami (Lule, Suède) 0x143b 0x083b Latin1_General_CI_AI
Sami (Nord, Finlande) 0x0c3b 0x083b Latin1_General_CI_AI
Sami (Nord, Norvège) 0x043b 0x043b Latin1_General_CI_AI
Sami (Nord, Suède) 0x083b 0x083b Latin1_General_CI_AI
Sami (Skolt, Finlande) 0x203b 0x083b Latin1_General_CI_AI
Sami (Sud, Norvège) 0x183b 0x043b Latin1_General_CI_AI
Sami (Sud, Suède) 0x1c3b 0x083b Latin1_General_CI_AI
Sanskrit (Inde) 0x044f 0x0439 Non disponible au niveau du serveur
Serbe (Bosnie-Herzégovine, cyrillique) 0x1c1a 0x0c1a Latin1_General_CI_AI
Serbe (Bosnie-Herzégovine, latin) 0x181a 0x081a Latin1_General_CI_AI
Serbe (Serbie, Cyrillique) 0x0c1a 0x0c1a Latin1_General_CI_AI
Serbe (Serbie, Latin) 0x081a 0x081a Latin1_General_CI_AI
Sesotho sa Leboa/Sotho du Nord (Afrique du Sud) 0x046c 0x0409 Latin1_General_CI_AS
Setswana/Tswana (Afrique du Sud) 0x0432 0x0409 Latin1_General_CI_AS
Cinghalais (Sri Lanka) 0x045b 0x0439 Non disponible au niveau du serveur
Slovaque (Slovaquie) 0x041b 0x041b Slovaque_CI_AS
Slovène (Slovénie) 0x0424 0x0424 Slovène_CI_AS
Espagnol (Argentine) 0x2c0a 0x0c0a Modern_Spanish_CI_AS
Espagnol (Bolivie) 0x400a 0x0c0a Modern_Spanish_CI_AS
Espagnol (Chili) 0x340a 0x0c0a Modern_Spanish_CI_AS
Espagnol (Colombie) 0x240a 0x0c0a Modern_Spanish_CI_AS
Espagnol (Costa Rica) 0x140a 0x0c0a Modern_Spanish_CI_AS
Espagnol (République dominicaine) 0x1c0a 0x0c0a Modern_Spanish_CI_AS
Espagnol (Équateur) 0x300a 0x0c0a Modern_Spanish_CI_AS
Espagnol (Salvador) 0x440a 0x0c0a Modern_Spanish_CI_AS
Espagnol (Guatemala) 0x100a 0x0c0a Modern_Spanish_CI_AS
Espagnol (Honduras) 0x480a 0x0c0a Modern_Spanish_CI_AS
Espagnol (Mexique) 0x080a 0x0c0a Modern_Spanish_CI_AS
Espagnol (Nicaragua) 0x4c0a 0x0c0a Modern_Spanish_CI_AS
Espagnol (Panama) 0x180a 0x0c0a Modern_Spanish_CI_AS
Espagnol (Paraguay) 0x3c0a 0x0c0a Modern_Spanish_CI_AS
Espagnol (Pérou) 0x280a 0x0c0a Modern_Spanish_CI_AS
Espagnol (Porto Rico) 0x500a 0x0c0a Modern_Spanish_CI_AS
Espagnol (Espagne) 0x0c0a 0x0c0a Modern_Spanish_CI_AS
Espagnol (Espagne, Tri traditionnel) 0x040a 0x040a Traditional_Spanish_CI_AS
Espagnol (États-Unis) 0x540a 0x0409 Latin1_General_CI_AS
Espagnol (Uruguay) 0x380a 0x0c0a Modern_Spanish_CI_AS
Espagnol (Venezuela) 0x200a 0x0c0a Modern_Spanish_CI_AS
Swahili (Kenya) 0x0441 0x0409 Latin1_General_CI_AS
Suédois (Finlande) 0x081d 0x040b Finland_Swedish_CI_AS
Suédois (Suède) 0x041d 0x040b Finland_Swedish_CI_AS
syriaque (Syrie) 0x045a 0x045a Non disponible au niveau du serveur
Tadjik (Tadjikistan) 0x0428 0x0419 Cyrillique_Général_CI_AS
Tamazight (Algérie, Latin) 0x085f 0x085f Latin1_General_CI_AI
Tamoul (Inde) 0x0449 0x0439 Non disponible au niveau du serveur
Tatar (Russie) 0x0444 0x0444 Cyrillique_Général_CI_AS
Telugu (Inde) 0x044a 0x0439 Non disponible au niveau du serveur
Thaï (Thaïlande) 0x041e 0x041e Thaï_CI_AS
Tibétain (RPC) 0x0451 0x0451 Non disponible au niveau du serveur
Turc (Turquie) 0x041f 0x041f Turc_CI_AS
Turkmène (Turkménistan) 0x0442 0x0442 Latin1_General_CI_AI
Ouïghour (RPC) 0x0480 0x0480 Latin1_General_CI_AI
Ukrainien (Ukraine) 0x0422 0x0422 Ukrainien_CI_AS
Haut-sorabe (Allemagne) 0x042e 0x042e Latin1_General_CI_AI
Ourdou (Pakistan) 0x0420 0x0420 Latin1_General_CI_AI
Ouzbek (Ouzbékistan, cyrillique) 0x0843 0x0419 Cyrillique_Général_CI_AS
Ouzbek (Ouzbékistan, latin) 0x0443 0x0443 Ouzbek_Latin_90_CI_AS
Vietnamien (Vietnam) 0x042a 0x042a Vietnamien_CI_AS
Gallois (Royaume-Uni) 0x0452 0x0452 Latin1_General_CI_AI
Wolof (Sénégal) 0x0488 0x040c French_CI_AS
Xhosa/isiXhosa (Afrique du Sud) 0x0434 0x0409 Latin1_General_CI_AS
Yi (RPC) 0x0478 0x0409 Latin1_General_CI_AS
Yoruba (Nigéria) 0x046a 0x0409 Latin1_General_CI_AS
Zulu/isiZulu (Afrique du Sud) 0x0435 0x0409 Latin1_General_CI_AS

Après avoir attribué un classement au serveur, vous pouvez le modifier uniquement en exportant tous les objets et données de la base de données, en reconstruisant le Maître database, and importing all database objects and data. Instead of changing the default collation of an instance of SQL Server, you can specify the desired collation when you create a new database or database column.

To query the server collation for an instance of SQL Server, use the SERVERPROPERTY function:

To query the server for all available collations, use the following fn_helpcollations() built-in function:

Database-level collations

When you create or modify a database, you can use the COLLATE clause of the CREATE DATABASE or ALTER DATABASE statement to specify the default database collation. If no collation is specified, the database is assigned the server collation.

You can't change the collation of system databases unless you change the collation for the server.

The database collation is used for all metadata in the database, and the collation is the default for all string columns, temporary objects, variable names, and any other strings used in the database. When you change the collation of a user database, there can be collation conflicts when queries in the database access temporary tables. Temporary tables are always stored in the tempdb system database, which uses the collation for the instance. Queries that compare character data between the user database and tempdb might fail if the collations cause a conflict in evaluating the character data. You can resolve this issue by specifying the COLLATE clause in the query. For more information, see COLLATE (Transact-SQL).

You can't change the collation after the database has been created on Azure SQL Database.

You can change the collation of a user database by using an ALTER DATABASE statement that's similar to the following:


The fundamental idea of NVARCHAR

NCHAR, NVARCHAR or NTEXT are similar to CHAR, VARCHAR OR TEXT, where the N prefix represents the International Language Character Set. The N-prefixed data types indicate that the resulting string could be comprised of a Unicode character set with variable length where each character occupies 2 bytes. Without the N prefix, the string could be converted to the default charset of the database but could result in certain special characters not being recognized as part of the International Language Character Set.

Today’s development platforms or their operating systems support the Unicode character set. Therefore, In SQL Server, you should utilize NVARCHAR rather than VARCHAR. If you do use VARCHAR when Unicode support is present, then an encoding inconsistency will arise while communicating with the database. This inconsistency causes query performance issues that eventually generate errors like blocking or a deadlock in SQL Server.

How can you recover from this query performance issue? Indexes can fail when an incorrect data type has been used within a column. In SQL Server, if an indexed VARCHAR column is presented with a Unicode N string, SQL Server won’t be able to make use of the index. A similar query performance issue occurs when an indexed column containing INTEGER data is presented with VARCHAR type data. We will talk about more examples below.

Imagine, that a SalesOrderHeader table has an AccountNumber column with VARCHAR data type and the total number of rows is 31,465. What will occur if we use prefix N before a string in a WHERE condition? Here, we will investigate a couple of query performance parameters on query execution, for example, logical reads, index utilization, execution time, etc.


Binary Collation for UTF-8

CTP 2.0 did not come with a binary UTF-8 collation. Why might we need / want one? Well, here are some reasons:

  1. Microsoft&rsquos implementation of Unicode has incomplete, and some incorrect, sort weights. One example:
    Choosing a binary collation that can differentiate between ‘ss’ and ‘ß’ for nvarchar column in Sql Server
  2. When needing to know if two values are 100% identical, you need a binary Collation (such as when auditing for changes, etc). Even if all characters had correct sort weights, you still wouldn&rsquot be able to differentiate between a base character plus a combining diacritic and the pre-composed single character equivalent. Nor would you be able to differentiate between a base character plus multiple combining diacritics and the same characters with a different order for the diacritics. In both of those cases, the visual representation of the &ldquocharacter&rdquo is the same, but the number or order of the underlying Code Points would be different. The first item from the following post provides a working example: No, Binary Collations are not Case-Sensitive
  3. When storing alphanumeric codes (e.g. airline confirmation codes, phone numbers, postal codes, etc), binary sorting and comparison is beaucoup faster since it ignores all linguistic rules, which is perfect for scenarios such as these where there is no expectation of applying such rules.
  4. Finding / removing "(null)" character U+0000 / CHAR(0)

CTP 2.3 introduced the long-awaited BIN2 collation: UTF8_BIN2 . This was a definite improvement over not having one, but there were a few issues that absolutely needed to be addressed.

  1. It exists (Yay!)
  2. No BIN collation to confuse people with.
  3. Only one BIN2 collation no BIN2 per each culture, which would have added no benefit and likely would have confused people wondering what the difference was between the various UTF8_BIN2 collations.

Not So Good

  1. Version 80 used instead of 140. This is a problem because version 80 is missing 649 uppercase / lowercase mappings that version 140 collations have. This affects the accuracy of the UPPER and LOWER functions.
  2. No version number in the name, so inconsistent with all other Windows collations.
  3. No culture name, so inconsistent with all other collations. Should be something like "Invariant" or "General", or even "Latin1_General_version#_" if need be (since the UTF8_BIN2 collation does have an LCID of 1033, which is "Latin1_General").

This is a MAJOR problem, actually. On the surface it appears to be nothing more than a different way to name the collation. But, there is an issue that is hidden by the fact that the version 80 collations don&rsquot include the version number (i.e. "80") in the collation name. The last major update of collations was the version 100 collations that introduced many new collations as well as used a newer version of Unicode. Newer versions of Unicode have more sort weights defined, more upper-case / lower-case mappings defined, and some fixes to previous weights and/or mappings that might not have been correct. The version 100 collations were introduced in SQL Server 2008. SQL Server 2017 did introduce some version 140 collations with an even newer version of Unicode, but that was for seul the Japanese collations. At some point, Microsoft is going to need to bring the rest of the version 100 collations up to the 140 level (or beyond). When that happens, all of the new collations will have the new version number in their names. That&rsquos fine for all collations sauf UTF8_BIN2 . SQL Server 2019, which is version 150, didn&rsquot introduce new collations with newer Unicode sort weights (the UTF-8 collations are just the existing collations that do a different 8-bit encoding). So, assuming the next version of SQL Server does upgrade the Unicode info, that would be version 160. Since there is already a UTF8_BIN2 collation that isn&rsquot going to have its definition changed, a new collation will be added, and the naming convention would make it: 160_UTF8_BIN2 . That might look ok, but identifiers (i.e. names of things in the system), cannot begin with a number. This will be quite the difficult situation once somebody attempts to create this new collation.

Final Resolution

CTP 3.0 finally resolved 99% of the issues related to UTF-8 binary collations. The binary collation was updated to be: Latin1_General_100_BIN2_UTF8 .

  1. Version is 100 instead of 80, so many more upper-case / lower-case mappings (even if not as many as version 140)
  2. Name is now prefixed with a culture name, which is not only consistent with all other collations, but also avoids the problem is ending up with a version of the UTF-8 binary collation that begins with a number (again, that would not be a valid identifier).

Only remaining issue is that a second binary collation is needed for the Turkish locale / culture as the upper-case / lower-case mappings for i and I are not the same as in all other cultures. I submitted a feedback suggestion for this:

Finally, there&rsquos a rather minor issue in that the new Latin1_General_100_BIN2_UTF8 collation does not work with the NTEXT datatype. This is a problem because the new UTF-8 collations are not supposed to affect NVARCHAR / UTF-16 data, et binary collations do not fully support / recognize Supplementary Characters, yet that&rsquos the error message one gets when attempting to use Latin1_General_100_BIN2_UTF8 with NTEXT . Of course, the NTEXT datatype has been deprecated since the release of SQL Server 2005, so this is likely a rather low priority. Still, I filled a bug report for it here:


It looks like your varbinary string got injected with some nonsense. All of the sequences of two 00 values are null characters, so this is why your string is terminating upon conversion. The first character is 0x24 (dollar sign), which is why the output is just a dollar sign.

Now, if I take your string and strip out all of the 00 sequences:

I get something close again, there is a bunch of garbage in there, but the string you're after est in there:

You can ignore the leading garbage by just taking the original value and performing RIGHT() against it, but this assumes that the important part of the string is always the same length (we can't tell you if that's true).

Or using SUBSTRING , but this assumes that the garbage at the beginning of the string is always the same length:

We also can't possibly tell you Pourquoi that garbage is there and if it has any additional meaning. You'll need to find out how the values got encoded this way in the first place. The value you wanted encoded, 22639935-KCN , should have looked a little differently as varbinary :

So, again, you will need to do some research to find out why this value wasn't encoded this way. We can't answer all of this because we didn't design your system or store those values.


ASCII encoding error when updating field content in SQL Server table - Geographic Information Systems

The following note and error message indicate that a SAS ® data set has an encoding value that does not match the encoding setting for the SAS session:

In order to confirm the mismatch, use the following code for further debugging where libref.datasetname is the name of the problematic data set:

Compare the encoding value setting of the SAS session with the encoding value setting of the data set. If the two do not match, then the SAS session should be invoked with the encoding value shown for the data set. The CONFIG information from the OPTIONS procedure displays in the SAS log the config file currently in use, usually !SASHomeSASFoundation9.X ls . The same directory contains other configuration files, at a minimum: en (English), 1d (DBCS), and u8 (Unicode). Locate the desired configuration file, and use this file to invoke SAS.

In the following use case, the data set shows UTF8 encoding, and the SAS ® 9.4 session shows Wlatin1 encoding:

Your SAS session should be invoked with UTF-8 encoding in order to avoid the NOTE and ERROR.

To invoke SAS using UTF-8 encoding on Windows, do one of the following:

  • Du Start menu, select All ProgramsSASAdditional LanguagesSAS 9.X (Unicode Support).
  • From a desktop icon, do the following:
    1. Right-click the SAS icon and select Propriétés. On the Shortcut tab, in the Target line, add the desired configuration file (with the complete path) to the end:

On UNIX platforms, the SAS invocation scripts are located in:

More information specific to UNIX platforms can be found under Post-installation Configuration for National Language Support.

If a conversion of the encoding value for the SAS data set is necessary, confer with Usage Note 15597: How to convert SAS ® data set encoding.

The following link contains additional NLS documentation: SAS ® National Language Support (NLS).

Starting in SAS ® 9.4M5 (TS1M5), you can use the %VALIDCHS macro function to validate the character encoding compatibility for data set variables.