Comparación de cadenas sensibles a mayúsculas y minúsculas SQL

234

¿Cómo se comparan las cadenas para que la comparación sea verdadera solo si los casos de cada una de las cadenas también son iguales? Por ejemplo:

Select * from a_table where attribute = 'k'

... devolverá una fila con un atributo de 'K'. No quiero este comportamiento.

amccormack
fuente
Puede que no sea lo que necesita, pero puede cambiar la Clasificación o usar una Clasificación específica en su consulta.
Kane
77
¿Qué producto SQL?
cuando el

Respuestas:

388
Select * from a_table where attribute = 'k' COLLATE Latin1_General_CS_AS 

Hizo el truco.

amccormack
fuente
44
Normalmente usaría Latin1_General_Bin
gbn
3
Sí, el enfoque estándar es utilizar una intercalación sin distinción entre mayúsculas y minúsculas, aunque las colaciones en sí son específicas del proveedor. ¿Es su sintaxis SQL Server?
cuando el
En mi caso, tengo 1 columna en mi base de datos que distingue entre mayúsculas y minúsculas. Necesitaba compararlo con una columna estándar (CI). Usé una variación de este DONDE Foo.Bar = (Baz.Bar COLLATE Latin1_General_CS_AS)
Hypnovirus
2
Gracias, pero ¿qué es Latin1_General_CS_AS? ¿Es una palabra clave especial?
Vijay Singh Rana
2
@VijaySinghRana Latin1_General_CS_ASes una especificación de la recopilación. La clasificación se refiere a un conjunto de reglas que determinan cómo se ordenan y comparan los datos. Vea esta página para más información.
amccormack
51

También puede convertir ese atributo como mayúsculas y minúsculas utilizando esta sintaxis:

ALTER TABLE Table1
ALTER COLUMN Column1 VARCHAR(200)
COLLATE SQL_Latin1_General_CP1_CS_AS

Ahora su búsqueda será sensible a mayúsculas y minúsculas .

Si desea volver a hacer que esa columna no sea ​​sensible a mayúsculas y minúsculas , use

ALTER TABLE Table1
ALTER COLUMN Column1 VARCHAR(200)
COLLATE SQL_Latin1_General_CP1_CI_AS
Yugal
fuente
29

Puede convertir fácilmente columnas a VARBINARIO (longitud máxima). La longitud debe ser la máxima que espera para evitar una comparación defectuosa. Es suficiente establecer la longitud como la longitud de la columna. Recortar columna le ayuda a comparar el valor real, excepto que el espacio tiene un significado y está valorado en las columnas de su tabla. Esta es una muestra simple y, como puede ver, recorto el valor de las columnas y luego convierto y comparo .:

CONVERT(VARBINARY(250),LTRIM(RTRIM(Column1))) = CONVERT(VARBINARY(250),LTRIM(RTRIM(Column2)))

Espero que esto ayude.

QMaster
fuente
2
Exactamente lo que estaba buscando. Una forma sencilla de hacer una comparación única y sensible a mayúsculas y minúsculas para buscar entradas que contengan mayúsculas.
Mike D.
20

Como otra alternativa, podría usar HASHBYTES, algo como esto:

SELECT * 
FROM a_table 
WHERE HASHBYTES('sha1', attribute) = HASHBYTES('sha1', 'k')
Dave Sexton
fuente
1
¿Qué pasa con las colisiones? Sería raro, pero supongo que habría varias cadenas que se combinan con el mismo valor.
David Klempfner el
Sí posible, pero extremadamente raro en un ejemplo de cadena tan simple que habría pensado.
Dave Sexton el
@DavidKlempfner, ¿por qué no hacer primero la comparación y, si coinciden, también buscar hashbytes? Podríamos hacer esto una función e invocarlo como StringsAreCaseSensitiveEqual (a, b) => a = by AND HASHBYTES ('sha1', a) = HASHBYTES ('sha1', b)
Demetris Leptos
3

Puede definir attributecomo BINARYo usar INSTRo STRCMPpara realizar su búsqueda.

MatTheCat
fuente
Esta respuesta no parece ser sobre SQL Server según la etiqueta de pregunta. Ese DBMS carece de estas INSTRy STRCMPfunciones.
Jonas