有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java“latin1_german1_ci”排序从何而来?

当Java/Spring/Hibernate应用程序试图对mysql数据库执行准备好的语句时,我从中收到以下错误消息:

Caused by: java.sql.SQLException: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin1_german1_ci,COERCIBLE) for operation '='

生成该命令的select语句(如tomcat日志所示)是:

SELECT s.* FROM score_items s where  
s.s_score_id_l=299   and 
(s.p_is_plu_b = 'F')  and 
isTestProduct(s.p_upc_st) = 'N'  and 
v_is_complete_b='T'  
order by s.nc_name_st, s.p_upc_st

每个show table status命令的表排序规则是:

 utf8_general_ci 

所有char、varchar和text字段的排序规则为“utf8_general_ci”。bigint、int和datetime字段为空

数据库排序规则为latin1_swedish_ci,如命令所示:

show variables like "collation_database";

编辑:我能够使用Eclipse/STS和Tomcat 6实例在本地机器上成功地运行它。本地进程正在从与生成错误的生产服务器上的进程相同的数据库中读取。发生错误的服务器是Tomcat 7。实例是一个Amazon Linux服务器

编辑2:当我在QA环境中运行报告时,我也能够成功地运行它,服务器中有JDBC语句。xml重置为指向生产数据库。QA本质上是生产环境的一面镜子,一些开发工作正在进行。我还应该指出,上个月我看到了一个类似的错误,但当我重新阅读报告时,它消失了。最后,我不确定它为什么会有不同,但被查询的表是巨大的,有700多万行,每行可能有100个字段

编辑3:根据Shadow的评论,我发现在测试函数中指定了字符集“latin1”。我把它改成了utf8,希望它能解决这个问题

我如何找出哪个字段是“^{

当表和字段为“utf8_general_ci或null时,为什么要使用“latin1_swedish_ci”进行比较

问题是否与函数字符集有关?如果是,我如何确定它使用的是哪个字符集/排序规则

如何缩小导致问题的字段/功能范围


共 (1) 个答案

  1. # 1 楼答案

    这与java或hibernate无关,这完全取决于mysql,也许还取决于连接字符串

    在mysql中,您可以在多个级别定义字符集和排序规则,这可能会导致很多问题:

    • 服务器
    • 数据库
    • 桌子
    • 纵队
    • 连接

    有关更多详细信息,请参阅character sets and collations上的mysql文档

    总而言之:当且仅当在较低级别未指定字符集或排序规则时,较高级别的默认值才会生效。因此,列级定义将覆盖表级定义show table status命令显示表级默认值,但这些默认值可能已在列级被覆盖show full columnsshow create table命令将显示任何给定字段使用的真实字符集和排序规则

    连接级别的字符集/排序规则定义使情况更加复杂,因为sql语句中使用的字符串常量将使用连接字符集/排序规则,除非它们有显式声明

    然而,mysql使用强制性值来避免使用各种字符集和表达式引起的大多数问题,如character sets / collations used in expressions上的mysql文档所述

    从您提到的在另一台计算机上执行查询时有效,可以看出问题在于连接字符集/排序规则。我认为它将围绕isTestProduct()调用展开

    真正确定导致isdue的条件的唯一方法是逐个消除这些条件,当错误消失时,最后消除的条件就是罪魁祸首。但定义与字段中使用的内容一致的适当连接字符集和排序规则也会有所帮助