Selezione insensibile al maiuscolo / minuscolo di MySQL


242

Qualcuno può dirmi se una SELECTquery MySQL è case sensitive o case sensitive per impostazione predefinita? In caso contrario, quale query dovrei inviare in modo da poter fare qualcosa del tipo:

SELECT * FROM `table` WHERE `Value` = "iaresavage"

Dove in realtà, il vero valore di Valueè IAreSavage.


44
In definitiva dipende dalle regole di confronto archiviate - se è "_ci" (senza distinzione tra maiuscole e minuscole) o "_cs" (con distinzione tra maiuscole e minuscole)
Jovan Perovic,

15
Questa è una domanda scarsamente formulata;). La metà delle risposte ti mostra come fare un confronto senza distinzione tra maiuscole e minuscole, la metà punta su maiuscole e minuscole. E solo 1 ti dice che l'impostazione predefinita non è sensibile al maiuscolo / minuscolo. :) Vale la pena notare che l'insensibilità al case funziona anche quando si fa un confronto come'value' in ('val1', 'val2', 'val3')
SaltyNuts

5
@SaltyNuts amico, leggendo questa domanda 7 anni dopo e rendendomi conto di quanto fossi un imbarazzante è imbarazzante! Avrei potuto semplicemente leggere la documentazione e la risposta è come la prima frase sulle istruzioni SELECT ...
NoodleOfDeath

Per aggiungere ciò che ha detto @JovanPerovic, utf8_bin lo rende sensibile al maiuscolo / minuscolo. Non sono sicuro che esistesse allora
Chiwda

Risposte:


494

Non fanno distinzione tra maiuscole e minuscole , a meno che non si faccia un confronto binario .


3
Per lo più concordo con il commento di Tim, non penso che fare un "più basso ()" sui tuoi valori ovunque sia il modo migliore per gestirlo, sembra una soluzione alternativa. Ma lo ammetto a volte ha senso ed è più facile. (Colin ha menzionato che fascicolare era migliore) Avevamo spostato i dati storici nella tabella mysql che ha rotto la logica legacy a causa di alcuni valori di colonna con case insensibili. Avevamo bisogno di conoscere la differenza tra "GE1234" e "ge1234", dovevano essere unici e rimanere registrati in quel modo. Impostiamo invece la nostra colonna in create table statement in questo modo: varchar (20) SET DI CARATTERI utf8 COLLATE utf8_bin
gregthegeek

19
Non so perché così tante persone abbiano votato a favore. Indica chiaramente qui dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html che "... questo significa che per i caratteri alfabetici, i confronti saranno sensibili al maiuscolo / minuscolo". Quindi, se cerco "DickSavagewood" NON raccoglierei "dicksavagewood". Fare lo stesso con LOWER () lo raccoglierà. Quindi la mia risposta alla domanda: nel tuo caso particolare, SELECT è sensibile al maiuscolo / minuscolo.
Luftwaffle,

10
@ user1961753: Leggi ancora: "Per stringhe binarie (varbinary, blob) ... farà distinzione tra maiuscole e minuscole".
Marc B,

1
@MarcB questo link è ora interrotto. Potresti risolverlo? :)
Phiter

5
Come ha detto Jovan, dipende dalle regole di confronto, quindi questa risposta è praticamente sbagliata.
phil294,

117

È possibile minuscolo il valore e il parametro passato:

SELECT * FROM `table` WHERE LOWER(`Value`) = LOWER("IAreSavage")

Un altro modo (migliore) sarebbe quello di utilizzare l' COLLATEoperatore come indicato nella documentazione


21
Come SELECTapparirebbe questa affermazione COLLATEallora?
Sì, Barry,

11
Dice, nella pagina di documentazione di cui sopra, che "i confronti di stringhe non binarie sono insensibili alle maiuscole per impostazione predefinita".
Per Quested Aronsson,

9
Un po 'terrificante quante persone hanno votato questa risposta. Come spiegato sopra @Marc, i confronti non fanno distinzione tra maiuscole e minuscole. È necessario comprendere regole di confronto e indici e configurarle correttamente: l'utilizzo di trasformazioni di stringa come LOWER()o una COLLATEclausola arbitraria può bypassare completamente un indice e, nel tempo, con l'aumentare della tabella, ciò può avere conseguenze drastiche sulle prestazioni. Probabilmente questi sono nomi utente che stai cercando? Utilizzare un confronto senza distinzione tra maiuscole e minuscole e aggiungere un indice univoco alla colonna. Utilizzare EXPLAINper confermare che l'indice è in uso.
mindplay.dk,

1
Stavo per dire lo stesso di mindplay.dk ... upper () e lower () ignorano l'indice e influiscono direttamente sulle prestazioni su tabelle di database di grandi dimensioni.
GTodorov,

Concordo sia con mindplay.dk che con le opinioni di GTodorov. Fai attenzione usando un metodo su una colonna target nella clausola where. L'indice della colonna può essere inutile. Usa EXPLAIN!
Traeper

51

USA IL BINARIO

Questa è una selezione semplice

SELECT * FROM myTable WHERE 'something' = 'Something'

= 1

Questa è una selezione con binario

SELECT * FROM myTable WHERE BINARY 'something' = 'Something'

o

SELECT * FROM myTable WHERE 'something' = BINARY 'Something'

= 0


3
Quando ha senso usare BINARY solo su un lato del = (SELEZIONA * DA myTable DOVE BINARY 'qualcosa' = 'Qualcosa')?
Jimmy

@Jimmy Cosa intendi esattamente? Il codice funziona. Quando un lato del confronto viene convertito in binario, il confronto viene eseguito binario.
Jori,

@Jori Oh, immagino di aver letto male - ho pensato che uno dei due esempi avesse BINARY su entrambi i lati della parità.
Jimmy,

Ho appena votato perché questa è davvero la risposta giusta. Secondo la documentazione sul sito Web MySQL, dicono che è meglio usare il comando BINARY piuttosto che cercare di digitare le tue parole / richieste in una lingua specifica perché il comando BINARY dice di lasciare tutto come è e usarlo esattamente come è presentato. Quindi, quando sono arrivato alla ricerca di una risposta, le due risposte qui mi hanno portato al sito Web MySQL e a guardare il loro documento. L'uso di BINARY è meglio. La traduzione può causare altri problemi.
Mark Manning,

43

I confronti non fanno distinzione tra maiuscole e minuscole quando la colonna utilizza un confronto che termina con _ci(come il confronto predefinito latin1_general_ci ) e sono sensibili al maiuscolo / minuscolo quando la colonna utilizza un confronto che termina con _cso _bin(come il confronto utf8_unicode_cse utf8_bin).

Controlla le regole di confronto

È possibile controllare le regole di confronto del server , del database e delle connessioni utilizzando:

mysql> show variables like '%collation%';
+----------------------+-------------------+
| Variable_name        | Value             |
+----------------------+-------------------+
| collation_connection | utf8_general_ci   |
| collation_database   | latin1_swedish_ci |
| collation_server     | latin1_swedish_ci |
+----------------------+-------------------+

e puoi controllare le regole di confronto dei tavoli usando:

mysql> SELECT table_schema, table_name, table_collation 
       FROM information_schema.tables WHERE table_name = `mytable`;
+----------------------+------------+-------------------+
| table_schema         | table_name | table_collation   |
+----------------------+------------+-------------------+
| myschema             | mytable    | latin1_swedish_ci |

Cambia regole di confronto

È possibile modificare il confronto tra database, tabelle o colonne in una distinzione tra maiuscole e minuscole come segue:

-- Change database collation
ALTER DATABASE `databasename` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;

-- or change table collation
ALTER TABLE `table` CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin;

-- or change column collation
ALTER TABLE `table` CHANGE `Value` 
    `Value` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin;

I tuoi confronti dovrebbero ora fare distinzione tra maiuscole e minuscole.


25

Il confronto delle stringhe nella frase WHERE non fa distinzione tra maiuscole e minuscole. Puoi provare a confrontare usando

WHERE `colname` = 'keyword'

o

WHERE `colname` = 'KeyWord'

e otterrai lo stesso risultato . Questo è il comportamento predefinito di MySQL.

Se si desidera che il confronto sia sensibile al maiuscolo / minuscolo , è possibile aggiungere in COLLATEquesto modo:

WHERE `colname` COLLATE latin1_general_cs = 'KeyWord'

Che SQL darebbe risultati diversi con questo: DOVE colnameCOLLATE latin1_general_cs = 'keyword'

latin1_general_cs è un confronto comune o predefinito nella maggior parte dei database.


16

Le regole di confronto scelte determinano la distinzione tra maiuscole e minuscole.


9

L'impostazione predefinita non fa distinzione tra maiuscole e minuscole, ma la cosa più importante che dovresti considerare è come la tabella è stata creata in primo luogo, perché puoi specificare la distinzione tra maiuscole e minuscole quando crei la tabella.

Lo script seguente crea una tabella. Notate in fondo che dice "COLLATE latin1_general_cs". Che cs alla fine significa maiuscole e minuscole. Se vuoi che la tua tabella non faccia distinzione tra maiuscole e minuscole, puoi lasciare quella parte fuori o usare "COLLATE latin1_general_ci".

   CREATE Table PEOPLE (

       USER_ID  INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,

       FIRST_NAME  VARCHAR(50) NOT NULL,
       LAST_NAME  VARCHAR(50) NOT NULL,

       PRIMARY KEY (USER_ID)

   )

   ENGINE=MyISAM DEFAULT CHARACTER SET latin1
    COLLATE latin1_general_cs AUTO_INCREMENT=0;

Se il tuo progetto è tale da poter creare la tua tabella, ha senso specificare la preferenza di distinzione tra maiuscole e minuscole quando crei la tabella.




2

Nota anche che i nomi delle tabelle fanno distinzione tra maiuscole e minuscole su Linux a meno che tu non imposti la lower_case_table_namedirettiva config su 1 . Questo perché le tabelle sono rappresentate da file che fanno distinzione tra maiuscole e minuscole in Linux.

In particolare, fai attenzione allo sviluppo su Windows che non fa distinzione tra maiuscole e minuscole e che viene distribuito alla produzione dove si trova. Per esempio:

"SELECT * from mytable" 

contro la tabella myTable avrà esito positivo in Windows ma non in Linux, a meno che non sia impostata la direttiva sopra menzionata.

Riferimento qui: http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html


1
+1 - Lo scenario di scrivere query senza distinzione tra maiuscole e minuscole e poi fallire su Linux è accaduto molto nel nostro progetto
Vic

@Vic Sto riscontrando lo stesso problema con il mio progetto. Potresti dirmi come l'hai risolto?
Kamran Ahmed,

@KamranAhmed, devi usare il case dei nomi delle tabelle esattamente come appaiono negli script di creazione
Vic

@Vic sarebbe l'ultima risorsa, dato che dovrei modificare letteralmente tonnellate di domande. Mi chiedevo se ci sarebbe stato un modo semplice per farlo. Grazie comunque!
Kamran Ahmed,

@KamranAhmed, prova a cambiare lower_case_table_namecome specificato nella risposta in cui stiamo commentando
Vic

1

La soluzione attualmente accettata è per lo più corretta.

Se si utilizza una stringa non binaria (CHAR, VARCHAR, TEXT), i confronti non fanno distinzione tra maiuscole e minuscole , in base alle regole di confronto predefinite.

Se si utilizza una stringa binaria (BINARY, VARBINARY, BLOB), i confronti fanno distinzione tra maiuscole e minuscole, quindi è necessario utilizzare LOWERcome descritto in altre risposte.

Se non si utilizzano le regole di confronto predefinite e si utilizza una stringa non binaria, la distinzione tra maiuscole e minuscole viene decisa dalla raccolta selezionata.

Fonte: https://dev.mysql.com/doc/refman/8.0/en/case-sensitivity.html . Leggi attentamente. Alcuni altri hanno sbagliato a dire che i confronti sono necessariamente sensibili al maiuscolo / minuscolo o insensibili. Questo non è il caso.


0

Puoi provarlo. spero che sia utile.

SELECT * FROM `table` WHERE `Value` COLLATE latin1_general_cs = "IAreSavage"

0

I campi stringa con il set di flag binario saranno sempre sensibili al maiuscolo / minuscolo. Se hai bisogno di una ricerca con distinzione tra maiuscole e minuscole per un campo di testo non binario, usa questo: SELEZIONA 'test' REGEXP BINARY 'TEST' COME RISULTATO;

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.