MySQL JOIN操作报错问题小解_weixin_30546933的博客-程序员秘密

 

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

Author: CobbLiu

Org version 7.9.3f with Emacs version 24

转载于:https://www.cnblogs.com/cobbliu/p/4272606.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30546933/article/details/96362159

智能推荐

关于双核心CPU 你所不知道的5个“秘密”_sas???的博客-程序员秘密

现在如果谈到处理器,那么“双核”这个词应该会不可避免的被谈及到。看着满大街由INTEL公司打出来的双核处理器广告,相信任何人都不会怀疑2006年将会是属于双核心处理器。但是从相关的双核心处理器的各种报告中我发现有很多的地方是失实的,是会对消费者产生误导的。因此我打算通过今天的这篇文章给大家再介绍一下目前正在日益流行的双核心处理器,这次我会告诉大家有关双核心处理器的五件事,也许...

linux下安装tcpdump_wuchh3的博客-程序员秘密

在一些Linux发行版中,Tcpdump通常作为标准的软件包被默认安装,执行“tcpdump”命令能够确定是否已安装了Tcpdump。假如系统中还没有安装Tcpdump,去www.tcpdump.org下载最新的Tcpdump源码包和libpcap包。Libpcap提供了系统独立的用户级别网络数据包捕获接口,并充分考虑到应用程序的可移植 性。自定义安装目录,将下载的安装包放在此目录下:...

最大子段和 分治_Stupid坨的博客-程序员秘密

求数列的最大子段和。给定n个元素的整数列(可能为负整数)a1,a2,…,an,求形如ai,ai+1,aj,i,j=1,2,…,n,i<=j的子段,使其和为最大。例如,当(a1, a2, a3, a4, a5, a6)=(-2, 11, -4, 13, -5, -2) max_sum =20,best_i = 2,best_j = 4answer:#include<iostream>using namespace std;int max_sub_sum(int a[

【面试题001】最强java八股文_檀越剑指大厂的博客-程序员秘密

一、基础篇网络基础TCP三次握手1、OSI与TCP/IP 模型2、常见网络服务分层3、TCP与UDP区别及场景4、TCP滑动窗口,拥塞控制5、TCP粘包原因和解决方法6、TCP、UDP报文格式HTTP协议1、HTTP协议1.0_1.1_2.02、HTTP与HTTPS之间的区别3、Get和Post请求区别4、HTTP常见响应状态码5、重定向和转发区别6、Cookie和Session区别。浏览器输入URL过程操作系统基础进程和线程的区别1、进程间..

经典算法思路总结_算法思路怎么写_csdn_black的博客-程序员秘密

1、n 从 1 开始,每个操作可以选择对 n 加 1,或者对 n 加倍。如果最后结果为 2013,最少 需要()个操作https://www.nowcoder.com/questionTerminal/5e27998c3f854109905610cac8a5d802?pos=73&mutiTagIds=602&orderByHotValue=1  2、给定一个字符串...

随便推点

uboot环境变量(设置bootargs向linux内核传递正确的参数)_zwtxy1231010的博客-程序员秘密

转载:http://blog.chinaunix.net/u3/94312/showart_1923637.html这是我uboot的环境变量设置,在该设置下可以运行initram内核(从内存下载到nandflash再运行),但是运行nfs根文件系统的时候一直出错,各种错误。查看了很多资料后猜想应该是uboot传递给linux内核的参数有问题,也就是bootargs的设置有问题。#...

bat关闭java_通过bat脚本停止java进程的三个方法_weixin_39609500的博客-程序员秘密

通过bat脚本停止java进程的三个方法1.拷贝java.exe启动时复制java.exe程序修改进程映像名,然后通过映像名杀进程。栗子过程操作拷贝程序拷贝一份java.exe程序,重名为tstop.exe,放在PATH下。修改启动脚本@echo offtitle tstoptstop -jar …/lib/laucher.jar … …/lib/*.jar,…/conf,执行停止命令C:\Use...

【C语言】一个球从100米高的自由落下,每次落地后反跳回原高度的一半,再落下,再反弹。求第10次落地时,共经过多少米,第10次反弹多高。_doudouwa1234的博客-程序员秘密

//一个球从100米高的自由落下,每次落地后反跳回原高度的一半,再落下,再反弹。求第10次落地时,共经过多少米,第10次反弹多高。#include int main(){ float h=100; float s=0; int i; for(i=1;i<10;i++) { h=h/2; s=s+2*h; } printf("第十次的高度为:%f\n",h); prin

R语言基础数据类型_r语言数据类型_小潘的生信笔记的博客-程序员秘密

R语言主要有三种基本的数据类型,分别是数值型(Numeric)、整型(integer)以及字符型(character)。

编码学习之UTF-8_utf-8编码学习_柚子君下的博客-程序员秘密

UTF-8,全称是8-bit unicode transformation format,应该是目前最流行的一种编码。UTF-8是一种变长编码,一个字符占用1~6个字节,通常来说,汉字占有3个字节(虽然我没有找到反例,但是不建议直接这么定义“一个汉字=3个字节)UTF-8向下兼容ASCII码编码的方法如下如上图1. 如果第一个字节的第一个bit是0,表示这是一个ASCII码,一个直接就可以了2. 如果第一个直接的前两个bit是11,代表这是一个字符的第一个Byte,然后从左向右,

vscode的默认设置(配置)列表_vscode 默认打开列表_st独酌的博客-程序员秘密

默认设置(详细)以下是Visual Studio代码的默认设置及其值。您还可以在“设置”编辑器中查看默认值。{// Editor// Controls whether the diff editor shows changes in leading or trailing whitespace as diffs."diffEditor.ignoreTrimW...