2013-02-19 16 views
64

Nel documentation about the LIKE operator, non viene indicato nulla sulla distinzione tra maiuscole e minuscole. È? Come abilitarlo/disabilitarlo?L'operatore LIKE fa distinzione tra maiuscole e minuscole con MSSQL Server?

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

+9

Dipende dalla collazione della colonna (o database). Se è sensibile al maiuscolo/minuscolo, allora 'LIKE' è case sensitive, se non lo è, allora' LIKE' non è – Lamak

+0

Controlla la documentazione sulle collations SQL-Server http://msdn.microsoft.com/en-us/library/ms144250 % 28v = sql.105% 29.aspx – GarethD

+0

Qual è il tuo obiettivo? Vuoi distinguere tra maiuscole e minuscole o maiuscole e minuscole? –

risposta

69

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

Quando viene eseguita un'installazione di SQL Server, viene scelta una collazione predefinita per l'istanza. A meno che non venga esplicitamente indicato diversamente (controllare la clausola di confronto) quando viene creato un nuovo database, esso 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 come sql_latin1_general_cp1_ci_as stabilisce come deve essere trattato il contenuto della colonna. CI sta per case insensitive e AS sta per accent sensitivo.

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

(a) Per controllare un metodo di confronto esempio

select serverproperty('collation') 

(b) Per controllare le regole di confronto del database

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

(c) Per creare un database ci ing un confronto diverso

create database exampledatabase 
collate sql_latin1_general_cp1_cs_as 

(d) Per creare una colonna con un confronto diverso

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

(e) Per modificare una collazione colonna

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

Si è possibile modificare un'istanza e le regole di confronto del database ma non influisce sulla creazione precedente d oggetti.

È anche possibile modificare una confronto di colonne al volo per il confronto delle stringhe, ma questo è altamente sconsigliato in un ambiente di produzione perché è estremamente costoso.

select 
    column1 collate sql_latin1_general_cp1_ci_as as column1 
from table1 
+2

Sembra che l'intervallo di caratteri come '[A-Z]' sia sempre insensibile al maiuscolo/minuscolo. '[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 tipo: 'seleziona COLLATION_NAME, iif (cast (COLLATIONPROPERTY (COLLATION_NAME, 'ComparisonStyle') come int) & 1 = 0, 'case sensitive', 'case insensitive ') da INFORMATION_SCHEMA.COLUMNS dove TABLE_NAME =' exampletable 'e COLUMN_NAME =' examplecolumn'' –

2

provare a eseguire,

SELECT SERVERPROPERTY('COLLATION') 

Poi scoprire se la vostra collazione è case sensitive o meno.

13

Si ha un'opzione per definire l'ordine di confronto al momento della definizione della tabella. Se si definisce un ordine con distinzione tra maiuscole e minuscole, l'operatore LIKE si comporterà in base alla distinzione tra maiuscole e minuscole; se si definisce un ordine di confronto maiuscole e minuscole, l'operatore LIKE ignorerà caso carattere così:

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 quick demo on sqlfiddle mostra i risultati di ordine di collazione sulle ricerche con LIKE.

8

Se si vuole raggiungere un caso di ricerca sensibili senza cambiare le regole di confronto della colonna/database/server, è sempre possibile utilizzare la clausola COLLATE, per esempio

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 senso, anche se la vostra colonna/database/server è case sensitive e non si vuole un caso di ricerca sensibili, per esempio

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; 
+0

Attenzione nell'ultima query se si utilizza 'WHERE bar COLLATE Latin1_General_CS_AS LIKE '[jk]%'' restituirà 'John' come in questo capitale di confronto 'J' è tra minuscolo' j' e minuscolo 'k'. È come 'aAbBcC ... jJkKlLmM ...' che non è ovvio. Sembra che 'Latin1_General_BIN' sia più prevedibile con le ricerche di intervallo con l'operatore LIKE. – wqw

3

L'operatore like accetta due stringhe. Queste stringhe devono avere regole di confronto compatibili, come spiegato here.

A mio parere, le cose si complicano. La query seguente restituisce un errore dicendo che le regole di confronto sono incompatibili:

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 a caso qui, le regole di confronto di default è SQL_Latin1_General_CP1_CI_AS. La seguente query è successo, 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 sensitve e minuscole.

In altre parole, c'è una differenza tra non avere regole di confronto e utilizzare le regole di confronto predefinite. Quando una parte non ha regole di confronto, viene "assegnata" una collazione esplicita dall'altra parte.

(I risultati sono gli stessi quando il confronto esplicito si trova sulla sinistra.)

+0

Riesci a riprodurre l'errore su una tabella che NON è un oggetto di sistema come INFORMATION_SCHEMA.TABLES? –

+0

@AaronBertrand. . . Sì posso. Il database è rotto;)? –

+0

Non so, sono su un dispositivo mobile in questo momento e non posso avviare una VM Windows. Semplicemente non so che la tua descrizione è tecnicamente accurata. –

12

Tutto questo parlare di regole di confronto sembrano un po 'troppo complicato. Perché non usare qualcosa di simile:

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

Allora il tuo assegno è case insensitive qualunque sia il confronto

+6

Perché questo non è sargibile. Il tuo esempio utilizza una variabile e un carattere jolly principale. Ma contro una colonna indicizzata con regole di confronto insensibili al maiuscolo 'come' a% ''potrebbe usare l'indice e la versione' upper' non può. –

+1

La domanda era se l'operatore 'like' rispetta la distinzione tra maiuscole e minuscole. – jumxozizi

Problemi correlati