如何解决“非法混合排序规则”SQLException?

Posted

技术标签:

【中文标题】如何解决“非法混合排序规则”SQLException?【英文标题】:Howto resolve "Illegal mix of collations" SQLException? 【发布时间】:2012-06-27 18:04:06 【问题描述】:

我查看了 mysql 参考,在这里,在 *** 中,看起来很多人在字符编码方面遇到了困难,但我找不到这个问题的明确答案:

一个java程序正在使用mysql数据库,当查询中有特殊字符如ű,ő(但á,é,í,ó,ú有效)时,它会抛出一个SQLException:

    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
    Connection conn = DriverManager.getConnection(
            "jdbc:odbc:<database>", "<user>", "<pass>"
            );

    PreparedStatement stmt = conn.prepareStatement(
            " select username, priority " +
            " from users " +
            " where username like ?");
            //" where username like ? collate latin2_general_ci");
    stmt.setString(1, "Ernő");
    ResultSet rs = stmt.executeQuery();
    while(rs.next()) 
        System.out.println(rs.getString("username") + "  " + rs.getInt("priority"));
    

例外:

Exception in thread "main" java.sql.SQLException:
[MySQL][ODBC 5.1 Driver][mysqld-5.1.63-0ubuntu0.10.04.1]
Illegal mix of collations (latin2_hungarian_ci,IMPLICIT)
and (latin1_swedish_ci,COERCIBLE) for operation 'like'

表结构为:

CREATE TABLE `users` (
`username` varchar(45) COLLATE latin2_hungarian_ci NOT NULL,
`password` varchar(45) COLLATE latin2_hungarian_ci NOT NULL,
`priority` tinyint(4) NOT NULL,
`idCimlistaFK` int(10) unsigned DEFAULT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`username`),
KEY `fk_users_tbl_Cimlista1` (`idCimlistaFK`),
CONSTRAINT `fk_users_tbl_Cimlista1` FOREIGN KEY (`idCimlistaFK`)
REFERENCES `tbl_cimlista` (`id_Cimlista`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin2 COLLATE=latin2_hungarian_ci 

当我试图在注释行中强制进行排序时:

" where username like ? collate latin2_general_ci");

它也会抛出异常:

COLLATION 'latin2_general_ci' is not valid for CHARACTER SET 'latin1'

有谁知道,如何解决这个问题(可能在 java 中)? (我不想更改数据库,因为它是一个遗留系统。)

更新:

按照 Rahul Agrawal 的建议,我使用了以下网址:

"jdbc:mysql://localhost:3306/database?characterEncoding=latin2"

它确实有效,但是,我注意到了一个副作用。 当我使用测试服务器更新和插入数据时,它在 Win XP 机器上运行 mysql,一切正常。但是当我更新并将数据插入到运行 Ubuntu 的生产服务器时,我确实得到了行,其中有 ? 符号而不是 ő,ű 字母。从那以后,我通过一种解决方法解决了这个问题,但是很高兴看到并理解出了什么问题,这里有什么问题。

【问题讨论】:

你试过COLLATE latin1_general_ci吗? 是的。没有帮助,但是,我设法让它与 Rahul Agrawal 的建议一起工作。无论如何,谢谢! 【参考方案1】:

您需要使用 UTF-8 字符集

在连接 URL 中试试这个

jdbc:mysql://localhost:3306/testdb?characterEncoding=utf8

数据库 CHARSET=utf8

数据库排序 = utf8_general_ci

【讨论】:

【参考方案2】:

由于显而易见的原因,您并不总是可以更改数据库列。在这些时候,正则表达式可以帮助您。

您可以使用以下内容:

String output = input.replaceAll("[^\\u0020-\\u007e\\u00a0-\\u00ff]",
                                     replaceWithWhateverYouWant);

【讨论】:

以上是关于如何解决“非法混合排序规则”SQLException?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 非法混合排序规则

MySQL某些字符导致“非法混合排序规则”错误

MySql 中的非法混合排序规则错误

“非法混合排序规则”错误与 phpMyAdmin 的库存安装

如何修复“非法混合排序规则(latin1_swedish_ci,IMPLICIT)和(utf8mb4_general_ci,COERCIBLE)以进行'like'操作”?

在 LOCATE 中使用用户定义的变量时,MySQL 非法混合排序规则