我得到下面的错误时,试图做一个选择通过一个存储过程在MySQL。
操作'='的排序规则(latin1_general_cs,IMPLICIT)和(latin1_general_ci,IMPLICIT)的非法混合
你知道哪里出了问题吗?
该表的排序规则为latin1_general_ci, where子句中的列的排序规则为latin1_general_cs。
我得到下面的错误时,试图做一个选择通过一个存储过程在MySQL。
操作'='的排序规则(latin1_general_cs,IMPLICIT)和(latin1_general_ci,IMPLICIT)的非法混合
你知道哪里出了问题吗?
该表的排序规则为latin1_general_ci, where子句中的列的排序规则为latin1_general_cs。
当前回答
把我的2c加入到未来谷歌员工的讨论中。
我正在调查一个类似的问题,在使用接收varchar参数的自定义函数时,我得到了以下错误:
Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and
(utf8_general_ci,IMPLICIT) for operation '='
使用以下查询:
mysql> show variables like "collation_database";
+--------------------+-----------------+
| Variable_name | Value |
+--------------------+-----------------+
| collation_database | utf8_general_ci |
+--------------------+-----------------+
我能够告诉DB使用utf8_general_ci,而表是使用utf8_unicode_ci定义的:
mysql> show table status;
+--------------+-----------------+
| Name | Collation |
+--------------+-----------------+
| my_view | NULL |
| my_table | utf8_unicode_ci |
...
注意,视图具有NULL排序规则。视图和函数似乎有排序规则定义,即使该查询为一个视图显示为空。使用的排序规则是创建视图/函数时定义的DB排序规则。
可悲的解决方案是既改变db排序规则,又重新创建视图/函数,迫使它们使用当前的排序规则。
更改db的排序规则: ALTER DATABASE mydb DEFAULT COLLATE utf8 更改表格排序规则: ALTER TABLE mydb CONVERT TO CHARACTER SET utf8 COLLATE
我希望这能帮助到一些人。
其他回答
Very interesting... Now, be ready. I looked at all of the "add collate" solutions and to me, those are band aid fixes. The reality is the database design was "bad". Yes, standard changes and new things gets added, blah blah, but it does not change the bad database design fact. I refuse to go with the route of adding "collate" all over the SQL statements just to get my query to work. The only solution that works for me and will virtually eliminate the need to tweak my code in the future is to re-design the database/tables to match the character set that I will live with and embrace for the long term future. In this case, I choose to go with the character set "utf8mb4".
因此,当您遇到“非法”错误消息时,这里的解决方案是重新设计数据库和表。这比听起来要简单快捷得多。甚至可能不需要导出数据并从CSV重新导入数据。更改数据库的字符集,并确保所有表的字符集都匹配。
使用这些命令来指导您:
SHOW VARIABLES LIKE "collation_database";
SHOW TABLE STATUS;
现在,如果您喜欢在这里或那里添加“collate”,并通过强制完全“重写”来增强代码,请听我的猜测。
我有一个类似的问题,试图使用FIND_IN_SET过程与字符串变量。
SET @my_var = 'string1,string2';
SELECT * from my_table WHERE FIND_IN_SET(column_name,@my_var);
并且正在接收错误
错误码:1267。排序规则的非法混合(utf8_unicode_ci,IMPLICIT) 和(utf8_general_ci,隐式)操作'find_in_set'
简短的回答:
不需要更改任何collation_YYYY变量,只需在变量声明旁边添加正确的排序规则,即。
SET @my_var = 'string1,string2' COLLATE utf8_unicode_ci;
SELECT * from my_table WHERE FIND_IN_SET(column_name,@my_var);
长一点的回答:
我首先检查了排序变量:
mysql> SHOW VARIABLES LIKE 'collation%';
+----------------------+-----------------+
| Variable_name | Value |
+----------------------+-----------------+
| collation_connection | utf8_general_ci |
+----------------------+-----------------+
| collation_database | utf8_general_ci |
+----------------------+-----------------+
| collation_server | utf8_general_ci |
+----------------------+-----------------+
然后我查看了表格整理:
mysql> SHOW CREATE TABLE my_table;
CREATE TABLE `my_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`column_name` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=125 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
这意味着我的变量被配置为默认排序规则utf8_general_ci,而我的表被配置为utf8_unicode_ci。
通过在变量声明旁边添加COLLATE命令,变量排序规则与为表配置的排序规则相匹配。
如果安装了phpMyAdmin,可以按照以下链接中给出的说明进行操作:https://mediatemple.net/community/products/dv/204403914/default-mysql-character-set-and-collation您必须将数据库的排序规则与所有表的排序规则以及表中的字段进行匹配,然后重新编译所有存储过程和函数。这样,一切就都能正常工作了。
MySQL真的不喜欢混合排序规则,除非它可以将它们强制到同一个排序规则(这在您的情况下显然是不可行的)。难道不能通过COLLATE子句强制使用相同的排序规则吗?(或更简单的二进制快捷方式,如果适用…)
这通常是由于比较两个排序规则不兼容的字符串或试图将不同排序规则的数据选择到一个组合列中而导致的。
子句COLLATE允许您指定查询中使用的排序规则。
例如,下面的WHERE子句总是会给出你发布的错误:
WHERE 'A' COLLATE latin1_general_ci = 'A' COLLATE latin1_general_cs
您的解决方案是为查询中的两个列指定共享排序规则。下面是一个使用COLLATE子句的例子:
SELECT * FROM table ORDER BY key COLLATE latin1_general_ci;
另一种选择是使用BINARY操作符:
二进制str是CAST(str AS BINARY)的简写。
你的解决方案可能是这样的:
SELECT * FROM table WHERE BINARY a = BINARY b;
or,
SELECT * FROM table ORDER BY BINARY a;
请记住,正如Jacob Stamm在评论中指出的那样,“转换列来进行比较将导致忽略该列上的任何索引”。
关于整理业务的更多细节,我强烈推荐eggyal对这个问题的出色回答。