背景
实际问题复杂一些,最终发现是一个select语句有问题,这里做一个抽象的记录:
select * from view_a where field_a = '是';
报错collations不匹配,也就是标题中的错误。那么collation
是什么?
创建数据库时,可以指定character set
,比如utf8。而collation
是指定的字符集下的排序规则。
当两个字符串比较时,需要用相同的规则才可以进行对比。
collation的生成规则
具体可以参考MYSQL的官方文档,在这里,简单来说。
- 有指定用指定
- 没有指定,如果指定了字符集,则用字符集默认(可以用
SHOW CHARACTER SET
命令查看字符集的默认collation) - 如果都没有指定,则使用链接数据库的
collation_connection
系统变量。
原因分析
在我的例子中,出问题的field_a
用了utf8_unicode_ci
,而字符串是
,用了utf8_general_ci
。
而我检查了field_a
的定义,发现是一个case when语句生成的字符串,按道理不应该和查询语句例得字符串使用不同的collation
。
解决方案
第一种
一开始没有深入分析,查询到可以在sql语句中强制指定比较用的collation
:
select * from view_a where field_a = '是' collate utf8_general_ci ;
这样就不会报错
第二种
从源头上解决。接着之前的设想,估计是第一次建立这个视图的时候,连接数据库时(或者连接的工具)里设置了另外的默认collation
,导致跟默认的不同。
于是我在本机重新创建了这个视图,再运行原始sql,就没有问题了。