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

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

你知道哪里出了问题吗?

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


当前回答

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”,并通过强制完全“重写”来增强代码,请听我的猜测。

其他回答

我个人在一次手术中遇到过这个问题。 如果你不想改变表,你可以尝试将你的参数转换为过程。 我已经尝试了几次使用collate(与一个集到选择),但没有一个适合我。

CONVERT(my_param USING utf32)做到了这一点。

下面的方法对我很有效。

CONVERT( Table1.FromColumn USING utf8)    =  CONVERT(Table2.ToColumn USING utf8) 

把我的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

我希望这能帮助到一些人。

解决方案,如果文字涉及。

我使用Pentaho数据集成,不需要指定sql语法。 使用非常简单的DB查找就会出现错误 "操作'='的排序规则(cp850_general_ci, coerble)和(latin1_swedish_ci, coerble)的非法混合"

生成的代码是 SELECT DATA_DATE AS latest DATA_DATE FROM hr_cc_normalised_data_date_v WHERE PSEUDO_KEY = ?"

长话短说,查找是一个视图,当我发布

mysql> show full columns from hr_cc_normalised_data_date_v;
+------------+------------+-------------------+------+-----+
| Field      | Type       | Collation         | Null | Key |
+------------+------------+-------------------+------+-----+
| PSEUDO_KEY | varchar(1) | cp850_general_ci  | NO   |     |
| DATA_DATE  | varchar(8) | latin1_general_cs | YES  |     |
+------------+------------+-------------------+------+-----+

这就解释了“cp850_general_ci”的来源。

视图是用'SELECT 'X',......'创建的 根据手册,这样的文字应该从服务器设置继承字符集和排序规则服务器设置被正确地定义为" latin1 "和" latin1_general_cs " 因为这显然没有发生,我强迫它在创建视图

CREATE OR REPLACE VIEW hr_cc_normalised_data_date_v AS
SELECT convert('X' using latin1) COLLATE latin1_general_cs        AS PSEUDO_KEY
    ,  DATA_DATE
FROM HR_COSTCENTRE_NORMALISED_mV
LIMIT 1;

现在它为两个列显示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列。