为什么 utf8mb4 列在 MySQL 5.7.22 中拒绝 4 字节字符?
Why does a utf8mb4 column reject 4-byte characters in MySQL 5.7.22?
我正在尝试将所有 4 字节字符的字符串保存到 MySQL utf8mb4 列。
UPDATE `uga_libsteam`.`group_history` SET `source_name`='' WHERE `group_id`='103582791430024497' and`history_id`='1655';
人物如下
- http://www.fileformat.info/info/unicode/char/1d4d4/index.htm
- http://www.fileformat.info/info/unicode/char/1D4F6/index.htm
- http://www.fileformat.info/info/unicode/char/1D4F9/index.htm
- http://www.fileformat.info/info/unicode/char/1D4FB/index.htm
- http://www.fileformat.info/info/unicode/char/1D4EE/index.htm
- http://www.fileformat.info/info/unicode/char/1D4FC/index.htm
但是,当我 运行 这个查询时,我收到这个错误。
Executing:
UPDATE `uga_libsteam`.`group_history` SET `source_name`='' WHERE `group_id`='103582791430024497' and`history_id`='1655';
Operation failed: There was an error while applying the SQL script to the database.
ERROR 1366: 1366: Incorrect string value: '\xF0\x9D\x93\x94\xF0\x9D...' for column 'source_name' at row 1
SQL Statement:
UPDATE `uga_libsteam`.`group_history` SET `source_name`='' WHERE `group_id`='103582791430024497' and`history_id`='1655'
这是我的架构。标题已弃用,最终我将删除它。以前,source_name 和 target_name 都是 utf8/utf8_unicode_ci,但我昨晚解决了这个问题。
CREATE TABLE `group_history` (
`group_id` bigint(20) unsigned NOT NULL,
`history_id` bigint(20) unsigned NOT NULL,
`type_id` tinyint(2) DEFAULT NULL,
`title` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`display_date` datetime DEFAULT NULL,
`year_offset` tinyint(2) unsigned DEFAULT NULL,
`month` tinyint(2) unsigned DEFAULT NULL,
`day` tinyint(2) unsigned DEFAULT NULL,
`time` time DEFAULT NULL,
`source_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`source_steam_id` bigint(20) DEFAULT NULL,
`target_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`target_steam_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`group_id`,`history_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
为什么数据库拒绝输入应该合法的字符?我必须切换到 UTF-32 才能工作吗?
Previously, source_name and target_name were both utf8/utf8_unicode_ci, but I was able to fix that last night.
我猜你试图通过更改 table 的默认字符集来修复字符集。
ALTER TABLE group_history DEFAULT CHARSET utf8mb4;
这不会更改 table 现有列的字符集,它只会更改 table 的默认字符集,只有在您随后添加新列时才会使用它。现有列仍使用旧字符集 utf8 编码。
要转换现有列,您必须使用:
ALTER TABLE group_history CONVERT TO CHARACTER SET utf8mb4;
这将使用新字符集重写所有现有字符串列,随后允许您插入 4 字节字符值。
Thanks to this answer, I had to run this 在插入到我的数据库之前可以工作...
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
好消息是我现在可以插入到我的数据库中,坏消息是我正在为 PHP 应用程序编写此代码并且 PDO 不工作并且正在保存????????到数据库。
编辑:,我也找到了 PHP 问题的解决方案。这是我的代码之前的样子:
$dsn = "mysql:host=$this->hostname;port=$this->port;dbname=$this->database;charset=utf8mb4";
try {
$this->pdo = new \PDO($dsn, $this->username, $this->password, array(\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION));
$this->pdo->exec('SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;');
} catch (\PDOException $e) {
die($e->getMessage());
}
这是我必须将其更改为:
$dsn = "mysql:host=$this->hostname;port=$this->port;dbname=$this->database;charset=utf8mb4";
try {
$this->pdo = new \PDO($dsn, $this->username, $this->password, array(\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, \PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci'));
} catch (\PDOException $e) {
die($e->getMessage());
}
我正在尝试将所有 4 字节字符的字符串保存到 MySQL utf8mb4 列。
UPDATE `uga_libsteam`.`group_history` SET `source_name`='' WHERE `group_id`='103582791430024497' and`history_id`='1655';
人物如下
- http://www.fileformat.info/info/unicode/char/1d4d4/index.htm
- http://www.fileformat.info/info/unicode/char/1D4F6/index.htm
- http://www.fileformat.info/info/unicode/char/1D4F9/index.htm
- http://www.fileformat.info/info/unicode/char/1D4FB/index.htm
- http://www.fileformat.info/info/unicode/char/1D4EE/index.htm
- http://www.fileformat.info/info/unicode/char/1D4FC/index.htm
但是,当我 运行 这个查询时,我收到这个错误。
Executing:
UPDATE `uga_libsteam`.`group_history` SET `source_name`='' WHERE `group_id`='103582791430024497' and`history_id`='1655';
Operation failed: There was an error while applying the SQL script to the database.
ERROR 1366: 1366: Incorrect string value: '\xF0\x9D\x93\x94\xF0\x9D...' for column 'source_name' at row 1
SQL Statement:
UPDATE `uga_libsteam`.`group_history` SET `source_name`='' WHERE `group_id`='103582791430024497' and`history_id`='1655'
这是我的架构。标题已弃用,最终我将删除它。以前,source_name 和 target_name 都是 utf8/utf8_unicode_ci,但我昨晚解决了这个问题。
CREATE TABLE `group_history` (
`group_id` bigint(20) unsigned NOT NULL,
`history_id` bigint(20) unsigned NOT NULL,
`type_id` tinyint(2) DEFAULT NULL,
`title` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`display_date` datetime DEFAULT NULL,
`year_offset` tinyint(2) unsigned DEFAULT NULL,
`month` tinyint(2) unsigned DEFAULT NULL,
`day` tinyint(2) unsigned DEFAULT NULL,
`time` time DEFAULT NULL,
`source_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`source_steam_id` bigint(20) DEFAULT NULL,
`target_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`target_steam_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`group_id`,`history_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
为什么数据库拒绝输入应该合法的字符?我必须切换到 UTF-32 才能工作吗?
Previously, source_name and target_name were both utf8/utf8_unicode_ci, but I was able to fix that last night.
我猜你试图通过更改 table 的默认字符集来修复字符集。
ALTER TABLE group_history DEFAULT CHARSET utf8mb4;
这不会更改 table 现有列的字符集,它只会更改 table 的默认字符集,只有在您随后添加新列时才会使用它。现有列仍使用旧字符集 utf8 编码。
要转换现有列,您必须使用:
ALTER TABLE group_history CONVERT TO CHARACTER SET utf8mb4;
这将使用新字符集重写所有现有字符串列,随后允许您插入 4 字节字符值。
Thanks to this answer, I had to run this 在插入到我的数据库之前可以工作...
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
好消息是我现在可以插入到我的数据库中,坏消息是我正在为 PHP 应用程序编写此代码并且 PDO 不工作并且正在保存????????到数据库。
编辑:
$dsn = "mysql:host=$this->hostname;port=$this->port;dbname=$this->database;charset=utf8mb4";
try {
$this->pdo = new \PDO($dsn, $this->username, $this->password, array(\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION));
$this->pdo->exec('SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;');
} catch (\PDOException $e) {
die($e->getMessage());
}
这是我必须将其更改为:
$dsn = "mysql:host=$this->hostname;port=$this->port;dbname=$this->database;charset=utf8mb4";
try {
$this->pdo = new \PDO($dsn, $this->username, $this->password, array(\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, \PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci'));
} catch (\PDOException $e) {
die($e->getMessage());
}