Golang MySQL 1366错误:不正确的字符串值

3
我正在将字符串插入数据库,但是遇到了MySQL 1366错误,提示无效的字符串字节序列。
2016/11/04 13:33:40 Error 1366: Incorrect string value: '\x89PNG\x0D\x0A...' for column 'text' at row 1
2016/11/04 13:33:56 Error 1366: Incorrect string value: '\xB6\xEB\xE4\x0B\x92\xEE...' for column 'text' at row 1
2016/11/04 13:33:56 Error 1366: Incorrect string value: '\xFF\xD8\xFF\xE0\x00\x10...' for column 'text' at row 1
2016/11/04 13:34:35 Error 1366: Incorrect string value: '\x9C]\x91\xD1k\xC2...' for column 'text' at row 1

我的MySQL配置如下所示,已设置为utf8mb4:

mysql> SHOW VARIABLES LIKE 'character_set%';
+--------------------------+----------------------------+
| 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/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

我的数据库连接池看起来像这样:

db, err = sql.Open("mysql", config.User+":"+config.Password+"@tcp("+config.Host+")/"+config.Database)
if err != nil {
    log.Fatal(err)
}

db.Exec("SET NAMES 'utf8mb4'; SET CHARACTER SET utf8mb4;")

我还缺些什么?


我曾经遇到过同样的问题,后来发现字符串中不知何故引入了控制字符(在我的情况下,是将_MS-Word_格式化文本从 MS-Word 复制到 Web 页面的输入字段时)。在我的情况下,解决方案是在客户端过滤掉控制字符。 - FDavidov
2个回答

7
那些不是有效的UTF-8字符串,它们是二进制数据(第一个是PNG文件!)。你需要将它们存储在真正的二进制列中,因为MySQL确实执行UTF-8特定的操作,比如大小写折叠和语言排序。(Go不强制执行字符串的UTF-8编码,所以Go不会抱怨。Go仅使用UTF-8编码字符串字面值,但\x 转义序列会覆盖此设置。当然,range[]rune转换和各种包都假定字符串是UTF-8编码。)
你可以使用utf8.ValidString()来检查字符串是否是有效的序列。

2

在包含图像的列中使用BLOB(可能是MEDIUMBLOB)数据类型。使用TEXT会导致检查编码。PNG文件不包含正确编码的utf8字符,因此会出现错误。

你对utf8mb4的其余使用可能没有问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接