¿El operador LIKE distingue entre mayúsculas y minúsculas con MSSQL Server?


99

En la documentación sobre el operador LIKE , no se dice nada sobre la distinción entre mayúsculas y minúsculas. ¿Lo es? ¿Cómo habilitarlo / deshabilitarlo?

Estoy consultando varchar(n)columnas, en una instalación de Microsoft SQL Server 2005, si eso importa.


14
Depende de la clasificación de su columna (o base de datos). Si LIKELIKE
distingue entre

Consulte la documentación sobre las intercalaciones de SQL-Server msdn.microsoft.com/en-us/library/ms144250%28v=sql.105%29.aspx
GarethD

¿Cuál es tu objetivo? ¿Quieres que distinga entre mayúsculas y minúsculas o no?
Aaron Bertrand

1
La distinción entre mayúsculas y minúsculas tiene como valor predeterminado la intercalación de la columna que, por defecto, es la de la base de datos. La mayoría de las veces se vuelve circular, ¿en qué dirección quieres ir?
Tony Hopkinson

Respuestas:


101

No es el operador el que distingue entre mayúsculas y minúsculas, es la propia columna.

Cuando se realiza una instalación de SQL Server, se elige una intercalación predeterminada para la instancia. A menos que se mencione explícitamente lo contrario (verifique la cláusula de clasificación a continuación), cuando se crea una nueva base de datos, hereda la clasificación de la instancia y cuando se crea una nueva columna, hereda la clasificación de la base de datos a la que pertenece.

Una colación como sql_latin1_general_cp1_ci_asdicta cómo se debe tratar el contenido de la columna. CI significa mayúsculas y minúsculas y AS significa acento sensible.

Una lista completa de intercalaciones está disponible en https://msdn.microsoft.com/en-us/library/ms144250(v=sql.105).aspx

(a) Para comprobar una colación de instancias

select serverproperty('collation')

(b) Para comprobar la intercalación de una base de datos

select databasepropertyex('databasename', 'collation') sqlcollation

(c) Para crear una base de datos usando una colación diferente

create database exampledatabase
collate sql_latin1_general_cp1_cs_as 

(d) Para crear una columna usando una colación diferente

create table exampletable (
    examplecolumn varchar(10) collate sql_latin1_general_cp1_ci_as null
)

(e) Para modificar una clasificación de columnas

alter table exampletable
alter column examplecolumn varchar(10) collate sql_latin1_general_cp1_ci_as null

Es posible cambiar las intercalaciones de una instancia y de una base de datos, pero no afecta a los objetos creados previamente.

También es posible cambiar una intercalación de columnas sobre la marcha para comparar cadenas, pero esto no es recomendable en un entorno de producción porque es extremadamente costoso.

select
  column1 collate sql_latin1_general_cp1_ci_as as column1
from table1

5
Parece que la gama de personajes como [A-Z]siempre es sensible a las mayúsculas. [ABCDEFGHIJKLMNOPQRSŠTUVWXYZŽÅÄÖ]sin embargo, parece obedecer a la colación.
jumxozizi

1
Además, puede consultar la distinción entre mayúsculas y minúsculas de una columna en particular con algo como esto:select COLLATION_NAME, iif(cast(COLLATIONPROPERTY(COLLATION_NAME, 'ComparisonStyle') as int) & 1 = 0, 'case sensitive', 'case insensitive') from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'exampletable' and COLUMN_NAME = 'examplecolumn'
Jeppe Stig Nielsen

@jumxozizi Agregué tu sugerencia a la respuesta.
John Zabroski

@JeppeStigNielsen Agregué tu sugerencia a la respuesta.
John Zabroski

18

Toda esta charla sobre colación parece un poco complicada. ¿Por qué no usar algo como:

IF UPPER(@@VERSION) NOT LIKE '%AZURE%'

Entonces su cheque no distingue entre mayúsculas y minúsculas sea cual sea la colación


10
Porque esto no es sargable. Su ejemplo usa una variable y un comodín inicial. Pero contra una columna indexada con una intercalación que no distingue entre mayúsculas y minúsculas, like 'a%'podría usar el índice y la upperversión no.
Martin Smith

3
La pregunta era si el likeoperador distingue entre mayúsculas y minúsculas.
jumxozizi

Necesita conocer la colación, de lo contrario, hacer esto podría no tener sentido. Por ejemplo, si la columna que se consulta contra usos Latin1_General_CI_AS, entonces hacer UPPER(@@VALUE) NOT LIKE '%SOMETHING%'o @@COLUMN NOT LIKE '%SOMETHING%'es irrelevante: el resultado sería el mismo.
rsenna

13

Tiene una opción para definir el orden de clasificación en el momento de definir su tabla. Si define un orden sensible a mayúsculas y minúsculas, su LIKEoperador se comportará de manera sensible a mayúsculas y minúsculas; Si define un orden de clasificación que no distingue entre mayúsculas y minúsculas, el LIKEoperador también ignorará las mayúsculas y minúsculas:

CREATE TABLE Test (
    CI_Str VARCHAR(15) COLLATE Latin1_General_CI_AS -- Case-insensitive
,   CS_Str VARCHAR(15) COLLATE Latin1_General_CS_AS -- Case-sensitive
);

Aquí hay una demostración rápida de sqlfiddle que muestra los resultados del orden de clasificación en las búsquedas con LIKE.


12

Si desea lograr una búsqueda sensible a mayúsculas y minúsculas sin cambiar la intercalación de la columna / base de datos / servidor, siempre puede usar la COLLATEcláusula, por ejemplo

USE tempdb;
GO
CREATE TABLE dbo.foo(bar VARCHAR(32) COLLATE Latin1_General_CS_AS);
GO
INSERT dbo.foo VALUES('John'),('john');
GO
SELECT bar FROM dbo.foo 
  WHERE bar LIKE 'j%';
-- 1 row

SELECT bar FROM dbo.foo 
  WHERE bar COLLATE Latin1_General_CI_AS LIKE 'j%';
-- 2 rows

GO    
DROP TABLE dbo.foo;

También funciona al revés, si su columna / base de datos / servidor distingue entre mayúsculas y minúsculas y no desea una búsqueda que distinga entre mayúsculas y minúsculas, por ejemplo

USE tempdb;
GO
CREATE TABLE dbo.foo(bar VARCHAR(32) COLLATE Latin1_General_CI_AS);
GO
INSERT dbo.foo VALUES('John'),('john');
GO
SELECT bar FROM dbo.foo 
  WHERE bar LIKE 'j%';
-- 2 rows

SELECT bar FROM dbo.foo 
  WHERE bar COLLATE Latin1_General_CS_AS LIKE 'j%';
-- 1 row

GO
DROP TABLE dbo.foo;

Tenga cuidado en la última consulta si la usa WHERE bar COLLATE Latin1_General_CS_AS LIKE '[j-k]%'devolverá Johnya que en esta intercalación el capital Jestá entre minúsculas jy minúsculas k. Es como si aAbBcC...jJkKlLmM...no fuera obvio. Parece que Latin1_General_BINes más predecible con búsquedas de rango con operador LIKE.
wqw

7

El likeoperador toma dos cuerdas. Estas cadenas deben tener intercalaciones compatibles, como se explica aquí .

En mi opinión, las cosas se complican luego. La siguiente consulta devuelve un error que indica que las intercalaciones son incompatibles:

select *
from INFORMATION_SCHEMA.TABLES
where 'abc' COLLATE SQL_Latin1_General_CP1_CI_AS like 'ABC' COLLATE SQL_Latin1_General_CP1_CS_AS

En una máquina aleatoria aquí, la intercalación predeterminada es SQL_Latin1_General_CP1_CI_AS. La siguiente consulta es correcta, pero no devuelve filas:

select *
from INFORMATION_SCHEMA.TABLES
where 'abc' like 'ABC' COLLATE SQL_Latin1_General_CP1_CS_AS

Los valores "abc" y "ABC" no coinciden en un mundo sensible a mayúsculas y minúsculas.

En otras palabras, existe una diferencia entre no tener colación y usar la colación predeterminada. Cuando un lado no tiene colación, entonces se le "asigna" una colación explícita del otro lado.

(Los resultados son los mismos cuando la intercalación explícita está a la izquierda).


¿Puede reproducir el error en una tabla que NO sea un objeto del sistema como INFORMATION_SCHEMA.TABLES?
Aaron Bertrand

@AaronBertrand. . . Sí, puedo. ¿Está rota la base de datos;)?
Gordon Linoff

No sé, estoy en un dispositivo móvil en este momento y no puedo activar una máquina virtual de Windows. Simplemente no sé si su descripción completa es técnicamente precisa.
Aaron Bertrand

4

Intenta correr

SELECT SERVERPROPERTY('COLLATION')

Luego, averigüe si su intercalación distingue entre mayúsculas y minúsculas o no.



0

Puede cambiar fácilmente la intercalación en Microsoft SQL Server Management Studio.

  • tabla de clic derecho -> diseño.
  • elija su columna, desplácese hacia abajo las propiedades de la columna i hasta Colación.
  • Establezca su preferencia de clasificación marcando "Sensible a mayúsculas y minúsculas"
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.