J'ai une table avec une colonne varchar. Il autorise les marques déposées (™), les droits d'auteur (©) et d'autres caractères Unicode comme indiqué ci-dessous.
Create table VarcharUnicodeCheck
(
col1 varchar(100)
)
insert into VarcharUnicodeCheck (col1) values ('MyCompany')
insert into VarcharUnicodeCheck (col1) values ('MyCompany™')
insert into VarcharUnicodeCheck (col1) values ('MyCompany░')
insert into VarcharUnicodeCheck (col1) values ('MyCompanyï')
insert into VarcharUnicodeCheck (col1) values ('MyCompany')
select * from VarcharUnicodeCheck
Mais la définition de varchar indique qu'elle autorise les données de chaîne non unicode. Mais les symboles Trademark (™) et Registered (®) sont des caractères Unicode . La définition contredit-elle la propriété du type de données varchar? J'ai lu quelques liens comme le premier et le deuxième . Mais je ne pouvais toujours pas comprendre pourquoi il autorise la chaîne unicode lorsque la définition dit qu'il n'autorise que les valeurs de chaîne non unicode.
Réponses:
Vous avez tort ici. Vos chaînes ne contiennent que des
ascii
caractères.Voici un test simple qui vous montre que vos personnages sont tous des ascii (+ certains
extended ascii
avec des codes ascii entre 128 et 255):Ici, vous pouvez clairement voir que tous vos caractères sont codés sur 1 octet:
Oui, ce ne sont pas des caractères ascii purs mais ils sont en ASCII étendu .
Ici, je vous montre le vrai caractère unicode
Trademark(™)
et son code et sa représentation binaire:Enfin, vous pouvez voir que le
Trademark(™)
caractère unicode a le code 8482 et non 153:la source
Ö
) et dans ISO-8859-1 (parfois appelé Latin1), c'est un code de contrôle sans représentation imprimable. Sauf si vous savez que vous utiliserez toujours la même page de code, il est plus sûr de s'en tenir aux caractères ANSI (127 ou moins) ou d'utiliser des types Unicode. La page de codes 1252 est la plus courante dans SQL Server mais loin d'être omniprésente.D'après les commentaires, je suis d'accord "ASCII étendu" est un terme vraiment mauvais qui signifie en fait une page de codes qui mappe les caractères / points de code dans la plage 128-255, au-delà de la plage de points de code 0-127 standard définie par ASCII.
SQL Server prend en charge de nombreuses pages de codes via des classements. Les caractères non ASCII peuvent être stockés dans varchar tant que le classement sous-jacent prend en charge le caractère.
Le caractère «™» peut être stocké dans des colonnes varchar / char lorsque la page de codes de classement SQL Server est supérieure ou égale à 1250. La requête ci-dessous les énumérera:
Mais seul un sous-ensemble de ceux-ci prend également en charge le caractère «©», de sorte que le classement des colonnes devra être l'un des suivants pour prendre en charge les deux:
la source
Bien que les autres réponses ne soient pas incorrectes, je pense qu'il serait utile de signaler une confusion dans la terminologie de base. J'ai souligné deux mots dans la citation ci-dessus de la question comme exemple de cette confusion. Lorsque la documentation SQL Server parle d'Unicode et non-Unicode des données , ils ne parlent des personnages . Ils parlent des séquences d'octets qui représentent certains caractères. La principale différence entre les types Unicode (
NCHAR
,NVARCHAR
,XML
et le dépréciée / malNTEXT
) et les types non-Unicode (CHAR
,VARCHAR
et le dépréciée / malTEXT
) est ce que les types de séquences d'octets qu'ils peuvent stocker.Les types non Unicode stockent l'un des nombreux codages 8 bits, tandis que les types Unicode stockent un seul codage Unicode 16 bits: UTF-16 Little Endian. Comme les autres réponses l'ont mentionné, quels caractères peuvent être stockés dans un codage 8 bits / non Unicode dépend de la page de codes, qui est déterminée par le classement. Alors que d'autres ont noté que la valeur en octets d'un "caractère" peut varier selon les pages de codes sur lesquelles il se trouve, la valeur en octets peut même varier au sein de la même page de codes lorsqu'il s'agit de l'une des plusieurs pages de codes EBCDIC (variations de Windows- 1252), qui ne se trouvent que dans les anciennes versions de SQL Server, ne devraient pas vraiment être utilisées (c'est-à-dire celles dont le nom commence par
SQL_
).Par conséquent, la définition est précise: tous les caractères que vous pouvez gérer pour stocker dans un type non Unicode sont toujours 8 bits (même s'ils utilisent deux valeurs 8 bits en combinaison comme un seul "caractère", ce qui est ce que le Double- Le jeu de caractères octet / les pages de codes DBCS le permettent). Et les types de données Unicode sont toujours 16 bits, même s'ils utilisent parfois deux valeurs 16 bits en combinaison comme un seul "caractère" (c'est-à-dire une paire de substitution qui à son tour représente un caractère supplémentaire).
ET, en raison de la prise en charge native de SQL Server pour le codage UTF-8
VARCHAR
et lesCHAR
types de données à partir de SQL Server 2019,VARCHAR
ne peut plus être appelé "non-Unicode". Donc, à partir de la première version bêta publique de SQL Server 2019 en septembre 2018, nous devrions nous référer àVARCHAR
un "type de données 8 bits", même lorsque nous parlons en termes de versions antérieures à SQL Server 2019. Cette terminologie est vraie pour les 4 types d'encodages utilisables avecVARCHAR
:Seul le
TEXT
type de données (obsolète à partir de SQL Server 2005, donc ne l'utilisez pas) est "non-Unicode", mais ce n'est qu'une technicité, et le qualifier de "type de données 8 bits" est exact.NVARCHAR
,,NCHAR
etNTEXT
peut être appelé "UTF-16" ou "type de données 16 bits". Oracle, je crois, utilise la terminologie de "Unicode uniquement" pourNVARCHAR
, mais cela n'exclut pas clairement la possibilité d'utiliser UTF-8 (également un encodage Unicode), qui ne fonctionnera pas, donc il vaut probablement mieux s'en tenir à les deux premières options.Pour plus de détails sur les nouveaux encodages UTF-8, veuillez consulter mon article:
Prise en charge native UTF-8 dans SQL Server 2019: Sauveur ou faux prophète?
PS Je progresse lentement vers la mise à jour de la documentation SQL Server pour refléter ces changements.
PPS Microsoft a déjà mis à jour certaines pages avec des informations UTF-8, y compris la documentation char et varchar référencée dans la question. Il ne contient plus l'expression "non-Unicode". Mais ce n'est qu'un FYI; cela ne change pas la question car il s'agit d'encodages non Unicode contenant des caractères qui étaient à tort pensés être uniquement Unicode.
la source
La question contient une idée fausse centrale sur ce qu'est Unicode. Le jeu de caractères Unicode, ainsi que ses encodages tels que UTF-8 et UTF-16, est l'une des nombreuses façons de représenter le texte dans un ordinateur, et dont le but est de remplacer tous les autres jeux de caractères et encodages. Si "données non Unicode" signifiait "caractères non présents dans Unicode", alors aucun du texte que j'ai utilisé dans cette réponse ne pourrait être stocké dans ce type, car toutes les lettres de l'alphabet latin et la ponctuation courante utilisées dans l'anglais courant sont inclus dans Unicode.
Les représentations textuelles peuvent être globalement envisagées en deux parties: un jeu de caractères mappant les différents caractères (lettres, chiffres, symboles, etc.) aux nombres sur un graphique de référence; et un codage représentant ces nombres sous forme de modèles de bits (sur disque, via une connexion réseau, etc.). Ici, nous nous intéressons principalement à la première partie: quels caractères sont répertoriés dans les graphiques pour un jeu de caractères particulier.
Étant donné qu'Unicode vise à avoir des nombres (qu'il appelle des "points de code") pour chaque caractère dans le monde, des références comme Wikipedia se réfèrent souvent à la position Unicode d'un caractère comme une information standard de référence. Cependant, cela ne signifie pas que les autres jeux de caractères n'ont pas de mappage pour ce même caractère.
L'un des jeux de caractères (et codages) les plus anciens et les plus simples encore en usage est ASCII, qui a des mappages pour 128 caractères différents (0 à 127), car il utilise 7 bits pour coder chaque caractère. Étant donné que cela exclut de nombreux caractères accentués et symboles communs, les codages ultérieurs utilisent 8 bits et mappent les mêmes 128 premiers caractères, ajoutant au jeu de caractères en remplissant les positions 128 à 255. Parmi ceux-ci figurent les normes ISO 8859-1 et ISO 8859- 15 , et la page de codes Windows spécifique à Microsoft 1252 .
Donc, pour revenir à MS SQL Server: une "chaîne Unicode", telle qu'elle est stockée dans une
nchar
,nvarchar
ou unentext
colonne, peut représenter tous les caractères mappés dans le jeu de caractères Unicode, car elle utilise un codage Unicode pour stocker les données. Une « chaîne non Unicode », telle qu'elle est stockée dans unechar
,varchar
outext
colonne, peuvent représenter uniquement les caractères mis en correspondance dans un autre codage . Tout ce que vous pouvez stocker dans une colonne non Unicode peut également être stocké dans une colonne Unicode, mais pas l'inverse.Pour savoir exactement quels caractères vous pouvez stocker, vous devez connaître le "classement" utilisé, qui dicte ce que Microsoft appelle une "page de code", comme expliqué sur cette page de référence Microsoft . Il est probable que dans votre cas, vous utilisez la page de code très courante 1252, que j'ai mentionnée plus tôt.
Les caractères que vous avez mentionnés existent à la fois dans Unicode et dans la page de code 1252:
la source