MySQL JOIN操作报错问题小解
1 问题描述
在调用一个MySQL存储过程的时候,有时候会出现下面的错误:
Illigal mix of collations(gbk\_chinese\_ci, IMPLICIT) and (latin1\_swedish\_ci, IMPLICIT) for operation '='
我从去年到现在遇到了很多这个问题,这篇文章做一下解决方法的总结,基本上能覆盖这个问题的所有解法
2 问题根源
这个问题的出现是由于JOIN操作时=操作符的左右参数的字符编码不一致导致导致的,解决问题的方法也基于此
3 问题解法
存储过程的代码千奇百怪,导致这个问题的原因也有多种多样。下面就由浅入深地谈谈这个问题的解法
3.1 step1
遇到这个问题首先要做的,就是要查看存储过程中JOIN操作的两列的字符编码是否一致,如果其中一个是GBK,另一个是UTF8,那就要统一这两列的字符编码,具体修改成哪个, 看你的应用场景,一般情况下,建议使用UTF8,GBK更容易被SQL攻击,没有中文的数据时,就不要使用GBK了。
3.2 step2
如果step1修改后还是不能解决上面的问题,那您就需要查看一下您的存储过程中是否有where条件,很可能是您的where条件中=左右两侧的数据编码不一致,通过 show variables like '%character%' 命令查看client的编码是否跟database的编码一致。
+--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | gbk | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | gbk | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+
3.3 step3
上面的调整基本上能解决大部分此类问题,但是我们的存储过程依然执行不了。经过一番分析,发现我们的存储过程中会新建一个临时表,代码大概是这样:
INSERT INTO tmp(region, cell, relation) SELECT DISTINCT r.region, t.cell, -1 FROM rr_tmp r LEFT JOIN ( SELECT DISTINCT region, cell FROM ri_tmp ri, ce_tmp ct WHERE ri.region=ce.region) t ON r.region=t.region WHERE r.region is null;
我们怀疑字符编码不一致的原因是这个临时表的字符编码与rr_tmp表的字符编码不一致导致的,但是如何控制临时表的字符编码呢?
临时表的字符编码其实就是数据库的默认字符编码,通过 show create database test_db
可以看到数据库的字符编码 将数据库的字符编码修改成与rr_tmp的字符编码一致,就OK了
alter database test_db characeter set utf8
Date: 2015-02-04T15:58+0800
相关文章
- MySQL Binlog Digger 4.28 【mysql日志分析工具】
- mysql高性能分页语句_如何优化Mysql千万级快速分页
- mysql binary like_MYSQL的binary解决mysql数据大小写敏感问题的方法
- VS2013与MySql建立连接;您的项目引用了最新实体框架;但是,找不到数据链接所需的与版本兼容的实体框架数据库 EF6使用Mysql的技巧
- MySQL修改视图(ALTER VIEW)
- 十一、Mysql - 主从复制原理 - 异步复制
- mysql系列报错
- mysql 报错从 新安装
- MySQL中间件之ProxySQL(7):详述ProxySQL的路由规则
- ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061),mysql服务已启动
- 转 mysql spool_用MySQL实现类似Oracle SPOOL的功能
- python操作mysql数据库系列-操作MySql数据库(五)
- 浅析mysql报错:Error writing file '/tmp/MY4QWdUa' (Errcode: 28 - No space left on device) 磁盘空间不足的问题和解决思路
- MySQL 5.7 Invalid default value for 'CREATE_TIME'报错的解决方法
- Starting MySQL. ERROR! The server quit without updating PID file(xxx/x.pid)
- (3.11)mysql基础深入——mysql文件分类与配置文件管理
- mysql大致学习路径
- MySQL启动报错“Bind on TCP/IP port: Address already in use”
- Mysql 1290 - The MySQL server is running with the --secure-file-priv option
- Linux 之 LNMP服务器搭建-MySQL