Hibaszimulálás DROP TABLE IF EXISTS t1; CREATE TABLE t1( latin1_txt VARCHAR(6) CHARSET latin1, utf8_txt VARCHAR(6) CHARSET utf8 )ENGINE=InnoDB; #INSERT INTO t1 VALUES('á','á'); # Így csempészünk be utf8-at a latin1-be: INSERT INTO t1 VALUES (UNHEX('C3A1'),UNHEX('C3A1')); # C3A1: az á betű utf8 kódja. SELECT LENGTH(latin1_txt),LENGTH(utf8_txt),CHAR_LENGTH(latin1_txt),CHAR_LENGTH(utf8_txt),HEX(latin1_txt),HEX(utf8_txt),latin1_txt,utf8_txt FROM t1; +--------------------+------------------+-------------------------+-----------------------+-----------------+---------------+------------+----------+ | LENGTH(latin1_txt) | LENGTH(utf8_txt) | CHAR_LENGTH(latin1_txt) | CHAR_LENGTH(utf8_txt) | HEX(latin1_txt) | HEX(utf8_txt) | latin1_txt | utf8_txt | +--------------------+------------------+-------------------------+-----------------------+-----------------+---------------+------------+----------+ | 2 | 2 | 2 | 1 | C3A1 | C3A1 | A! | á | +--------------------+------------------+-------------------------+-----------------------+-----------------+---------------+------------+----------+ Az 'A!' a Crimson hazugsága, valójában egy hullámos ékezetű A (latin1-ben C3) és egy fordított felkiáltójel (latin1-ben A1) kódja van ott. ---------------------- Javítás konvertálással, 1. kísérlet SELECT HEX(latin1_txt),HEX(CONVERT(latin1_txt USING utf8)),CONVERT(latin1_txt USING utf8) FROM t1; +-----------------+-------------------------------------+--------------------------------+ | HEX(latin1_txt) | HEX(CONVERT(latin1_txt USING utf8)) | CONVERT(latin1_txt USING utf8) | +-----------------+-------------------------------------+--------------------------------+ | C3A1 | C383C2A1 | A! | +-----------------+-------------------------------------+--------------------------------+ Hullámos ékezetű A : C3 (latin1) --> C383 (utf8) Fordított felkiáltójel: A1 (latin1) --> C2A1 (utf8) A latin1-nek tekintett szöveget bájtonként konvertálja, azt hiszi, hogy két karakter. A CONVERT(latin1_txt USING utf8) ezt jelenti: 'Vedd a mező tartalmát, nézd meg, hogyan van kódolva, értelmezd ennek megfelelően és alakítsd át utf8-cá!' Javítás konvertálással, a jó megoldás SELECT HEX(latin1_txt),HEX(CONVERT(BINARY latin1_txt USING utf8)),CONVERT(BINARY latin1_txt USING utf8) FROM t1; +-----------------+--------------------------------------------+---------------------------------------+ | HEX(latin1_txt) | HEX(CONVERT(BINARY latin1_txt USING utf8)) | CONVERT(BINARY latin1_txt USING utf8) | +-----------------+--------------------------------------------+---------------------------------------+ | C3A1 | C3A1 | á | +-----------------+--------------------------------------------+---------------------------------------+ A BINARY konvertálás bináris sztringgé konvertál, vagyis egyszerűen csak leszedi a karakterkészlet-jelzést, a tartalommal nem csinál semmit. Ezt a 'nyers' bájtsorozatot értelmezzük ezután utf8 karakterekként. Hiszen tudjuk, hogy valójában egy utf8 karaktersorozat került be valami hiba folytán a latin1 kódolású mezőbe. A CONVERT(BINARY latin1_txt USING utf8) ezt jelenti: 'Vedd a mező tartalmát, értelmezd utf8-ként!'