通过JDBC-ODBC从Access数据库中读取Unicode字符

时间:2013-10-05 00:37:39

标签: java ms-access jdbc unicode jdbc-odbc

我的Access 2010数据库中有一些非标准字符。当我通过

阅读它们时
Connection con = null;
try{
    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
    java.util.Properties prop = new java.util.Properties();
    prop.put("charSet", "UTF8");
    String database = "jdbc:odbc:Lb";
    con = DriverManager.getConnection(database, prop);
} catch (Exception ex) {
    System.out.println("Error");
}
Statement stm = conn.createStatement();
ResultSet rs = stm.executeQuery("SELECT distinct forename, surname from PSN where isValid");

while (rs.next()) {
    String forename = rs.getString("forename");
}

我收到字符所在的问号(?)。这是为什么?

4 个答案:

答案 0 :(得分:1)

当DB包含波兰字符时,我有问号。当我将charecter编码设置为windows-1250时,它已得到修复。

def establish(dbFile: File): Connection = {
  val fileName = dbFile.getAbsolutePath
  val database = s"${driver}DBQ=${fileName.trim};DriverID=22;READONLY=true}"
  val props = new Properties()
  props.put("charSet", "Cp1250")
  val connection= DriverManager.getConnection(database,props)
  connection
}

答案 1 :(得分:0)

我希望您的JDBC驱动程序能够透明地处理对数据库的读写字符。 Java的内部字符串表示形式是UTF-16。

Java(UTF-16)         --JDBC--> Database(DbEncoding)
Database(DbEncoding) --JDBC--> Java(UTF-16) 

也许问题是你试图用UTF8强制读取它们而数据库使用另一个内部表示?

另外,您如何确认收到'?'

如果涉及System.out,则应考虑此PrintStream将内存字符串转换为它使用的Charset。 IIRC这个Charset可以在Charset.defaultcharset()中找到,并且是运行该程序的JVM的属性。

最好检查char的十六进制值并查找Unicode表,以确保从数据库读取时信息已丢失。

希望这有点帮助。

答案 2 :(得分:0)

这是Access ODBC驱动程序和JDBC-ODBC Bridge之间长期存在的互操作性问题。 Access使用UTF-16LE编码的变体( UTF-8)存储Unicode字符,并且JDBC-ODBC桥无法检索它们。

(请注意,这不是Access ODBC驱动程序本身的问题,因为Python的pyodbc等其他工具可以正确检索Unicode字符。这是兼容性问题。 JDBC-ODBC Bridge和Access ODBC驱动程序。)

2005年11月向Sun提交了bug report概述了该问题。该报告于2013年4月以评论

结束为“无法修复”
  

该桥已从Java SE 8中删除,不受支持

如果您需要在Access数据库中使用任意Unicode字符,则应考虑使用UCanAccess。有关更多信息,请参阅

Manipulating an Access database from Java without ODBC

答案 3 :(得分:0)

这不是“utf8”,“Cp1250”!

必须使用: ISO-8859-1

java.util.Properties prop = new java.util.Properties();
prop.put("charSet", "ISO-8859-1");
String connURL = "jdbc:odbc:DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=" + accessFileName + ";uid=''; pwd='';";    
sql = "SELECT * FROM enq_horaires;";'
con = DriverManager.getConnection(connURL, prop);
stmt = con.createStatement();
ResultSet rset = stmt.executeQuery(sql);