【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
相关推荐
雨中飘荡的记忆44 分钟前
ElasticJob分布式调度从入门到实战
java·后端
掘金安东尼1 小时前
让 JavaScript 更容易「善后」的新能力
前端·javascript·面试
掘金安东尼1 小时前
用 HTMX 为 React Data Grid 加速实时更新
前端·javascript·面试
SudosuBash2 小时前
[CS:APP 3e] 关于对 第 12 章 读/写者的一点思考和题解 (作业 12.19,12.20,12.21)
linux·并发·操作系统(os)
灵感__idea3 小时前
Hello 算法:众里寻她千“百度”
前端·javascript·算法
yinuo4 小时前
轻松接入大语言模型API -04
前端
袋鼠云数栈UED团队4 小时前
基于 Lexical 实现变量输入编辑器
前端·javascript·架构
cipher5 小时前
ERC-4626 通胀攻击:DeFi 金库的"捐款陷阱"
前端·后端·安全
UrbanJazzerati5 小时前
非常友好的Vue 3 生命周期详解
前端·面试
AAA阿giao5 小时前
从零构建一个现代登录页:深入解析 Tailwind CSS + Vite + Lucide React 的完整技术栈
前端·css·react.js