ResultSet.updateRow() 为操作 '<=>' 生成"排序规则 (latin1_bin,IMPLICIT) 和 (utf8_general_ci,COERCIBLE)



我有下表,name是拉丁语1,其余是UTF8。

CREATE TABLE `test_names` (
  `name` varchar(500) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
  `other_stuff_1` int DEFAULT NULL,
  `other_stuff_2` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

我在 Java 中遇到以下问题:

SELECT ... FOR UPDATE. 然后我调用updateInt(2, 1)并在其结果集上updateRow()并得到Illegal mix of collations (latin1_bin,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '<=>'

如何在不更改表/连接的字符集的情况下完成这项工作?

多谢。

---更新---

我使用SELECT name, other_stuff_1 FROM test_names LIMIT 1 FOR UPDATE;,连接字符串DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + db + "?allowMultiQueries=true", user, password);

确切的堆栈跟踪为:

java.sql.SQLException: Illegal mix of collations (latin1_bin,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '<=>'
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1086)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4237)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4169)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2617)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2778)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2834)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2156)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2441)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2366)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2350)
    at com.mysql.jdbc.UpdatableResultSet.updateRow(UpdatableResultSet.java:2405)

从我的角度来看,我可以给你一些建议

  1. 首先更新连接器/J 最新版本。
  2. 运行此查询
SET NAMES='utf8'
  1. &characterEncoding=UTF-8添加到 JDBC 连接字符串中。希望你已经做到了。

  2. 使用convert() for insert or updatecast() for select查询。欲了解更多详情 http://dev.mysql.com/doc/refman/5.7/en/charset-convert.html

  3. 对于"非法混合排序
  4. 规则"相关问题,您可以跟进排查mysql中的"非法混合排序规则"错误

问题是您正在尝试从在不同列上具有不同字符集的表中进行选择。

您必须使用 CONVERT() 将查询中具有不同字符集的列转换为正确的字符集。

http://dev.mysql.com/doc/refman/5.7/en/charset-convert.html

在这种情况下,应将查询修改为:

SELECT CONVERT(name USING latin1), other_stuff_1 FROM test_names LIMIT 1 FOR UPDATE;

恕我直言,当表中的编码不统一时,在这种情况下,您不能使用可更新的结果集(例如,主键在 latin1 中,但其他列在 utf8 中)。

正如 Andras 指出的那样,您可以在 sql 端转换编码,但随后您将无法更新结果集。

为什么不简单地使用 executeUpdate(...) 更新表?您可以通过简单的选择缩小目标行的范围,然后遍历生成的主键列表并调用 executeUpdate。

对我来说,这适用于混合编码列。举个例子:

    conn.setAutoCommit(false);
    ResultSet rs = st.executeQuery("SELECT name other_stuff_1 FROM test_names");
    List<String> keys = new ArrayList<String>();
    while(rs.next()) {
        keys.add(rs.getString(1));
    }
    rs.close();
    for(String key : keys) {
        st.executeUpdate("update test_names set other_stuff_1='"+key.length()+"', other_stuff_2='" + key.toUpperCase() + "' where name='" + key + "'");
    }
    conn.commit();

相关内容

  • 没有找到相关文章

最新更新