¿Cómo construyo una consulta SQL (MS SQL Server) donde la cláusula "where" no distingue entre mayúsculas y minúsculas?
SELECT * FROM myTable WHERE myField = 'sOmeVal'
Quiero que los resultados vuelvan ignorando el caso
sql
sql-server
where-clause
case-insensitive
Raúl Agrait
fuente
fuente
WHERE
declaración, y afectará a todas lasWHERE
cláusulas, ¿correcto?UPPER
oLOWER
mayúsculas y luego usarLIKE
para buscar?Por lo general, las comparaciones de cadenas no distinguen entre mayúsculas y minúsculas. Si su base de datos está configurada para la intercalación que distingue entre mayúsculas y minúsculas, debe forzar el uso de una que no distinga entre mayúsculas y minúsculas:
SELECT balance FROM people WHERE email = '[email protected]' COLLATE SQL_Latin1_General_CP1_CI_AS
fuente
Encontré otra solución en otro lugar; es decir, usar
pero todo el mundo aquí está diciendo que, en SQL Server, ¿no importa porque de todos modos está ignorando el caso? Estoy bastante seguro de que nuestra base de datos distingue entre mayúsculas y minúsculas.
fuente
Las 2 respuestas principales (de Adam Robinson y Andrejs Cainikovs ) son un poco correctas, ya que técnicamente funcionan, pero sus explicaciones son incorrectas y, por lo tanto, pueden ser engañosas en muchos casos. Por ejemplo, aunque la
SQL_Latin1_General_CP1_CI_AS
intercalación funcionará en muchos casos, no se debe suponer que sea la intercalación adecuada que no distingue entre mayúsculas y minúsculas. De hecho, dado que el OP está trabajando en una base de datos con una intercalación sensible a mayúsculas y minúsculas (o posiblemente binaria), sabemos que el OP no está utilizando la intercalación que es la predeterminada para tantas instalaciones (especialmente las instaladas en un sistema operativo) utilizando estadounidense Inglés como idioma):SQL_Latin1_General_CP1_CI_AS
. Claro, el OP podría estar usandoSQL_Latin1_General_CP1_CS_AS
, pero cuando se trabaja conVARCHAR
datos, es importante no cambiar la página de códigos, ya que podría provocar la pérdida de datos, y eso está controlado por la configuración regional / cultura de la intercalación (es decir, Latin1_General vs French vs Hebrew, etc.). Consulte el punto 9 a continuación.Las otras cuatro respuestas son incorrectas en diversos grados.
Aclararé todos los malentendidos aquí para que los lectores puedan tomar las decisiones más apropiadas / eficientes.
No usar
UPPER()
. Eso es un trabajo extra completamente innecesario. Usa unaCOLLATE
cláusula. Se debe realizar una comparación de cadenas en cualquier caso, pero el usoUPPER()
también debe verificar, carácter por carácter, para ver si hay una asignación en mayúsculas y luego cambiarla. Y necesitas hacer esto en ambos lados. AgregarCOLLATE
simplemente dirige el procesamiento para generar las claves de clasificación utilizando un conjunto de reglas diferente al que iba a utilizar de forma predeterminada. UsarCOLLATE
es definitivamente más eficiente (o "performante", si le gusta esa palabra :) que usarUPPER()
, como se demuestra en este script de prueba (en PasteBin) .También está el problema señalado por @Ceisc en la respuesta de @ Danny:
La mayúscula turca "İ" es el ejemplo común.
No, la intercalación no es una configuración para toda la base de datos, al menos no en este contexto. Existe una intercalación predeterminada en el nivel de la base de datos, y se usa como predeterminada para las columnas alteradas y recién creadas que no especifican la
COLLATE
cláusula (que es probablemente de donde proviene este error común), pero no afecta las consultas directamente a menos que usted esté comparar literales de cadena y variables con otras variables y literales de cadena, o está haciendo referencia a metadatos a nivel de base de datos.No, la intercalación no es por consulta.
Las intercalaciones son por predicado (es decir, algo operando algo) o expresión, no por consulta. Y esto es cierto para toda la consulta, no solo para la
WHERE
cláusula. Esto cubre JOINs, GROUP BY, ORDER BY, PARTITION BY, etc.No, no convierta a
VARBINARY
(pconvert(varbinary, myField) = convert(varbinary, 'sOmeVal')
. Ej. ) Por las siguientes razones:_BIN2
si está usando SQL Server 2008 o una versión más reciente; de lo contrario, no tendrá más remedio que usar uno que termine con_BIN
. Si los datos lo sonNVARCHAR
, no importa qué configuración regional use, ya que todos son iguales en ese caso, porLatin1_General_100_BIN2
lo tanto, siempre funciona. Si los datos sonVARCHAR
, debe utilizar la misma configuración regional que los datos están actualmente en (por ejemploLatin1_General
,French
,Japanese_XJIS
, etc.), ya que la configuración regional determina la página de códigos que se utiliza, y el cambio de páginas de códigos puede alterar los datos (es decir, pérdida de datos).CONVERT()
él, usará el valor predeterminado de 30. El peligro es que si la cadena puede tener más de 30 bytes, se truncará silenciosamente y es probable que obtenga resultados incorrectos de este predicado.No,
LIKE
no siempre distingue entre mayúsculas y minúsculas. Utiliza la intercalación de la columna a la que se hace referencia, o la intercalación de la base de datos si una variable se compara con un literal de cadena, o la intercalación especificada mediante laCOLLATE
cláusula opcional .LCASE
no es una función de SQL Server. Parece ser Oracle o MySQL. ¿O posiblemente Visual Basic?Dado que el contexto de la pregunta es comparar una columna con un literal de cadena, ni la intercalación de la instancia (a menudo denominada "servidor") ni la intercalación de la base de datos tienen ningún impacto directo aquí. Las intercalaciones se almacenan por cada columna, y cada columna puede tener una intercalación diferente, y esas intercalaciones no necesitan ser las mismas que la intercalación predeterminada de la base de datos o la intercalación de la instancia. Claro, la intercalación de instancias es la predeterminada para lo que una base de datos recién creada usará como su intercalación predeterminada si la
COLLATE
cláusula no se especificó al crear la base de datos. Y del mismo modo, la intercalación predeterminada de la base de datos es lo que utilizará una columna modificada o recién creada siCOLLATE
no se especificó la cláusula.Debe utilizar la intercalación que no distingue entre mayúsculas y minúsculas, que por lo demás es la misma que la intercalación de la columna. Utilice la siguiente consulta para encontrar la intercalación de la columna (cambie el nombre de la tabla y el nombre del esquema):
SELECT col.* FROM sys.columns col WHERE col.[object_id] = OBJECT_ID(N'dbo.TableName') AND col.[collation_name] IS NOT NULL;
Entonces solo cambia el
_CS
to be_CI
. Entonces,Latin1_General_100_CS_AS
se convertiríaLatin1_General_100_CI_AS
.Si la columna usa una intercalación binaria (terminada en
_BIN
o_BIN2
), busque una intercalación similar usando la siguiente consulta:SELECT * FROM sys.fn_helpcollations() col WHERE col.[name] LIKE N'{CurrentCollationMinus"_BIN"}[_]CI[_]%';
Por ejemplo, asumiendo que la columna está usando
Japanese_XJIS_100_BIN2
, haga esto:SELECT * FROM sys.fn_helpcollations() col WHERE col.[name] LIKE N'Japanese_XJIS_100[_]CI[_]%';
Para obtener más información sobre intercalaciones, codificaciones, etc., visite: Información de intercalaciones
fuente
No, solo usarlo
LIKE
no funcionará.LIKE
busca valores que coincidan exactamente con su patrón dado. En este casoLIKE
, solo encontraría el texto 'sOmeVal' y no 'someval'.Una solución práctica es usar la
LCASE()
función.LCASE('sOmeVal')
obtiene la cadena en minúsculas de su texto: 'someval'. Si usa esta función para ambos lados de su comparación, funciona:SELECT * FROM myTable WHERE LCASE(myField) LIKE LCASE('sOmeVal')
La declaración compara dos cadenas en minúsculas, de modo que su 'sOmeVal' coincidirá con cualquier otra notación de 'someval' (por ejemplo, 'Someval', 'sOMEVAl', etc.).
fuente
LCASE()
en SQL Server (al menos no que yo pueda ver). Creo que esta respuesta es para un RDBMS completamente diferente. Consulte mi respuesta para obtener una aclaración sobre las comparaciones de cadenas.Puede forzar la distinción entre mayúsculas y minúsculas, lanzando a un varbinary como ese:
SELECT * FROM myTable WHERE convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
fuente
¿En qué base de datos estás? Con MS SQL Server, es una configuración para toda la base de datos, o puede anularla por consulta con la palabra clave COLLATE.
fuente