¿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
¿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
Respuestas:
En la configuración predeterminada de una base de datos de SQL Server, las comparaciones de cadenas no distinguen entre mayúsculas y minúsculas. Si su base de datos anula esta configuración (mediante el uso de una intercalación alternativa), deberá especificar qué tipo de intercalación utilizar en su consulta.
SELECT * FROM myTable WHERE myField = 'sOmeVal' COLLATE SQL_Latin1_General_CP1_CI_AS
Tenga en cuenta que la intercalación que proporcioné es solo un ejemplo (aunque es más que probable que funcione bien para usted). Puede encontrar un esquema más completo de las intercalaciones de SQL Server aquí .
UPPER
o LOWER
mayúsculas y luego usar LIKE
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 = 'billg@microsoft.com'
COLLATE SQL_Latin1_General_CP1_CI_AS
Encontré otra solución en otro lugar; es decir, usar
upper(@yourString)
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.
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 una COLLATE
cláusula. Se debe realizar una comparación de cadenas en cualquier caso, pero el uso UPPER()
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. Agregar COLLATE
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. Usar COLLATE
es definitivamente más eficiente (o "performante", si le gusta esa palabra :) que usar UPPER()
, como se demuestra en este script de prueba (en PasteBin) .
También está el problema señalado por @Ceisc en la respuesta de @ Danny:
En algunos idiomas, las conversiones de casos no son de ida y vuelta. es decir, INFERIOR (x)! = INFERIOR (SUPERIOR (x)).
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
(p convert(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 son NVARCHAR
, no importa qué configuración regional use, ya que todos son iguales en ese caso, por Latin1_General_100_BIN2
lo tanto, siempre funciona. Si los datos son VARCHAR
, debe utilizar la misma configuración regional que los datos están actualmente en (por ejemplo Latin1_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 la COLLATE
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 si COLLATE
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ía Latin1_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
No, solo usarlo LIKE
no funcionará. LIKE
busca valores que coincidan exactamente con su patrón dado. En este caso LIKE
, 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.).
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')
¿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.
WHERE
declaración, y afectará a todas lasWHERE
cláusulas, ¿correcto?