【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
相关推荐
子兮曰2 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
小羊没烦恼!2 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
子兮曰2 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
俊昭喜喜里2 天前
java中的继承和多态的区别
java
小羊没烦恼!2 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
未济2 天前
linux 配置环境变量
linux
傲世仙尊2 天前
目录即文件-Ext文件系统收尾篇
linux·c语言
前端小万2 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝2 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
譕痕2 天前
JSONObject与JSONArray封装数据格式区别
java·json