我得到下面的错误时,试图做一个选择通过一个存储过程在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。
当前回答
如果你遇到问题的列是“散列”,那么考虑以下…
如果“hash”是二进制字符串,你应该使用binary(…)数据类型。
如果“哈希”是一个十六进制字符串,你不需要utf8,应该避免这样做,因为字符检查等。例如,MySQL的MD5(…)会产生一个固定长度的32字节十六进制字符串。SHA1(…)给出一个40字节的十六进制字符串。这可以存储到CHAR(32)字符集ascii(或40的sha1)。
或者,更好的是,将UNHEX(MD5(…))存储为BINARY(16)。这样就把柱子的大小减少了一半。(然而,这确实使它不适合印刷。)SELECT十六进制(散列)…如果你想让它可读。
比较两个BINARY列没有排序规则问题。
其他回答
解决方案,如果文字涉及。
我使用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,错误已经消失。:)
如果安装了phpMyAdmin,可以按照以下链接中给出的说明进行操作:https://mediatemple.net/community/products/dv/204403914/default-mysql-character-set-and-collation您必须将数据库的排序规则与所有表的排序规则以及表中的字段进行匹配,然后重新编译所有存储过程和函数。这样,一切就都能正常工作了。
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”,并通过强制完全“重写”来增强代码,请听我的猜测。
下面的方法对我很有效。
CONVERT( Table1.FromColumn USING utf8) = CONVERT(Table2.ToColumn USING utf8)
这通常是由于比较两个排序规则不兼容的字符串或试图将不同排序规则的数据选择到一个组合列中而导致的。
子句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对这个问题的出色回答。