Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Characters appear as question marks in MySQL

I have a problem saving unicode characters in MySql.

Initially my database character set was set to latin1 and unicode strings were saves as quotation marks. After doing some research I added the following lines to my.cnf:

[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

and executed the query:

ALTER DATABASE <my_database> CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci

After restarting mysql, I get an error:

"org.springframework.jdbc.UncategorizedSQLException: Hibernate operation: Could not execute JDBC batch update; uncategorized SQLException for SQL ... Incorrect string value: '\xD0\xBA\xD1\x81\xD0\xB5...' for column 'first_name' at row 1"

Query mysql> show variables like 'char%'; returns the result:

Variable_name              | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8mb4                    |
| character_set_connection | utf8mb4                    |
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | utf8mb4                    |
| character_set_server     | utf8mb4                    |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/

and query mysql> show create database <my_database> gives:

| Database  | Create Database                                                       |
+-----------+-----------------------------------------------------------------------+
| my_database | CREATE DATABASE `my_database` /*!40100 DEFAULT CHARACTER SET utf8mb4 */

I know this question was answered many time but I tried everything I found in google and still couldn't fix it. Any help is appreciated!

UPDATE

After querying SHOW CREATE TABLE, I saw that DEFAULT CHARSET of the table was latin1.

I altered table with ALTER TABLE my_table CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

After that each column had CHARACTER SET set to latin1, while DEFAULT CHARSET at the end of the query result was utf8mb4

After altering the column with ALTER TABLE my_table MODIFY my_column VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, I got rid of the error when saving the value, but it went back to saving the string with question marks. Still haven't found the problem

like image 995
yinjia Avatar asked Dec 08 '16 16:12

yinjia


People also ask

What is question mark in MySQL query?

The question mark represents a parameter that will later be replaced. Using parameterized queries is more secure than embedding the parameters right into the query. SQL Server calls this parameterize queries, and Oracle calls it bind variables.

Which characters are not allowed in MySQL?

ASCII NUL (U+0000) and supplementary characters (U+10000 and higher) are not permitted in quoted or unquoted identifiers. Identifiers may begin with a digit but unless quoted may not consist solely of digits. Database, table, and column names cannot end with space characters.

Does MySQL allow special characters?

In MySQL, you can escape quote symbols by alternating between the single and double quote symbols. Alternatively, MySQL also has special character escape sequences as shown below: \0 - An ASCII NUL (0x00) character. \' - A single quote ( ' ) character.

What does question mark in SQL mean?

A dynamic parameter is a parameter to an SQL statement for which the value is not specified when the statement is created. Instead, the statement has a question mark (?) as a placeholder for each dynamic parameter. See Dynamic parameters.


3 Answers

  1. Make sure you have the correct encoding while inserting into DB. Add the following to your jdbc URL

    ?useUnicode=yes&characterEncoding=UTF-8
    

    So your final URL will look like this

    jdbc:mysql://HOSTNAME:PORT/DATABASE_NAME?useUnicode=yes&characterEncoding=UTF-8
    
  2. Make sure you create the table with utf8 character set and an appropriate collation (like utf8_general_ci)

like image 154
XOR Avatar answered Oct 24 '22 22:10

XOR


So 2 days later i was able to figure it out with the help from comment and other posts.

The issue with unicode was on 2 levels: 1) How it was saved in MySql 2) How Freemarker was displaying the value

These are the steps I did that solved the issue:

STEP1: Add the following lines to my.cnf file:

character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

STEP2: Run a query

ALTER TABLE my_table MODIFY my_column VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL

for each column that need to accept utf-8. That fixed MySql encoding. Note: altering the whole database or the table didn't seem to work.

STEP 3: Add the following property to ContentNegotiatingViewResolver bean :

<beanclass="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <property name="contentType" value="text/html;charset=UTF-8"/>
    </bean>

Problem solved.

like image 22
yinjia Avatar answered Oct 24 '22 22:10

yinjia


In my case, the problem with replacement of cyrillyc letters by question marks was easily solved by deleting the table and creating it again with adding to the end of a 'CREATE TABLE' statement the following:

DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci

For example:

CREATE TABLE IF NOT EXISTS People (id int NOT NULL AUTO_INCREMENT, name varchar(50), gender char(1), birthDate date, profession varchar(50), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci

More detaled informaton on encoding issues is provided on the official MySQL website.

like image 1
Roman Karagodin Avatar answered Oct 24 '22 21:10

Roman Karagodin