排序规则的非法混合 MySQL 错误

Posted

技术标签:

【中文标题】排序规则的非法混合 MySQL 错误【英文标题】:Illegal mix of collations MySQL Error 【发布时间】:2010-11-03 17:51:12 【问题描述】:

我在处理大量数据时遇到了这个奇怪的错误...

Error Number: 1267

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

SELECT COUNT(*) as num from keywords WHERE campaignId='12' AND LCASE(keyword)='hello again 昔 ã‹ã‚‰ ã‚ã‚‹ å ´æ‰€'

我能做些什么来解决这个问题?我可以以某种方式对字符串进行转义,这样就不会发生此错误,或者我是否需要以某种方式更改我的表编码,如果是,我应该将其更改为什么?

【问题讨论】:

这个错误,是不是注射剂? 这能回答你的问题吗? Illegal mix of collations error in mysql 【参考方案1】:
SET collation_connection = 'utf8_general_ci';

然后为您的数据库

ALTER DATABASE your_database_name CHARACTER SET utf8 COLLATE utf8_general_ci;

ALTER TABLE your_table_name CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

MySQL 有时会无缘无故地潜入瑞典语。

【讨论】:

@Ben:它最初是由一家瑞典公司开发的...这就是烦人的 latin1_swedish_ci 初始设置背后的原因.. :( 我没有权限执行第一条语句,但它只在表格中起作用 看起来这适用于很多人,但不幸的是,即使在尝试了此线程中的所有设备后,我仍然遇到此问题。我的数据库默认排序规则顽固地拒绝从“ucs2_bin”更改,所以甚至尝试将所有表和连接排序规则更改为“usc2_bin”,但我仍然收到错误“SQL 错误(1267):排序规则的非法混合(utf8_general_ci,IMPLICIT)和(ucs2_bin,IMPLICIT) 用于操作 '='"。 在充满数据的生产数据库上执行此操作真的安全吗? 不,不是真的,事实上这是个坏主意。连接的应用程序可能会设置一个字符集,并且可能会直接在 Web 上输出数据,例如现在使用与数据不匹配的字符集标题。这些命令在生产环境中非常危险,并且应该与连接到数据库的应用程序的任何潜在问题的审计相吻合。【参考方案2】:
CONVERT(column1 USING utf8)

解决了我的问题。其中 column1 是给我这个错误的列。

【讨论】:

对我来说,这行得通:CONVERT("column1" USING LATIN1)【参考方案3】:

您应该将表编码和连接编码都设置为UTF-8

ALTER TABLE keywords CHARACTER SET UTF8; -- run once

SET NAMES 'UTF8';
SET CHARACTER SET 'UTF8';

【讨论】:

这两样都需要,还是我可以只做其中之一? ALTER DATABASE myDb 默认字符集 utf8 整理 utf8_bin 。那行得通吗?这样做是为了影响我的所有表,而不仅仅是其中一个 ALTER DATABASE 不会更改您当前的表设置,只会更改新创建的表设置。更改数据库的默认字符集也无妨。 SET NAMES 和 SET CHARACTER SET 会改变你的连接编码。您需要在每次连接时发出这些命令。您的客户端库可能支持更优雅的方法来执行此操作(php::mysqli 支持,php::mysql 不支持)。 现在似乎可以工作,经过更多测试后我会接受。第二个查询需要运行一次,还是在每个脚本开始时运行?【参考方案4】:

使用以下语句表示错误

如果表中有数据,请注意备份数据。

 ALTER TABLE your_table_name CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

【讨论】:

【参考方案5】:

我的表最初是用 CHARSET=latin1 创建的。在表转换为 utf8 之后,一些列没有被转换,但这并不是很明显。 您可以尝试运行 SHOW CREATE TABLE my_table; 并查看未转换的列,或者使用以下查询修复有问题的列上的不正确字符集(根据您的需要更改 varchar 长度和 CHARSET 和 COLLATE):

 ALTER TABLE `my_table` CHANGE `my_column` `my_column` VARCHAR(10) CHARSET utf8 
 COLLATE utf8_general_ci NULL;

【讨论】:

【参考方案6】:

我发现使用cast() 对我来说是最好的解决方案:

cast(Format(amount, "Standard") AS CHAR CHARACTER SET utf8) AS Amount

还有一个convert() 函数。更多详情here

另一个资源here

【讨论】:

【参考方案7】:

一般来说,最好的方法是更改​​表排序规则。但是,我有一个旧应用程序,并且无法真正估计结果是否有副作用。因此,我尝试以某种方式将字符串转换为解决排序规则问题的其他格式。 我发现工作是通过将字符串转换为其字符的十六进制表示来进行字符串比较。在数据库中,这是通过 HEX(column). 完成的。对于 PHP,您可以使用此函数:

public static function strToHex($string)

    $hex = '';
    for ($i=0; $i<strlen($string); $i++)
        $ord = ord($string[$i]);
        $hexCode = dechex($ord);
        $hex .= substr('0'.$hexCode, -2);
    
    return strToUpper($hex);

在进行数据库查询时,必须先将原始 UTF8 字符串转换为 iso 字符串(例如,在 PHP 中使用 utf8_decode()),然后才能在数据库中使用它。由于排序规则类型,数据库内部不能包含 UTF8 字符,因此比较应该有效,尽管这会更改原始字符串(转换 ISO 字符集中不存在的 UTF8 字符会导致 ? 或这些字符被完全删除)。只需确保在将数据写入数据库时​​,使用相同的 UTF8 到 ISO 转换。

【讨论】:

【参考方案8】:

将表格的字符集改为utf8

ALTER TABLE your_table_name 转换为字符集 utf8

【讨论】:

【参考方案9】:

按照in this solution的建议,我的用户帐户没有更改数据库和表的权限。

如果您像我一样不关心character collation(您使用的是“=”运算符),则可以应用反向修复。在您的 SELECT 之前运行它:

SET collation_connection = 'latin1_swedish_ci';

【讨论】:

感谢发帖。我的数据库已经设置为 utf8,我的会话字符集和排序规则都是 utf8 和二进制。这是唯一有效的解决方法,无需深入挖掘。【参考方案10】:

在最重要的答案中列出您的更正后,更改服务器的默认设置。

在您的“/etc/my.cnf.d/server.cnf”或它所在的任何地方,将默认值添加到 [mysqld] 部分,这样它看起来像这样:

[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci

来源:https://dev.mysql.com/doc/refman/5.7/en/charset-applications.html

【讨论】:

以上是关于排序规则的非法混合 MySQL 错误的主要内容,如果未能解决你的问题,请参考以下文章

MySql 中的非法混合排序规则错误

当所有排序规则都已经标准化时,Mysql 非法混合排序规则

MySQL 非法混合排序规则

MySQL 视图 - 排序规则的非法混合

出现问题:MySQL中的排序规则的非法混合[重复]

MySQL 将排序规则与所有 utf8 db/tables/columns 非法混合