utf8mb4列为什么拒绝mysql 5.7.22中的4字节字符?

dhxwm5r4  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(374)

我正在尝试将一个包含所有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\u name和target\u name都是utf8/utf8\u unicode\u 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才能工作吗?

x759pob2

x759pob21#

以前,source\u name和target\u name都是utf8/utf8\u unicode\u ci,但我昨晚解决了这个问题。
我猜您试图通过更改表的默认字符集来修复字符集。

ALTER TABLE group_history DEFAULT CHARSET utf8mb4;

这不会更改表中现有列的字符集,只会更改表的默认字符集,只有在随后添加新列时才会使用默认字符集。现有的列仍然使用旧的字符集utf8进行编码。
要转换现有列,必须使用:

ALTER TABLE group_history CONVERT TO CHARACTER SET utf8mb4;

这将使用新的字符集重写所有现有的字符串列,然后允许您插入4字节的字符值。

gab6jxml

gab6jxml2#

多亏了这个答案,我不得不在插入数据库之前运行它。。。

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());
    }

相关问题