Saltar al contenido

¿Por qué el tipo de datos varchar permite valores unicode?

Hemos buscando por distintos espacios para así mostrarte la respuesta a tu duda, si tienes alguna difcultad puedes dejarnos un comentario y respondemos porque estamos para servirte.

Solución:

Pero los símbolos de marca comercial (™) y registrada (®) son caracteres Unicode.

Estás equivocado aquí. Tus cadenas contienen solo ascii caracteres.

Aquí hay una prueba simple que le muestra que sus caracteres son todos ascii (+ algunos extended ascii con códigos ascii entre 128 y 255):

declare @VarcharUnicodeCheck table
(
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 *,
        right(col1, 1)as last_char, 
        ascii(right(col1, 1)) as_last_char_ascii
from @VarcharUnicodeCheck;

Aquí puede ver claramente que todos sus caracteres están codificados en 1 byte:

ingrese la descripción de la imagen aquí

Sí, no son caracteres ascii puros, pero son ASCII extendido.

Aquí les muestro carácter Unicode real Trademark(™) y su código y representación binaria:

declare @t table (uni_ch nchar(1), ascii_ch char(1));
insert into @t values (N'™', '™');

select unicode(uni_ch) as [unicode of ™], 
       ascii(ascii_ch) [ascii of ™], 
       cast(uni_ch as varbinary(10)) as [uni_ch as varbinary], 
       cast(ascii_ch as varbinary(10)) as [ascii_ch as varbinary]
from @t;

ingrese la descripción de la imagen aquí

Finalmente, puedes ver que Trademark(™) El carácter unicode tiene código 8482 y no 153:

select nchar(8482), nchar(153)

De los comentarios, estoy de acuerdo en que “ASCII extendido” es un término realmente malo que en realidad significa una página de códigos que mapea caracteres / puntos de código en el rango 128-255, más allá del rango estándar de puntos de código 0-127 definido por ASCII.

SQL Server admite muchas páginas de códigos mediante intercalaciones. Los caracteres que no son ASCII se pueden almacenar en varchar siempre que la intercalación subyacente admita el carácter.

El carácter ‘™’ se puede almacenar en columnas varchar / char cuando la página de códigos de clasificación de SQL Server es 1250 o superior. La consulta a continuación enumerará estos:

SELECT COLLATIONPROPERTY(name, 'CodePage') AS code_page, name, description
FROM sys.fn_helpcollations()
WHERE COLLATIONPROPERTY(name, 'CodePage') >= 1250
ORDER BY name;

Pero solo un subconjunto de estos también admite el carácter ‘©’, por lo que la intercalación de columnas deberá ser una de las siguientes para admitir ambos:

SELECT COLLATIONPROPERTY(name, 'CodePage') AS code_page, name, description
FROM sys.fn_helpcollations()
WHERE COLLATIONPROPERTY(name, 'CodePage') IN(
    1250
    ,1251
    ,1252
    ,1253
    ,1254
    ,1255
    ,1256
    ,1257
    ,1258
)
ORDER BY name;

Pero la definición de varchar dice que permite no unicode string datos. Pero los símbolos de marca comercial (™) y registrada (®) son Unicode caracteres. ¿La definición contradice la propiedad del tipo de datos varchar?

Si bien las otras respuestas no son incorrectas, creo que ayudaría señalar una confusión en la terminología básica. He enfatizado dos palabras en la cita anterior de la pregunta como ejemplo de esta confusión. Cuando la documentación de SQL Server habla de Unicode y no Unicode datos, son no hablando de la caracteres. Están hablando de las secuencias de bytes que representan ciertos caracteres. La principal diferencia entre los tipos Unicode (NCHAR, NVARCHAR, XML, y el desaprobado / malvado NTEXT) y los tipos no Unicode (CHAR, VARCHAR, y el desaprobado / malvado TEXT) qué es tipos de secuencias de bytes que pueden almacenar.

Los tipos que no son Unicode almacenan una de varias codificaciones de 8 bits, mientras que los tipos Unicode almacenan una única codificación Unicode de 16 bits: UTF-16 Little Endian. Como han mencionado las otras respuestas, qué caracteres se pueden almacenar en una codificación de 8 bits / no Unicode depende de la página de códigos, que está determinada por la clasificación. Mientras que otros han notado que el valor de byte de un “carácter” puede variar entre las páginas de códigos en las que se encuentra, el valor de byte puede incluso variar dentro de la misma página de códigos cuando se trata de una de las varias páginas de códigos EBCDIC (variaciones de Windows- 1252), que solo se encuentran en las intercalaciones de SQL Server más antiguas, que realmente no deberían usarse (es decir, las que tienen nombres que comienzan con SQL_).

Por lo tanto, la definición es precisa: todos los caracteres que pueda administrar para almacenar en un tipo que no es Unicode son siempre de 8 bits (incluso si usan dos valores de 8 bits en combinación como un solo “carácter”, que es lo que Double- Juego de caracteres de bytes / páginas de códigos DBCS permiten). Y los tipos de datos Unicode son siempre de 16 bits, incluso si a veces usan dos valores de 16 bits en combinación como un solo “carácter” (es decir, un par sustituto que a su vez representa un carácter suplementario).

Y, debido a que SQL Server admite de forma nativa la codificación UTF-8 para VARCHAR y CHAR tipos de datos a partir de SQL Server 2019,

VARCHAR ya no se puede denominar “no Unicode”. Entonces, comenzando con la primera versión beta pública de SQL Server 2019 en septiembre de 2018, deberíamos referirnos a VARCHAR como un “tipo de datos de 8 bits”, incluso cuando se habla en términos de versiones anteriores a SQL Server 2019. Esta terminología es válida true para los 4 tipos de codificaciones que se pueden utilizar con VARCHAR:

  1. ASCII extendido
  2. Juegos de caracteres de doble byte (DBCS)
  3. EBCDIC
  4. UTF-8 (Unicode)

Solo el TEXT El tipo de datos (obsoleto a partir de SQL Server 2005, así que no lo use) es “no Unicode”, pero eso es solo un tecnicismo, y referirse a él como un “tipo de datos de 8 bits” es exacto.

NVARCHAR, NCHAR, y NTEXT puede denominarse “UTF-16” o “tipo de datos de 16 bits”. Oracle, creo, utiliza la terminología de “solo Unicode” para NVARCHAR, pero eso no descarta claramente la posibilidad de usar UTF-8 (también una codificación Unicode), que no funcionará, por lo que probablemente sea mejor seguir con las dos primeras opciones.

Para obtener detalles sobre las nuevas codificaciones UTF-8, consulte mi publicación:

Compatibilidad nativa con UTF-8 en SQL Server 2019: ¿Salvador o falso profeta?

PD: Estoy trabajando lentamente para actualizar la documentación de SQL Server para reflejar estos cambios.

PPS Microsoft ya ha actualizado algunas páginas con información UTF-8, incluida la documentación de char y varchar a la que se hace referencia en la pregunta. Ya no contiene la frase “no Unicode”. Pero eso es solo un FYI; no cambia la pregunta, ya que se trata de codificaciones no Unicode que contienen caracteres que se pensó erróneamente que eran solo Unicode.

Comentarios y puntuaciones

Si guardas alguna sospecha o disposición de ascender nuestro reseña eres capaz de escribir un exégesis y con placer lo estudiaremos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *