【1267 - Illegal mix of collations 】mysql报错解决记录

这是我的表:

sql 复制代码
CREATE TABLE `collect_data_node` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `node_ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '节点ip',
  `measure_frequency` double DEFAULT NULL COMMENT '测量频率',
  `measure_bandwidth` bigint(20) DEFAULT NULL COMMENT '测量带宽',
  `measure_power` float DEFAULT NULL COMMENT '测量功率',
  `monitor_model` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '监测模式',
  `collect_time` datetime DEFAULT NULL COMMENT '采集时间',
  `channel_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4296575 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='信号检测节点采集数据表';
sql 复制代码
CREATE DEFINER=`root`@`%` PROCEDURE `clean_up_old_data`(IN nodeIps TEXT, IN amount INT)
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE cur_nodeIp VARCHAR(255);
    DECLARE cur_count INT;
    DECLARE cur CURSOR FOR
        SELECT DISTINCT node_ip
        FROM collect_data_node
        WHERE FIND_IN_SET(node_ip, nodeIps);
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN cur;
    read_loop: LOOP
        FETCH cur INTO cur_nodeIp;
        IF done THEN
            LEAVE read_loop;
        END IF;

        -- 计算当前 nodeIp 的记录数
        SELECT COUNT(*)
        INTO cur_count
        FROM collect_data_node
        WHERE node_ip = cur_nodeIp;

        -- 如果当前 nodeIp 的记录数超过指定数量,则删除多余记录
        IF cur_count > amount THEN
            DELETE FROM collect_data_node
            WHERE node_ip = cur_nodeIp 
            and id NOT IN (
                SELECT id FROM (
                    SELECT id
                    FROM collect_data_node
                    WHERE node_ip = cur_nodeIp
                    ORDER BY collect_time DESC
                    LIMIT amount
                ) AS temp
            );
        END IF;
    END LOOP;
    CLOSE cur;
END
sql 复制代码
CALL clean_up_old_data2 (
	'97bfc421-94ef-4a58-8be2-7234baf3954d',
1000 
)

当我调用这个存储过程会报错:

1267 - Illegal mix of collations (utf8mb4_0900_ai_ci,IMPLICIT) and (utf8mb4_unicode_ci,IMPLICIT) for operation 'find_in_set'

find_in_set中涉及了排序

node_ip排序规则是:utf8mb4_0900_ai_ci,而输入变量nodeIps用的是默认的排序规则utf8mb4_unicode_ci。两个排序规则不一样,就报这个错了。

查看数据默认使用的排序规则:

sql 复制代码
SHOW VARIABLES LIKE 'collation_server';

发现是utf8mb4_unicode_ci

解决方案

创建表的时候排序规则指定成数据库默认的排序规则。

修改存储过程,有涉及到排序的手动指定排序规则,保持一致的排序规则。

sql 复制代码
CREATE DEFINER=`root`@`%` PROCEDURE `clean_up_old_data`(IN nodeIps TEXT, IN amount INT)
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE cur_nodeIp VARCHAR(255);
    DECLARE cur_count INT;
    DECLARE cur CURSOR FOR
        SELECT DISTINCT node_ip
        FROM collect_data_node
        WHERE FIND_IN_SET(
    node_ip COLLATE utf8mb4_unicode_ci,
    nodeIps COLLATE utf8mb4_unicode_ci
);
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN cur;
    read_loop: LOOP
        FETCH cur INTO cur_nodeIp;
        IF done THEN
            LEAVE read_loop;
        END IF;

        -- 计算当前 nodeIp 的记录数
        SELECT COUNT(*)
        INTO cur_count
        FROM collect_data_node
        WHERE node_ip COLLATE utf8mb4_0900_ai_ci = cur_nodeIp COLLATE utf8mb4_0900_ai_ci;

        -- 如果当前 nodeIp 的记录数超过指定数量,则删除多余记录
        IF cur_count > amount THEN
            DELETE FROM collect_data_node
            WHERE node_ip COLLATE utf8mb4_0900_ai_ci = cur_nodeIp COLLATE utf8mb4_0900_ai_ci

            and id NOT IN (
                SELECT id FROM (
                    SELECT id
                    FROM collect_data_node
										WHERE node_ip COLLATE utf8mb4_0900_ai_ci = cur_nodeIp COLLATE utf8mb4_0900_ai_ci
                    ORDER BY collect_time DESC
                    LIMIT amount
                ) AS temp
            );
        END IF;
    END LOOP;
    CLOSE cur;
END
相关推荐
bigbearxyz2 分钟前
Caused by: java.net.SocketException: Connection reset问题排查
java·keepalived·proxysql
黄筱筱筱筱筱筱筱14 分钟前
LINUX-防火墙
linux·服务器·网络
大家的林语冰29 分钟前
CSS 已死?DOM 性能黑洞!Pretext 排版革命让你在文本间跳舞,没有 DOM 也能纵享丝滑~
前端·javascript·css
vipbic39 分钟前
我也该升级了,陪伴了我7年的博客
前端
сокол1 小时前
【网安-Web渗透测试-靶场系列】AWD-Platform(ctf-hub)
linux·服务器·ubuntu·网络安全·docker
Lee川1 小时前
RAG 实战:从一篇掘金文章出发,拆解检索增强生成的全链路
前端·人工智能·后端
Lee川1 小时前
MCP 高德地图实战:当 AI 学会使用工具,一个协议如何重塑大模型的行动边界
前端·人工智能·后端
ZC跨境爬虫1 小时前
跟着 MDN 学CSS day_14:(尺寸调整技能测试与实战解析)
前端·css·ui·html·tensorflow
utf8mb4安全女神1 小时前
Linux系统服务相关命令【定时任务设置】【任务进程管理】【防火墙区域应用】
linux·运维·服务器
kyriewen2 小时前
用魔法打败魔法:我让AI替我去面试前端岗,AI面试官给我打了92分,还发了offer
前端·javascript·面试