187

MySql のエラー メッセージ:

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

他のいくつかの投稿を調べましたが、この問題を解決できませんでした。影響を受ける部分は次のようなものです。

CREATE TABLE users (
    userID INT UNSIGNED NOT NULL AUTO_INCREMENT,
    firstName VARCHAR(24) NOT NULL,
    lastName VARCHAR(24) NOT NULL,
    username VARCHAR(24) NOT NULL,
    password VARCHAR(40) NOT NULL,
    PRIMARY KEY (userid)
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE products (
    productID INT UNSIGNED NOT NULL AUTO_INCREMENT,
    title VARCHAR(104) NOT NULL,
    picturePath VARCHAR(104) NULL,
    pictureThumb VARCHAR(104) NULL,
    creationDate DATE NOT NULL,
    closeDate DATE NULL,
    deleteDate DATE NULL,
    varPath VARCHAR(104) NULL,
    isPublic TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
    PRIMARY KEY (productID)
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE productUsers (
    productID INT UNSIGNED NOT NULL,
    userID INT UNSIGNED NOT NULL,
    permission VARCHAR(16) NOT NULL,
    PRIMARY KEY (productID,userID),
    FOREIGN KEY (productID) REFERENCES products (productID) ON DELETE RESTRICT ON UPDATE NO ACTION,
    FOREIGN KEY (userID) REFERENCES users (userID) ON DELETE RESTRICT ON UPDATE NO ACTION
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci;

私が使用しているストアド プロシージャは次のとおりです。

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
        AND productUsers.productID = rProductID;
END

私はphpでテストしていましたが、SQLyogでも同じエラーが発生します。DB全体の再作成もテストしましたが、うまくいきません。

どんな助けでも大歓迎です。

4

8 に答える 8

251

ストアド プロシージャ パラメーターの既定の照合順序は でutf8_general_ciあり、照合順序を混在させることはできないため、次の 4 つのオプションがあります。

オプション 1 : 入力変数に追加COLLATEします。

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

オプション 2 :句COLLATEに追加:WHERE

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

オプション 3 : パラメータ定義に追加しINます (MySQL 5.7 より前):

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

オプション 4 : フィールド自体を変更します。

ALTER TABLE users CHARACTER SET utf8 COLLATE utf8_general_ci;

Unicode 順でデータを並べ替える必要がない限り、utf8_general_ci照合を使用するようにすべてのテーブルを変更することをお勧めします。コードを変更する必要がなく、並べ替えがわずかに高速化されるためです。

更新: utf8mb4/utf8mb4_unicode_ci が推奨される文字セット/照合方法になりました。utf8_general_ci は、パフォーマンスの向上がごくわずかであるため、使用しないことをお勧めします。https://stackoverflow.com/a/766996/1432614を参照してください

于 2012-08-02T02:25:30.540 に答える
7

同様の問題がありましたが、プロシージャ内で、クエリパラメーターが変数 eg を使用して設定されたときに発生しましたSET @value='foo'

これを引き起こしたのは、不一致collation_connectionとデータベース照合です。collation_connection一致するように変更されcollation_database、問題はなくなりました。これは、param/value の後に COLLATE を追加するよりもエレガントなアプローチだと思います。

要約すると、すべての照合が一致する必要があります。使用SHOW VARIABLESして確認collation_connectionしてcollation_database一致させます ( を使用してテーブルの照合も確認しますSHOW TABLE STATUS [table_name])。

于 2015-11-09T12:49:45.220 に答える
5

@bpileの回答に少し似ていますが、私のケースは my.cnf entry settingcollation-server = utf8_general_ciでした。それに気づいた後(そして上記のすべてを試した後)、データベースをutf8_unicode_ciではなくutf8_general_ciに強制的に切り替えました。

ALTER DATABASE `db` CHARACTER SET utf8 COLLATE utf8_general_ci;
于 2016-07-05T09:40:02.867 に答える
0

私の場合、次のエラーがあります

操作「=」の照合 (utf8_general_ci,IMPLICIT) と (utf8_unicode_ci,IMPLICIT) の不正な組み合わせ

$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 );

数週間の Google 検索の後、比較している 2 つのフィールドが異なる照合名で構成されていることに気付きました。最初のもの、つまりユーザー名は utf8_general_ci のもので、2 番目のものは utf8_unicode_ci のものなので、2 番目のテーブルの構造に戻り、2 番目のフィールド (matric_no) を utf8_general_ci に変更すると、うまくいきました。

于 2018-07-29T07:15:16.990 に答える