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


124

在处理大量数据时出现此奇怪的错误...

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 昔 ã‹ã‚‰ ã‚ã‚‹ å ´æ‰€'

我该怎么解决?我可以以某种方式转义字符串,以免发生此错误,还是我需要以某种方式更改表编码,如果是,应该将其更改为什么?


这个错误,是否可以注射?
hamza irizaj

1
这回答了你的问题了吗?MySql中非法归类错误混合
Farhan

Answers:


288
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有时会毫无理智地潜入瑞典。


3
@Ben:感谢您提供直接复制可复制的解决方案。节省了我很多时间。
Pistos

15
@Ben:它最初是由一家瑞典公司开发的...这就是恼人的
latin1_swedish_ci

1
我没有权限做第一条陈述,但它只适用于餐桌
Rob Sedgwick 2015年

为此爱你!:P
prateekkathal

看起来这对很多人都有效,但是不幸的是,即使尝试了该线程中的所有设备,我仍然遇到这个问题。我的数据库默认排序规则顽固地拒绝从'ucs2_bin'进行更改,因此甚至尝试将所有表和连接排序规则更改为'usc2_bin',但仍然收到错误“ SQL错误(1267):排序规则(utf8_general_ci,IMPLICIT)的非法混合,并且(ucs2_bin,IMPLICIT)用于操作'='“。
bikeman868

15

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

ALTER TABLE keywords CHARACTER SET UTF8; -- run once

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

这些都是必需的,还是我可以只做其中之一?
点击在2009年

ALTER DATABASE myDbDEFAULT CHARACTER SET utf8 COLLATE utf8_bin。那行得通吗?这样做是为了影响到我所有的表,而不仅仅是其中的一个表
单击Upvote 2009年

1
ALTER DATABASE不会更改您当前的表设置,只会更改新创建的设置。尽管它也不会改变数据库的默认字符集。
Quassnoi

SET NAMES和SET CHARACTER SET将更改您的连接编码。您每次连接时都需要发出这些命令。您的客户端库可能支持更优雅的方法(php :: mysqli支持,php :: mysql不支持)。
Quassnoi

似乎暂时可以使用,我将在进行更多测试后接受。第二个查询需要运行一次还是在每个脚本的开头运行?
点击在2009年

13
CONVERT(column1 USING utf8)

解决我的问题。其中column1是给出此错误的列。


对我来说,这
可行

4

使用以下语句出错

如果数据在表中,请小心数据备份。

 更改表your_table_name转换为字符集utf8收集utf8_general_ci;

2

通常,最好的方法是更改​​表排序规则。但是我有一个旧的应用程序,并不能真正估计结果是否有副作用。因此,我尝试以某种方式将字符串转换为解决排序规则问题的其他格式。我发现工作是通过将字符串转换为其字符的十六进制表示来进行字符串比较。在数据库上,这是通过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字符串(例如,utf8_decode()在PHP中使用),然后才能在数据库中使用它。由于排序规则类型,数据库内部不能包含UTF8字符,因此比较应该起作用,尽管这会更改原始字符串(转换ISO字符集中不存在的UTF8字符会导致?或将其完全删除)。只要确保在将数据写入数据库时​​使用相同的UTF8到ISO的转换即可。


2

我的表最初是使用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;




0

我的用户帐户没有此解决方案中建议的更改数据库和表的权限。

如果像我一样,您不关心字符排序规则(正在使用'='运算符),则可以应用反向修复。在选择之前运行此命令:

SET collation_connection = 'latin1_swedish_ci';
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.