zoukankan      html  css  js  c++  java
  • 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

    Author: CobbLiu

    Org version 7.9.3f with Emacs version 24

  • 相关阅读:
    GO-GRPC实践(二) 增加拦截器,实现自定义context(带request_id)、recover以及请求日志打印
    第六章-堆
    第五章-本地方法接口和本地方法栈
    第四章-虚拟机栈
    第三章-运行时数据区及程序计数器
    04-再谈类的加载器
    03-类的加载过程(类的生命周期)详解
    1.编程入门
    SpringBoot 整合 SpringSecurity 梳理
    pip版本过低无法升级问题
  • 原文地址:https://www.cnblogs.com/cobbliu/p/4272606.html
Copyright © 2011-2022 走看看