我得到下面的错误时,试图做一个选择通过一个存储过程在MySQL。

操作'='的排序规则(latin1_general_cs,IMPLICIT)和(latin1_general_ci,IMPLICIT)的非法混合

你知道哪里出了问题吗?

该表的排序规则为latin1_general_ci, where子句中的列的排序规则为latin1_general_cs。


当前回答

排序规则问题的另一个来源是mysql。proc表。检查存储过程和函数的排序规则:

SELECT
  p.db, p.db_collation, p.type, COUNT(*) cnt
FROM mysql.proc p
GROUP BY p.db, p.db_collation, p.type;

还要注意mysql.proc。Collation_connection和mysql.proc。character_set_client列。

其他回答

一个可能的解决方案是将整个数据库转换为UTF8(另见此问题)。

如果安装了phpMyAdmin,可以按照以下链接中给出的说明进行操作:https://mediatemple.net/community/products/dv/204403914/default-mysql-character-set-and-collation您必须将数据库的排序规则与所有表的排序规则以及表中的字段进行匹配,然后重新编译所有存储过程和函数。这样,一切就都能正常工作了。

在我的例子中,函数的默认返回类型是来自数据库的类型/排序规则(utf8mb4_general_ci),但数据库列是ascii。

WHERE ascii_col = md5(concat_ws(',', a,b,c))

权宜之计是

WHERE ascii_col = BINARY md5(concat_ws(',', a,b,c))

有时转换字符集可能是危险的,特别是在具有大量数据的数据库上。我认为最好的选择是使用“二进制”操作符:

e.g : WHERE binary table1.column1 = binary table2.column1

如果你遇到问题的列是“散列”,那么考虑以下…

如果“hash”是二进制字符串,你应该使用binary(…)数据类型。

如果“哈希”是一个十六进制字符串,你不需要utf8,应该避免这样做,因为字符检查等。例如,MySQL的MD5(…)会产生一个固定长度的32字节十六进制字符串。SHA1(…)给出一个40字节的十六进制字符串。这可以存储到CHAR(32)字符集ascii(或40的sha1)。

或者,更好的是,将UNHEX(MD5(…))存储为BINARY(16)。这样就把柱子的大小减少了一半。(然而,这确实使它不适合印刷。)SELECT十六进制(散列)…如果你想让它可读。

比较两个BINARY列没有排序规则问题。