Java 无法通过 JDBC-ODBC 从 Access 检索 Unicode(立陶宛语)字母

Edg*_*lov 2 java ms-access jdbc character-encoding jdbc-odbc

我有数据库,其中一些名称是用立陶宛字母写的,但是当我尝试使用 java 获取它们时,它会忽略立陶宛字母

\n\n
    DbConnection();\n    zadanie=connect.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);\n    sql="SELECT * FROM Clients;";   \n    dane=zadanie.executeQuery(sql);\n\n    String kas="Imon\xc4\x97";\n    while(dane.next())\n    {\n         String var=dane.getString("Pavadinimas");       \n         if (var!= null) {var =var.trim();} \n         String rus =dane.getString("Rusys");   \n         System.out.println(kas+" "+rus);\n    }\n\n    void DbConnection() throws SQLException\n    {\n        String baza="jdbc:odbc:DatabaseDC"; \n        try\n        {\n            Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");\n        }catch(Exception e){System.out.println("Connection error");}\n        connect=DriverManager.getConnection(baza);\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

在 DB 中,字段类型为 TEXT,大小为 20,不要使用任何其他字母解码或类似的内容。

\n\n

它给了我“ Imon\xc4\x97 Imone ”,尽管在数据库中写的是“Imon\xc4\x97”,它等于rus。

\n

Gor*_*son 5

现在 JDBC-ODBC 桥已从 Java 8 中删除,这个特定问题将越来越成为一个历史兴趣项目,但需要记录一下:

\n\n

对于代码点 U+00FF 以上的 Unicode 字符,JDBC-ODBC 桥从未与 Access ODBC 驱动程序(“Jet”和“ACE”)正确配合使用。这是因为 Access 将此类字符存储为 Unicode,但它使用 UTF-8 编码。相反,它使用 UTF-16LE 的“压缩”变体,其中代码点 U+00FF 及以下的字符存储为单个字节,而 U+00FF 以上的字符存储为空字节,后跟其 UTF-16LE 字节对(s)。

\n\n

如果字符串“Imon\xc4\x97\”存储在 Access 数据库中,以便它在 Access 本身中正确显示

\n\n

访问编码.png

\n\n

然后它被存储为

\n\n
I  m  o  n  \xc4\x97\n-- -- -- -- --------\n49 6D 6F 6E 00 17 01\n
Run Code Online (Sandbox Code Playgroud)\n\n

(\'\xc4\x97\' 是 U+0117)。

\n\n

JDBC-ODBC 桥不理解它从 Access ODBC 驱动程序接收到的最后一个字符的内容,因此它只是返回

\n\n
Imon?\n
Run Code Online (Sandbox Code Playgroud)\n\n

另一方面,如果我们尝试使用 UTF-8 编码将字符串存储在 Access 数据库中,就像 JDBC-ODBC 桥尝试插入字符串本身一样

\n\n
Statement s = con.createStatement();\ns.executeUpdate("UPDATE vocabulary SET word=\'Imon\xc4\x97\' WHERE ID=5");\n
Run Code Online (Sandbox Code Playgroud)\n\n

该字符串将被 UTF-8 编码为

\n\n
I  m  o  n  \xc4\x97\n-- -- -- -- -----\n49 6D 6F 6E C4 97\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后 Access ODBC 驱动程序会将其存储在数据库中:

\n\n
I  m  o  n  \xc3\x84  \xe2\x80\x94\n-- -- -- -- -- ---------\n49 6D 6F 6E C4 00 14 20\n
Run Code Online (Sandbox Code Playgroud)\n\n
    \n
  • C4 在 Windows-1252 中为 \\xc3\x84\',即 U+00C4,因此它存储为C4
  • \n
  • 97 在 Windows-1252 中是“em dash”,即 U+2014,因此它存储为00 14 20
  • \n
\n\n

现在 JDBC-ODBC 桥可以正常检索它(因为 Access ODBC 驱动程序将字符“解开”回C4 97出路),但是如果我们在 Access 中打开数据库,我们会看到

\n\n
Imon\xc3\x84\xe2\x80\x94\n
Run Code Online (Sandbox Code Playgroud)\n\n

utf8Encoded.png

\n\n

JDBC-ODBC 桥从来没有永远无法为 Access 数据库提供完整的本机 Unicode 支持。向 JDBC 连接添加各种属性并不能解决问题。

\n\n

要在没有 ODBC 的情况下获得 Access 数据库的完整 Unicode 字符支持,请考虑改用UCanAccess(更多详细信息请参阅此处的另一个问题。)

\n