2013-08-26 8 views
16

Ho usato in modo ignorante la codifica dei caratteri latin1_swedish_ci predefinita per tutte le righe varchar nel mio database durante lo sviluppo e ho determinato che questa è la radice dei problemi di codifica dei caratteri che ho avuto. Inoltre, sembra che la maggior parte delle persone in questi giorni stia raccomandando l'utilizzo di utf8_unicode_ci.Come modificare le regole di confronto di tutte le righe da latin1_swedish_ci a utf8_unicode_ci?

Mi piacerebbe convertire la codifica dei caratteri per tutte le righe nel mio database da latin1_swedish_ci a utf8_unicode_ci, ma l'unico modo che so come fare è cambiarlo riga per riga in phpMyAdmin, che richiede molto tempo .

C'è un modo più veloce, come una query che può essere eseguita che modifica le regole di confronto di tutte le righe varchar/text da latin1_swedish_ci a utf8_unicode_ci?

risposta

35

Se le colonne stanno usando il carattere tavolo set predefinito Poi è solo una query per ogni tabella per la conversione:

ALTER TABLE t CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci; 

Se il set di caratteri è impostato singolarmente su ogni colonna, per quanto ne so non c'è modo di farlo su tutte le colonne di tutte le tabelle nel database direttamente in MySql, ma è possibile scrivere un piccolo programma nella lingua scelta che lo fa.

Il vostro programma sarebbe interrogare la tabella INFORMATION_SCHEMA.COLUMNS e guardare la colonna CHARACTER_SET_NAME:

SELECT * FROM `INFORMATION_SCHEMA.COLUMNS` 
WHERE TABLE_SCHEMA = 'dbname' AND CHARACTER_SET_NAME = 'latin1' 

Per ogni risultato fila è banale per sintetizzare ed eseguire un ALTER TABLE interrogazione sul posto che cambia il set di caratteri e collazione in modo appropriato:

ALTER TABLE t MODIFY col TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci; 

Nella query sopra t, col e TEXT sarebbero i valori del TABLE_NAME, 012 Colonnee DATA_TYPE dal set di risultati INFORMATION_SCHEMA.COLUMNS.

+0

Grazie! ha funzionato alla grande e mi ha salvato un'enorme quantità di tempo! – Nate

+0

Bella risposta. Per quanto ne so, 'utf8_unicode_ci' dovrebbe essere usato al posto di' utf8_general_ci', dato che 'utf8_unicode_ci' è più preciso. Quindi, l'uso di 'utf8_unicode_ci' dovrebbe essere raccomandato. http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci –

+0

@Sudarshan_SMD hai ragione, non sono sicuro del perché ho usato generale invece di unicode, soprattutto considerando che la domanda dice generale, ed è stata troppo lunga ora. Grazie per averlo preso! – Jon

9

Si può effettivamente farlo all'interno di MySQL, utilizzando una procedura.

Basato su https://stackoverflow.com/a/12718767/1612273. Usa il database corrente, quindi assicurati di farlo su quello giusto!

delimiter // 

DROP PROCEDURE IF EXISTS convert_database_to_utf8 // 

CREATE PROCEDURE convert_database_to_utf8() 
BEGIN 
    DECLARE table_name VARCHAR(255); 
    DECLARE done INT DEFAULT FALSE; 

    DECLARE cur CURSOR FOR 
     SELECT t.table_name FROM information_schema.tables t WHERE t.table_schema = DATABASE() AND t.table_type='BASE TABLE'; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; 

    OPEN cur; 
     tables_loop: LOOP 
      FETCH cur INTO table_name; 

      IF done THEN 
       LEAVE tables_loop; 
      END IF; 

      SET @sql = CONCAT("ALTER TABLE ", table_name, " CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci"); 
      PREPARE stmt FROM @sql; 
      EXECUTE stmt; 
      DROP PREPARE stmt; 
     END LOOP; 
    CLOSE cur; 
END // 

delimiter ; 
call convert_database_to_utf8(); 
Problemi correlati