追踪 MySQL utf8 与 utf8mb4 的问题
Posted
技术标签:
【中文标题】追踪 MySQL utf8 与 utf8mb4 的问题【英文标题】:Tracking down MySQL utf8 vs. utf8mb4 Issues 【发布时间】:2021-10-29 09:29:15 【问题描述】:我们有一个完整的 utf8mb4 和 utf8mb4_unicode_ci 数据库。我什至导出了整个“项目”的所有 SQL 代码(通过 dbForge),并且在整个项目中找不到对 UTF8 的单个引用。我已验证所有表都使用正确的字符集和排序规则。
问题是每次我对我们的沙箱执行重置(它会重建数据库中的数据以进行测试)时,我在多个存储过程中都会收到以下错误:
SQLEXCEPTION:CORE_create_root_data:(HY000:3719) 'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous.
我不明白为什么会发生这种情况;在存储过程或它调用的存储过程或任何表的任何列中没有 UTF8 定义。我什至在调试模式下浏览了代码并追踪了触发这些警告的位置。这是一个简单地将根数据插入数据库的存储过程;并在调用返回时触发警告。这完全没有意义。例如:
下面是触发的处理程序:
DECLARE CONTINUE HANDLER FOR SQLWARNING
BEGIN
GET DIAGNOSTICS CONDITION 1 @p1 = RETURNED_SQLSTATE, @p2 = mysql_ERRNO, @p3 = MESSAGE_TEXT;
IF @p1 REGEXP '^01' = 1 THEN
SET @errortype = 'SQL WARNING';
ELSEIF @p1 REGEXP '^02' = 1 THEN
SET @errortype = 'NOT FOUND';
ELSEIF @p1 REGEXP '^0[0-2]' = 0 THEN
SET @errortype = 'SQLEXCEPTION';
END IF;
SET @full_error = CONCAT(@errortype, ':CORE_create_root_data:(', @p1, ':', @p2, ') ', @p3);
SELECT
@full_error;
END;
调用下面的存储过程(var_result 只是一个 BOOL 结果)。
CALL CORE_create_global_static_settings(in_password, var_result);
上面的代码是这样做的:
INSERT INTO global_static_setting (setting_category, setting_name, setting_value)
VALUES ('GLOBAL_VALUE', 'LIMIT_DEFAULT', 200);
从执行简单插入的 SP 返回时...触发 utf8 错误/警告。
知道这里发生了什么吗?
【问题讨论】:
【参考方案1】:假设您的数据库名为testdb
:以下查询为您提供了表的所有字符集:
SELECT c.character_set_name, t.table_name
FROM information_schema.tables AS t
INNER JOIN information_schema.collation_character_set_applicability AS c
ON c.collation_name = t.table_collation
WHERE t.table_schema = "testdb";
以下显示了所有列的字符集,但只有当它们是文本数据类型时,您才会看到一个。如果结果太多,可以在WHERE
子句中过滤表名和列名,但即使在大数据库中utf8
中utf8mb4
也很容易发现:
SELECT character_set_name, column_name, table_name
FROM information_schema.COLUMNS
WHERE table_schema = "testdb";
此外:存储过程和函数也有字符集。所以你必须:
-
备份所有程序和功能,
删除过程和函数,
执行
SET NAMES utf8mb4;
,最后
重新创建过程和函数。
他们现在将拥有所有字符集utf8mb4
。
【讨论】:
非常感谢;在发布之前,我运行了类似的东西。一切都是utf8mb4。所有表格和列。还有其他可能有助于追踪它的想法吗? 存储过程也有字符集***.com/questions/11920153/…我希望它们不是那么多,因为你需要删除每一个utf8 做到了。我不得不删除并重新创建所有存储过程和函数(大约 100,000 行代码 LOL)。万分感谢!如果您更新答案以包含上述内容,我会将其标记为正确。再次感谢!【参考方案2】:SQLEXCEPTION:CORE_create_root_data:(HY000:3719) 'utf8' 当前是字符集 UTF8MB3 的别名,但在未来版本中将是 UTF8MB4 的别名。请考虑使用 UTF8MB4 以便明确。
是一个警告。
多年前,MySQL 实现了一个不完整的 utf8 实现,但将其称为 utf8。现在它有一个完整的实现并称之为utf8mb4。旧的 utf8 现在有一个别名“utf8mb3”。 MySQL 想更改名称,但需要我们的帮助。
除非您明确需要“utf8mb3”,否则只要实际将“utf8”的任何用法更改为“utf8mb4”。更改中可能会有一些小问题,特别是如果您仍在运行版本 5.x。一旦你完全迁移到 8.0,航行应该会再次平静。
创建存储例程时,已建立的字符集和排序规则将存储为例程的属性。可能存储为“utf8”。
解决方法是确定您使用的是哪个字符集(utf8mb4 或 utf8mb3)并重新创建存储例程,
存在于 utf8mb3(旧的“utf8”)中的任何有效字符都可以在 utf8mb4(未来“utf8”)中使用。 (反之亦然,例如许多表情符号。)
【讨论】:
以上是关于追踪 MySQL utf8 与 utf8mb4 的问题的主要内容,如果未能解决你的问题,请参考以下文章
Mysql utf8mb3 utf8mb4 与UTF8 字符集参数(character_set_system)的说明