L'operatore LIKE fa distinzione tra maiuscole e minuscole con MSSQL Server?


99

Nella documentazione relativa all'operatore LIKE , non viene detto nulla sulla distinzione tra maiuscole e minuscole. È? Come abilitarlo / disabilitarlo?

Sto interrogando le varchar(n)colonne, su un'installazione di Microsoft SQL Server 2005, se questo è importante.


14
Dipende dalle regole di confronto della colonna (o del database). Se distingue tra maiuscole e minuscole, LIKEfa distinzione tra maiuscole e minuscole, se non lo è, allora LIKEnon lo è
Lamak

Controllare la documentazione sulle regole di confronto di SQL-Server msdn.microsoft.com/en-us/library/ms144250%28v=sql.105%29.aspx
GarethD

Qual è il tuo obiettivo? Vuoi che sia sensibile al maiuscolo / minuscolo o non sensibile al maiuscolo / minuscolo?
Aaron Bertrand

1
La distinzione tra maiuscole e minuscole viene impostata per impostazione predefinita sulle regole di confronto nella colonna, che per impostazione predefinita è quella sul database. È per lo più arrotondabile, in che modo vuoi andare?
Tony Hopkinson

Risposte:


101

Non è l'operatore che distingue tra maiuscole e minuscole, è la colonna stessa.

Quando viene eseguita un'installazione di SQL Server, viene scelto un confronto predefinito per l'istanza. Salvo diversa indicazione esplicita (controllare la clausola collate sotto) quando viene creato un nuovo database, eredita le regole di confronto dall'istanza e quando viene creata una nuova colonna eredita le regole di confronto dal database a cui appartiene.

Un confronto simile sql_latin1_general_cp1_ci_asdetermina come deve essere trattato il contenuto della colonna. CI sta per case insensitive e AS sta per accent sensitive.

Un elenco completo delle regole di confronto è disponibile su https://msdn.microsoft.com/en-us/library/ms144250(v=sql.105).aspx

(a) Per controllare le regole di confronto di un'istanza

select serverproperty('collation')

(b) Per controllare le regole di confronto del database

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

(c) Per creare un database utilizzando un confronto diverso

create database exampledatabase
collate sql_latin1_general_cp1_cs_as 

(d) Per creare una colonna utilizzando regole di confronto diverse

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

(e) Per modificare le regole di confronto di una colonna

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

È possibile modificare un'istanza e le regole di confronto del database ma non influisce sugli oggetti creati in precedenza.

È anche possibile modificare al volo le regole di confronto di una colonna per il confronto delle stringhe, ma ciò è altamente sconsigliato in un ambiente di produzione perché è estremamente costoso.

select
  column1 collate sql_latin1_general_cp1_ci_as as column1
from table1

5
Sembra che la gamma di caratteri come [A-Z]è sempre senza distinzione tra maiuscole e minuscole. [ABCDEFGHIJKLMNOPQRSŠTUVWXYZŽÅÄÖ]tuttavia sembra obbedire alle regole di confronto.
jumxozizi

1
Inoltre, puoi interrogare la distinzione tra maiuscole e minuscole di una particolare colonna con qualcosa del genere: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 ho aggiunto il tuo suggerimento alla risposta.
John Zabroski

@JeppeStigNielsen ho aggiunto il tuo suggerimento alla risposta.
John Zabroski

18

Tutto questo parlare di regole di confronto sembra un po 'troppo complicato. Perché non usare semplicemente qualcosa come:

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

Quindi il tuo assegno non fa distinzione tra maiuscole e minuscole indipendentemente dalle regole di confronto


10
Perché questo non è valutabile. Il tuo esempio utilizza una variabile e un carattere jolly iniziale. Ma contro una colonna indicizzata con un confronto senza distinzione tra maiuscole e minuscole like 'a%'potrebbe usare l'indice e la upperversione no.
Martin Smith

3
La domanda era se l' likeoperatore fosse o meno sensibile al maiuscolo / minuscolo.
jumxozizi

Devi conoscere le regole di confronto, altrimenti farlo potrebbe essere inutile. Ad esempio, se la colonna viene interrogata sugli usi Latin1_General_CI_AS, allora fare UPPER(@@VALUE) NOT LIKE '%SOMETHING%'o @@COLUMN NOT LIKE '%SOMETHING%'è irrilevante: il risultato sarebbe lo stesso.
rsenna

13

Hai un'opzione per definire l' ordine di confronto al momento della definizione della tabella. Se definisci un ordine con distinzione tra maiuscole e minuscole, il tuo LIKEoperatore si comporterà in modo sensibile al maiuscolo / minuscolo; se si definisce un ordine di confronto senza distinzione tra maiuscole e minuscole, l' LIKEoperatore ignorerà anche le maiuscole / minuscole:

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
);

Ecco una rapida demo su sqlfiddle che mostra i risultati dell'ordine di confronto nelle ricerche con LIKE.


12

Se si desidera ottenere una ricerca con distinzione tra maiuscole e minuscole senza modificare le regole di confronto della colonna / database / server, è sempre possibile utilizzare la COLLATEclausola, ad es.

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;

Funziona anche nell'altro modo, se la tua colonna / database / server fa distinzione tra maiuscole e minuscole e non vuoi una ricerca sensibile al maiuscolo / minuscolo, ad es

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;

Fai attenzione nell'ultima query se la usi WHERE bar COLLATE Latin1_General_CS_AS LIKE '[j-k]%'tornerà Johncome in questo confronto il capitale Jè tra minuscolo je minuscolo k. È come aAbBcC...jJkKlLmM...se non fosse ovvio. Sembra che Latin1_General_BINsia più prevedibile con le ricerche di intervallo con l'operatore LIKE.
wqw

7

L' likeoperatore prende due stringhe. Queste stringhe devono avere regole di confronto compatibili, come spiegato qui .

Secondo me le cose poi si complicano. La seguente query restituisce un errore che indica che le regole di confronto non sono compatibili:

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

Su una macchina casuale qui, le regole di confronto predefinite sono SQL_Latin1_General_CP1_CI_AS. La seguente query ha esito positivo, ma non restituisce alcuna riga:

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

I valori "abc" e "ABC" non corrispondono in un mondo sensibile al maiuscolo / minuscolo.

In altre parole, esiste una differenza tra l'assenza di regole di confronto e l'utilizzo delle regole di confronto predefinite. Quando un lato non ha regole di confronto, gli viene "assegnata" una regola di confronto esplicita dall'altra parte.

(I risultati sono gli stessi quando le regole di confronto esplicite sono a sinistra.)


Puoi riprodurre l'errore su una tabella che NON è un oggetto di sistema come INFORMATION_SCHEMA.TABLES?
Aaron Bertrand

@AaronBertrand. . . Sì posso. Il database è danneggiato;)?
Gordon Linoff

Non so, al momento sono su un dispositivo mobile e non riesco a far girare una VM Windows. Non so se la tua intera descrizione sia tecnicamente accurata.
Aaron Bertrand

4

Prova a correre,

SELECT SERVERPROPERTY('COLLATION')

Quindi scopri se le tue regole di confronto fanno distinzione tra maiuscole e minuscole o meno.



0

È possibile modificare facilmente le regole di confronto in Microsoft SQL Server Management Studio.

  • tabella clic destro -> design.
  • scegli la tua colonna, scorri verso il basso le proprietà della colonna fino a Collation.
  • Imposta la tua preferenza di ordinamento selezionando "Case Sensitive"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.