当前位置:首页 > 问答 > 正文

MySQL报错3987函数不支持字符集问题修复远程帮忙解决

最近在摆弄MySQL的时候,特别是当你想用一些内置函数处理文本,比如给字符串加密或者比较的时候,可能会突然蹦出来一个错误代码:3987,这个错误信息大概长这样:“Character set ‘utf8mb3’ is not supported for operation ‘function_name’”,意思就是说,你正在使用的这个名叫“function_name”的函数,它不待见名叫‘utf8mb3’的这个字符集,拒绝工作。

要弄懂这个问题,咱们得先扯远一点点,说说MySQL里的字符集,简单讲,字符集就是一套规则,规定了怎么把文字(比如汉字、英文、表情符号)转换成计算机能存的二进制数字,MySQL历史上最常用的字符集叫“utf8”,这个“utf8”其实是个“残血版”,它真正的名字应该是“utf8mb3”,它最多只用3个字节来存一个字符,这就导致了一个问题:现在大家聊天离不开的表情符号(Emoji),很多都需要4个字节来存储,如果你用这个“utf8mb3”字符集,是想存也存不进去表情符号的。

后来MySQL意识到了这个问题,就推出了它的完全体版本,叫“utf8mb4”,这个“mb4”就是最多4个字节的意思,它能完美支持包括表情符号在内的所有Unicode字符,MySQL官方现在都推荐大家用“utf8mb4”,而那个老的“utf8mb3”已经处于被淘汰的边缘了。

(根据MySQL官方文档的说明,从未来的MySQL版本开始,utf8mb3将被视为已弃用,并最终被移除,现在很多新功能和优化,都只围绕着utf8mb4来做了。)

好,背景说清楚了,现在回到我们的错误3987,这个错误发生的典型场景就是:你的MySQL服务器、数据库或者表的字符集,可能已经升级到了更现代的“utf8mb4”,但是你正在使用的某个特定函数,它内部的处理逻辑可能还比较老,或者有明确的限制,暂时没有完全适配“utf8mb4”字符集,错误信息里报的却是“utf8mb3”不支持,这听起来有点反直觉,这通常是因为函数在执行过程中,需要将数据转换到一种中间格式,而这个转换过程不支持旧的“utf8mb3”规则,或者函数明确要求输入必须是与服务器默认字符集兼容的“utf8mb4”格式,但你的输入数据或连接设置可能在某些环节被识别为了“utf8mb3”,从而引发了冲突。

在实际操作中,哪些情况会触发这个3987错误呢?我举几个常见的例子:

  1. 加密解密函数:比如AES_ENCRYPTAES_DECRYPTMD5SHA1等,这些函数处理的是二进制数据,它们对输入的字符串的字符集特别敏感。
  2. 字符串比较和排序函数:在某些复杂的排序规则(Collation)组合下,可能会出现问题。
  3. 特定的字符串处理函数:虽然不常见,但一些函数在处理不同字符集混合的数据时可能会报错。

既然知道了问题的根源是字符集不匹配或不被支持,那解决办法就是想办法让整个链条的字符集统一到“utf8mb4”,或者明确告知函数应该如何正确处理输入的数据,下面是一些可以尝试的修复步骤,你可以从简单到复杂逐一排查:

第一步:检查你的连接和系统设置

有时候问题不出在数据本身,而是你连接到数据库的方式,你可以通过执行以下SQL命令来查看当前的字符集设置:

SHOW VARIABLES LIKE 'character_set_%';
SHOW VARIABLES LIKE 'collation_%';

重点看character_set_clientcharacter_set_connectioncharacter_set_results这几个变量,理想情况下,它们都应该设置为utf8mb4,如果不是,你可以在建立数据库连接的代码中(比如PHP的PDO、Python的MySQLdb)显式地设置连接字符集,在连接字符串中加入类似charset=utf8mb4的参数。

第二步:检查表和字段的字符集

MySQL报错3987函数不支持字符集问题修复远程帮忙解决

确认一下你正在操作的那张表,以及具体那个字段,是不是真的用的是utf8mb4字符集,可以用这个命令查看:

SHOW CREATE TABLE your_table_name;

your_table_name换成你实际表名,在输出结果里,你会看到每个字段后面都跟着类似CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci的描述,如果这里显示的还是utf8mb3或者单纯的utf8(在旧版本中等同于utf8mb3),那问题很可能就出在这儿了,你需要修改表的字符集。

第三步:修改表或字段的字符集(如果发现是旧的)

如果检查发现表或字段确实是utf8mb3,你可以用ALTER TABLE语句来修改它,不过要小心,如果表很大,这个操作可能会锁表,影响线上服务,最好在业务低峰期进行。

-- 修改整个表的默认字符集和所有字符串字段的字符集
ALTER TABLE your_table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 或者只修改某一个字段的字符集
ALTER TABLE your_table_name MODIFY column_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

第四步:在SQL查询中显式转换字符集(临时解决方案)

如果上面改表结构比较麻烦,或者你确认不是表的问题,只是想快速让某个查询先跑起来,可以尝试在调用那个报错函数时,手动把字符串转成utf8mb4字符集,MySQL提供了CONVERT()函数或者USING关键字。

MySQL报错3987函数不支持字符集问题修复远程帮忙解决

你原来的报错语句可能是:

SELECT AES_ENCRYPT(my_column, 'key') FROM my_table;

可以尝试改成:

SELECT AES_ENCRYPT(CONVERT(my_column USING utf8mb4), 'key') FROM my_table;

或者

SELECT AES_ENCRYPT(my_column COLLATE utf8mb4_unicode_ci, 'key') FROM my_table;

这种方式是在查询层面临时解决,可能影响性能,但能帮你快速验证问题。

第五步:检查MySQL版本和函数支持

检查一下你的MySQL版本,非常旧的版本(比如8.0之前的某些版本)对utf8mb4的支持可能不够完善,如果可以,将MySQL升级到较新的稳定版(如8.0及以上版本)通常能解决很多这类字符集兼容性问题,你可以通过执行SELECT VERSION();来查看当前版本。

总结一下

MySQL报错3987的核心就是字符集“打架”了,解决问题的路线图就是“统一字符集到utf8mb4”,先从最简单的连接设置查起,再到表结构,如果都没问题,就在SQL语句里临时转换一下,保持MySQL版本的更新也是一个好习惯,这个过程可能需要你耐心地一步步排查,但一旦找到那个不匹配的环节,问题通常就能迎刃而解了,希望这些直接的解释和步骤能帮到你。