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

前端 未结 8 1236
一向
一向 2020-11-28 21:36

Error message on MySql:

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

I have gone

相关标签:
8条回答
  • 2020-11-28 21:47

    In my own case I have the following error

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

    $this->db->select("users.username as matric_no, CONCAT(users.surname, ' ', users.first_name, ' ', users.last_name) as fullname") ->join('users', 'users.username=classroom_students.matric_no', 'left') ->where('classroom_students.session_id', $session) ->where('classroom_students.level_id', $level) ->where('classroom_students.dept_id', $dept);

    After weeks of google searching I noticed that the two fields I am comparing consists of different collation name. The first one i.e username is of utf8_general_ci while the second one is of utf8_unicode_ci so I went back to the structure of the second table and changed the second field (matric_no) to utf8_general_ci and it worked like a charm.

    0 讨论(0)
  • 2020-11-28 21:49

    I spent half a day searching for answers to an identical "Illegal mix of collations" error with conflicts between utf8_unicode_ci and utf8_general_ci.

    I found that some columns in my database were not specifically collated utf8_unicode_ci. It seems mysql implicitly collated these columns utf8_general_ci.

    Specifically, running a 'SHOW CREATE TABLE table1' query outputted something like the following:

    | table1 | CREATE TABLE `table1` (
    `id` int(11) NOT NULL,
    `col1` varchar(4) CHARACTER SET utf8 NOT NULL,
    `col2` int(11) NOT NULL,
    PRIMARY KEY (`col1`,`col2`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
    

    Note the line 'col1' varchar(4) CHARACTER SET utf8 NOT NULL does not have a collation specified. I then ran the following query:

    ALTER TABLE table1 CHANGE col1 col1 VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL;

    This solved my "Illegal mix of collations" error. Hope this might help someone else out there.

    0 讨论(0)
  • 2020-11-28 21:58

    This happens where a column is explicitly set to a different collation or the default collation is different in the table queried.

    if you have many tables you want to change collation on run this query:

    select concat('ALTER TABLE ', t.table_name , ' CONVERT TO CHARACTER 
    SET utf8 COLLATE utf8_unicode_ci;') from (SELECT table_name FROM 
    information_schema.tables where table_schema='SCHRMA') t;
    

    this will output the queries needed to convert all the tables to use the correct collation per column

    0 讨论(0)
  • 2020-11-28 22:01

    Answer is adding to @Sebas' answer - setting the collation of my local environment. Do not try this on production.

    ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_unicode_ci;
    
    ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
    

    Source of this solution

    0 讨论(0)
  • 2020-11-28 22:08

    The default collation for stored procedure parameters is utf8_general_ci and you can't mix collations, so you have four options:

    Option 1: add COLLATE to your input variable:

    SET @rUsername = ‘aname’ COLLATE utf8_unicode_ci; -- COLLATE added
    CALL updateProductUsers(@rUsername, @rProductID, @rPerm);
    

    Option 2: add COLLATE to the WHERE clause:

    CREATE PROCEDURE updateProductUsers(
        IN rUsername VARCHAR(24),
        IN rProductID INT UNSIGNED,
        IN rPerm VARCHAR(16))
    BEGIN
        UPDATE productUsers
            INNER JOIN users
            ON productUsers.userID = users.userID
            SET productUsers.permission = rPerm
            WHERE users.username = rUsername COLLATE utf8_unicode_ci -- COLLATE added
            AND productUsers.productID = rProductID;
    END
    

    Option 3: add it to the IN parameter definition:

    CREATE PROCEDURE updateProductUsers(
        IN rUsername VARCHAR(24) COLLATE utf8_unicode_ci, -- COLLATE added
        IN rProductID INT UNSIGNED,
        IN rPerm VARCHAR(16))
    BEGIN
        UPDATE productUsers
            INNER JOIN users
            ON productUsers.userID = users.userID
            SET productUsers.permission = rPerm
            WHERE users.username = rUsername
            AND productUsers.productID = rProductID;
    END
    

    Option 4: alter the field itself:

    ALTER TABLE users CHARACTER SET utf8 COLLATE utf8_general_ci;
    

    Unless you need to sort data in Unicode order, I would suggest altering all your tables to use utf8_general_ci collation, as it requires no code changes, and will speed sorts up slightly.

    UPDATE: utf8mb4/utf8mb4_unicode_ci is now the preferred character set/collation method. utf8_general_ci is advised against, as the performance improvement is negligible. See https://stackoverflow.com/a/766996/1432614

    0 讨论(0)
  • 2020-11-28 22:09

    A bit similar to @bpile answer, my case was a my.cnf entry setting collation-server = utf8_general_ci. After I realized that (and after trying everything above), I forcefully switched my database to utf8_general_ci instead of utf8_unicode_ci and that was it:

    ALTER DATABASE `db` CHARACTER SET utf8 COLLATE utf8_general_ci;
    
    0 讨论(0)
提交回复
热议问题