UTF-8 encoding problem while importing a sql file

17,315

Solution 1

Thanks to deceze comment, I could fix the issue.

In HeidiSQL, when I choose the sql file to execute, there's actually an "ncoding" option I did not notice originally ;-)

If I keep "auto-detect", the import generates bad content (with mojibake characters)

If I force "UTF-8", the import is perfect

Dunno why HeidiSQL fails to auto-detect the encoding...

Solution 2

A few thoughts:

It looks like you have the character set set correctly. The fact that HeidiSQL displays a different character set, is probably because clients themselves set a character set.

For example, your mysql server might use "Character set A" by default. If a client connects and says they want "Character set B", the server will convert this on the fly.

utf8mb4 is a superset (and superior to) utf8. It's better to have your server default to utf8mb4. The popular usecase of utf8mb4 is emoji.

Anyway, the reason you are getting mojibake is probably unrelated to having these character sets set correctly.

What I think may have happened is as follows (this is a guess).

  1. Your tables/columns were set as UTF-8.
  2. A client connects and tells the server "I want to use ISO-8559-1/latin instead".
  3. The server happily complies and will convert the clients ISO-8559-1 strings to UTF-8 on the fly.
  4. Despite the client wanting to use ISO-8559-1, it actually sends UTF-8.
  5. The server thinks the data is ISO-8559-1 and treats it as such, and converts the UTF-8 using a ISO-8559-1 to UTF. It's effectively a double-encoding.

If I'm right, it means that you can have all your columns, connections and tables set to UTF-8, but your data is simply bad.

If this is correct, this process is reversable

You really just need the opposite operation. For example, if you had a PHP string $data, which is 'double-encoded' as UTF-8, the process would simply be to call this:

$output = utf8_decode($input)

It's also possible to fix this in MySQL. See this stack overflow question.

A few things to be aware of:

  1. Make sure this is actually the case. Are you getting the correct output after this operation?
  2. Make backups, obviously.
  3. Also make absolutely sure that whatever was writing double-encoded UTF-8 to your database is now fixed. The last thing you want is a table that's a mixture of different encodings.

Sidenote: This problem is extremely common. You are somewhat lucky that you're french because it highlights the problem. Many english systems I've seen have this issue but it largely goes unnoticed for a long time because a lot of text doesn't go outside the common ASCII range.

Share:
17,315
jpo38
Author by

jpo38

Software developer, mainly C++, worked with MFC, now working with Qt. Using CMake and more Python every day...

Updated on June 04, 2022

Comments

  • jpo38
    jpo38 almost 2 years

    I have a server hosting MySQL, PHPMyAdmin reports:

    Server version: 5.1.56-community
    MySQL charset: UTF-8 Unicode (utf8)
    

    I export a sql from using either mysqldump -uroot -p database > file.dump or mysqldump -uroot -p database -r file.dump (both generated files are identical anyway).

    Locally, I installed MySQL 5.5 and HeidiSQL 9.5.

    As the server's SQL file my.ini has:

    default-character-set=utf8
    

    I changed the local my.ini file to have

    default-character-set=utf8
    

    But also:

    character-set-server=utf8
    

    They were both set to latin1. Dunno why I have character-set-server set here while the server does not. Anyway.

    Now I start HeidiSQL, it shows utf8mb4 references instead of utf8 for the sessions parameters. I don't know why:

    enter image description here

    Now, I import my dumped file, and I see that even if everything is apparently configured in utf8, it looks like I have some encoding problems.

    On the server, I see: enter image description here

    Locally, in HeidiSQL, I see: enter image description here

    Special characters like à are not displayed correctly on the local database.

    Am I doing something wrong?

    Note that if I install HeidiSQL on the server, the variable tab shows the same values for the Session and Global parameters, and the à is shown correctly.

    So this may be the root cause of the problem, but I don't know how to fix it. If I change the Session values before importing the sql file it does not fix the issue, and also values are back to utf8mb4 when I start HeidiSQL again.