有 Java 编程相关的问题?

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

java从uCanAccess结果集中获取难以辨认的字符

我正在用西班牙语字符ñ á é í ó ú查询一个旧的Access 97数据库。我可以使用access很好地读取字符,所以我假设它使用ISO-8859-1,但是我无法将它们转换为UTF-8

不确定我的问题是否与我的连接有关:

public static Connection baseAccess(String base) {
    try {
        java.util.Properties propiedades = new java.util.Properties();
        propiedades.put("charSet", "ISO-8859-1");
        return DriverManager.getConnection(String.format("jdbc:ucanaccess://%s", base),propiedades);
    } catch (SQLException ex) {}
}

或者通过我对字符串的解析:

try (ResultSet rs = UtileriaDb.baseAccess(contabilidad).createStatement().executeQuery(sql);){
    while(rs.next()){
        String fromAccess = rs.getString(1);
        System.out.println(fromAccess);
        String transformed = new String(fromAccess.getBytes("ISO-8859-1"),"UTF-8");
        System.out.println(transformed);
    }
} catch (Exception ex) { }

所以当我期待:

Año Café

我得到:

A�o Caf�

A?o Caf?

尝试通过执行以下操作从结果集中获取字节内容:byte[] fromAccess = rs.getBytes(1);,但我遇到了一个异常

net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::4.0.4 incompatible data type in conversion: from SQL type VARCHAR to [B, value: myText
    at net.ucanaccess.jdbc.UcanaccessResultSet.getBytes(UcanaccessResultSet.java:339)

所以这是一条死胡同。有没有别的办法


共 (1) 个答案

  1. # 1 楼答案

    正如@Scratte正确指出的那样,rs.getString(1)返回的字符串已经包含替换字符。感谢他帮我指向this questionthis discussion

    我最终实现了一个ucanaccess JackcessOpenerInterface,工作非常出色

    package com.company.somepackage;
    
    import com.healthmarketscience.jackcess.Database;
    import com.healthmarketscience.jackcess.DatabaseBuilder;
    import java.io.File;
    import java.io.IOException;
    import java.nio.charset.Charset;
    import net.ucanaccess.jdbc.JackcessOpenerInterface;
    
    public class CharsetOpener implements JackcessOpenerInterface {
        public Database open(File f, String pwd) throws IOException {
            DatabaseBuilder db = new DatabaseBuilder(f);
            db.setCharset(Charset.forName("ISO-8859-1"));
            try {
                db.setReadOnly(false);
                return db.open();
            } catch (IOException e) {
                db.setReadOnly(true);
                return db.open();
            }
       }
    }
    

    对于我的连接生成器中的实现:

    public static Connection baseAccess(String base) {
        try {
            java.util.Properties propiedades = new java.util.Properties();
            propiedades.put("jackcessOpener", "com.company.somepackage.CharsetOpener");
            return DriverManager.getConnection(String.format("jdbc:ucanaccess://%s", base),propiedades);
        } catch (SQLException ex) {}
    }
    

    请注意,实际属性是jackcessOpener,必须指向完全限定的类名