MySQL查询时报错Illegal mix of collations

1.具体场景

两张表分别为:

CREATE TABLE `tb_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户编号(自增字段)',
  `userName` varchar(32) NOT NULL DEFAULT '' COMMENT '用户昵称',
  # ...
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1DEFAULT CHARSET=utf8 COMMENT='用户表';

CREATE TABLE `tb_sms_message` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `tel` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '手机号',
  # ...
  PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=1DEFAULT CHARSET=utf8;


报错信息如下:

 Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation '='

2.查询SQL

SELECT * FROM `tb_sms_message`
  where tel not IN (select userName from tb_user);

 

3.原因分析

两个关联的字段的collate不一致,无法直接关联。

这里我们可以对字段的校对集转化为一致:

CONVERT(tel USING utf8) COLLATE utf8_general_ci

修改后的SQL:

SELECT * FROM `tb_sms_message`
  where CONVERT(tel USING utf8) COLLATE utf8_general_ci not IN (select userName from tb_user);

 

网上搜了挺多的,但是真正提到我这个问题的解决方式:

http://www.cnblogs.com/mrma/p/3440992.html

### JDBC 查询 MySQL出现 `Illegal mix of collations` 错误的原因 当执行 SQL 查询操作(如 `'case'` 或其他运算符),如果涉及多个字段或表之间的比较,而这些字段具有不同的字符集或排序规则,则可能会引发 `java.sql.SQLException: Illegal mix of collations` 的异常。此错误表明参与计算的列之间存在不兼容的排序规则。 具体来说,在当前情况下,可能是某些字段使用了 `utf8mb4_general_ci` 排序规则,而另一些字段则使用了 `utf8mb4_0900_ai_ci` 排序规则[^1]。由于这两种排序规则并不完全一致,因此无法直接用于相等性判断或其他逻辑运算。 --- ### 解决方案 #### 方法一:统一字段的字符集和排序规则 可以通过修改数据库中的字段定义来确保它们都采用相同的字符集和排序规则。例如: ```sql ALTER TABLE your_table MODIFY column_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; ``` 通过上述语句可以将指定字段设置为与目标字段匹配的排序规则。注意替换 `your_table` 和 `column_name` 为你实际使用的表名和字段名称。 这种方法适用于能够调整数据库结构的情况,并且推荐作为长期解决方案以减少潜在问题的发生概率[^1]。 #### 方法二:强制转换数据类型 如果不允许更改现有数据库模式或者希望快速解决问题,可以在查询过程中显式地对某一侧的数据进行类型转换。比如利用 CAST 函数实现如下效果: ```sql SELECT * FROM your_table WHERE CAST(column_a AS CHAR CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci) = column_b; ``` 这里我们将 `column_a` 转换成了与 `column_b` 相同的排序规则形式后再做对比处理[^3]。尽管这种方式能够在一定程度上缓解即需求的压力,但从性能角度考虑它可能不如方法一所述那样高效稳定。 #### 方法三:配置客户端连接参数 有即使服务器端各对象间保持了一致性的设定仍会出现此类状况,这往往是因为客户端默认采用了不同于预期之外的编码方式所致。为此我们还可以尝试向 jdbc url 中加入额外属性来明确声明期望遵循的标准: 对于 UTF-8 编码环境而言: ```properties jdbc:mysql://localhost:3306/your_database?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=UTC ``` 而对于 GBK/Gb2312 场景下可相应改为: ```properties jdbc:mysql://localhost:3306/your_database?useUnicode=true&characterEncoding=GB2312&serverTimezone=UTC ``` 这样做的目的是让驱动程序按照所给定指示加载资源从而避免不必要的误解发生. --- ### 总结 针对 `JDBC MySQL Illegal mix of collations for operation 'case'` 这类错误,主要可以从三个方面入手解决:一是标准化所有关联要素至同一套体系之下;二是借助 SQL 内置功能完成临适配动作;三是优化外部交互接口部分使之契合内部实际情况。每种策略都有其适用范围以及局限之处,需依据项目具体情况灵活选用最佳实践路径。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值