2010-02-20 19 views
15

mi piacerebbe essere in grado di fare le query che normalizzano i caratteri accentati, in modo che, ad esempio:normalizzare caratteri accentati in MySQL query

é, è, and ê 

sono tutti trattati come 'e', ​​nelle query utilizzando '=' e come'. Ho una riga con campo nome utente impostato su 'rené' e mi piacerebbe poterlo abbinare su entrambi con 'rene' e 'rené'.

Sto tentando di farlo con la clausola 'collate' in MySQL 5.0.8. Ottengo il seguente errore:

mysql> select * from User where username = 'rené' collate utf8_general_ci; 
ERROR 1253 (42000): COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'latin1' 

FWIW, il mio tavolo è stato creato con:

CREATE TABLE `User` (
    `id` bigint(19) NOT NULL auto_increment, 
    `username` varchar(32) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `uniqueUsername` (`username`) 
) ENGINE=InnoDB AUTO_INCREMENT=56790 DEFAULT CHARSET=utf8 
+0

Cosa succede se cambi il set di caratteri della tabella in 'utf8'? – friedo

+0

friedo- non è quello che DEFAULT CHARSET = utf8 fa? (In realtà non ho creato questo tavolo, ma l'ho decodificato tramite 'show create table User'). –

+0

Sì, questo è quello che dovrebbe fare. Non so perché MySQL sembra pensare che il classificatore sia latin1 se lo si ha impostato su utf8, comunque. – friedo

risposta

8

Io suggerirei di salvare le versioni normalizzati al vostro tavolo in aggiunta con il vero nome utente. Cambiare la codifica al volo può essere costoso e devi ripetere la conversione per ogni riga di ogni ricerca.

Se stai usando PHP, è possibile utilizzare iconv() per gestire la conversione:

$username = 'rené'; 
$normalized = iconv('UTF-8', 'ASCII//TRANSLIT', $string); 

Poi si era appena salvare entrambe le versioni e utilizzare la versione normalizzata per la ricerca e il nome utente normale per la visualizzazione. Il confronto e la selezione sarà molto più velocemente dalla colonna normalizzata, a condizione che si normalizzare la stringa di ricerca anche:

$search = mysql_real_escape_string(iconv('UTF-8', 'ASCII//TRANSLIT', $_GET['search'])); 
mysql_query("SELECT * FROM User WHERE normalized LIKE '%".$search."%'"); 

Naturalmente questo metodo potrebbe non essere fattibile se si dispone di diverse colonne che hanno bisogno di normalizzazioni, ma nel tuo caso specifico questo potrebbe funzionare bene.

+0

Hmm, sono un po 'cauto nel mantenere i dati in più posizioni (DRY), a meno che non si riveli un collo di bottiglia. In questo caso, comporterebbe 3 campi esistenti: username, firstName e lastName (ho semplificato enormemente la mia struttura di tabella allo scopo di porre una semplice domanda). –

+0

Io uso PHP non funziona ... ho bisogno di più 1 riga successiva 'str_replace ("? ","% ", $ Normalizzato);' .. divertiti! – KingRider

2
$normalized = iconv('UTF-8', 'ASCII//TRANSLIT', $string); 

è una soluzione php perfetta, ma in mysql? CONVERTIRE?

in mysql

SELECT 'Álvaro José' as accented, (CONVERT ('Álvaro José' USING ascii)) as notaccented 

Produce:

Álvaro José  ?lvaro Jos? 

Le parole accentate non viene convertito in parole accentate, non è equivalente un translit di iconv.

RegExp non funziona con UTF-8.

Nessuna soluzione.

+1

Questa non è una risposta ma un commento con informazioni utili –

5

Ho implementato una funzione strtr php/TR comando UNIX in MySQL è possibile ottenere la fonte here

È possibile utilizzare come:

SELECT tr(name, 'áäèëî', 'aaeei') FROM persons 

o mettere a nudo alcuni personaggi

SELECT tr(name, 'áäèëî', null) FROM persons 
9

Il motivo dell'errore non è la tabella ma il set di caratteri del tuo input, ovvero il 'rené' nella tua query.Il comportamento dipende dalla character_set_connection variabile:

The character set used for literals that do not have a character set introducer and for number-to-string conversion.

utilizzando il client MySQL, cambiare utilizzando SET NAMES:

A SET NAMES 'charset_name' statement is equivalent to these three statements:

SET character_set_client = charset_name; 
SET character_set_results = charset_name; 
SET character_set_connection = charset_name; 

(da http://dev.mysql.com/doc/refman/5.5/en/charset-connection.html)

Esempio uscita:

mysql> set names latin1; 
Query OK, 0 rows affected (0.00 sec) 

mysql> select * from User where username = 'rené' collate utf8_general_ci; 
ERROR 1253 (42000): COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'latin1' 

mysql> set names utf8; 
Query OK, 0 rows affected (0.00 sec) 

mysql> select * from User where username = 'rené' collate utf8_general_ci; 
Empty set (0.00 sec) 

Altenatively, l'uso può impostare in modo esplicito il set di caratteri utilizzando un 'set di introduttore carattere':

mysql> set names latin1; 
Query OK, 0 rows affected (0.00 sec) 

mysql> select * from User where username = _utf8'rené' collate utf8_general_ci; 
Empty set (0.00 sec) 

So che questa domanda è piuttosto vecchio, ma dal momento che Google mi ha portato qui per una questione connessa, ho pensato che merita ancora una risposta :)

Problemi correlati