Cuando intentamos seleccionar el nombre ASCII, también regresa la versión Unicode.
Esta declaración es un malentendido sobre cómo funcionan las codificaciones. ASCII es una codificación de 8 bits y un conjunto de caracteres. Tiene valores de 0 a 127 y es común en la mayoría de las páginas de códigos y Unicode. Sin embargo, en realidad solo se aplica a los datos de VARCHAR
. Al usar NVARCHAR
, todos los caracteres son Unicode, incluso si esos caracteres se encuentran en otros juegos de caracteres. Así que aquí, solo se devuelven caracteres Unicode ya que NVARCHAR
solo contiene caracteres Unicode (codificados como UTF-16 Little Endian). Da la casualidad de que el conjunto de caracteres ASCII se duplicó como un subconjunto de Unicode.
Es decir, lo que realmente estás diciendo aquí es que solo quieres los caracteres latinos regulares, no la versión de ancho completo.
Parece que SQL Server asigna versiones basadas en Unicode de cada letra a su variante ASCII.
Sí y no. Windows y SQL Server pueden asignar caracteres Unicode a caracteres de apariencia similar dentro de una página de códigos de 8 bits, pero eso solo ocurre cuando se convierte una cadena Unicode en una página de códigos de 8 bits (o de una página de códigos a otra). otro). Eso no está pasando aquí. Aquí, nuevamente, solo está tratando con Unicode. Da la casualidad de que las formas regulares y de ancho completo del alfabeto inglés de EE. UU. se consideran iguales cuando la intercalación es sensible al ancho In. Y según su pregunta y el caso de prueba (dos cosas separadas, ya que la intercalación de una columna se usa cuando se consulta una columna, pero la intercalación predeterminada de la base de datos se usa cuando se trata solo de literales de cadena y/o variables), está claro que las intercalaciones que usted están usando (que podrían ser la misma intercalación) son anchos insensibles.
Para solucionar esto, no utilice una intercalación binaria. El uso de una intercalación binaria es la respuesta de acceso desafortunada y comúnmente aceptada para corregir consultas cuando las personas obtienen más coincidencias de las que esperaban. Y a veces es la respuesta correcta, pero la mayoría de las veces, como con esta pregunta, no lo es.
Simplemente necesita agregar "sensibilidad de ancho" a la intercalación que está utilizando. Puede encontrar la intercalación de la columna con la siguiente consulta, simplemente complete el nombre de la tabla y el nombre de la columna correctos:
SELECT col.[collation_name]
FROM sys.columns col
WHERE col.[object_id] = OBJECT_ID(N'<schema_name>.<table_name>')
AND col.[name] = N'<column_name>';
Si la Intercalación es una Intercalación de Windows (es decir, el nombre no comienza con SQL_
), entonces podría agregar _WS
a la final del nombre de la colación. Por ejemplo:
Latin1_General_100_CS_AS
--> Latin1_General_100_CS_AS_WS
Si la intercalación es una intercalación de SQL Server (es decir, el nombre sí comienza con SQL_
), ninguno de ellos permite la sensibilidad al ancho y debe elegir una intercalación de Windows equivalente. Si la Intercalación es SQL_Latin1_General_CP1_*
, intente lo mismo comenzando con Latin1_General_100_
.
-- current Collation (no width sensitivity)
SELECT CASE WHEN N'Word' = N'Word' COLLATE Latin1_General_100_CI_AS THEN 1
ELSE 0 END;
-- 1
-- add width sensitivity
SELECT CASE WHEN N'Word' = N'Word' COLLATE Latin1_General_100_CI_AS_WS THEN 1
ELSE 0 END;
-- 0
-- confirm case INsensitivity
SELECT CASE WHEN N'WORD' = N'Word' COLLATE Latin1_General_100_CI_AS_WS THEN 1
ELSE 0 END;
-- 1
Para obtener más detalles sobre por qué primero debe intentar obtener la sensibilidad correcta antes de usar una intercalación binaria, consulte la siguiente publicación mía:
No, las intercalaciones binarias no son Se distingue entre mayúsculas y minúsculas