如何通过 Java 从 MS Access 2007 数据库中读取 Unicode 字符?
Posted
技术标签:
【中文标题】如何通过 Java 从 MS Access 2007 数据库中读取 Unicode 字符?【英文标题】:How do I read Unicode characters from an MS Access 2007 database through Java? 【发布时间】:2010-05-09 10:02:37 【问题描述】:在 Java 中,我编写了一个读取 UTF8 文本文件的程序。该文本文件包含一个 SELECT 类型的 SQL 查询。然后程序在 Microsoft Access 2007 数据库上执行查询并将第一行的所有字段写入 UTF8 文本文件。
我遇到的问题是当返回包含 unicode 字符的行时,例如“♪”。这些字符显示为“?”在文本文件中。
我知道文本文件的读写是正确的,因为从包含 SQL 查询的文本文件中读取了一个伪 UTF8 字符(“◎”),并将其写入到包含结果行的文本文件中。在记事本中打开写入的文本文件时,UTF8 字符看起来是正确的,因此文本文件的读写不是问题的一部分。
这是我连接数据库和执行 SQL 查询的方式:
Connection c = DriverManager.getConnection("jdbc:odbc:Driver=Microsoft Access Driver (*.mdb, *.accdb);DBQ=C:/database.accdb;Pwd=temp");
ResultSet r = c.createStatement().executeQuery(sql);
我尝试为 Connection 设置一个 charSet 属性,但没有任何区别:
Properties p = new Properties();
p.put("charSet", "utf-8");
p.put("lc_ctype", "utf-8");
p.put("encoding", "utf-8");
Connection c = DriverManager.getConnection("...", p);
尝试使用“utf8”/“UTF8”/“UTF-8”,没有区别。如果我输入“UTF-16”,则会出现以下异常:
java.lang.IllegalArgumentException: 非法替换
已经搜索了几个小时没有结果,现在把希望寄托在你身上。请帮忙!
我也接受解决方法建议。 =) 我想要做的是进行 Unicode 查询(例如,搜索包含“あ”字符的帖子)并正确接收和保存带有 Unicode 字符的结果。
谢谢!
更新。这是该问题的一个独立示例:
package test;
import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.nio.charset.Charset;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.util.Properties;
public class Standalone
public static void main(String[] args)
try
Properties p = new Properties();
p.put("charSet", "UTF8");
Connection c = DriverManager.getConnection("jdbc:odbc:Driver=Microsoft Access Driver (*.mdb, *.accdb);DBQ=./dummy.accdb;Pwd=pass", p);
ResultSet r = c.createStatement().executeQuery("SELECT TOP 1 * FROM main;");
r.next();
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(new File("results.txt")), Charset.forName("UTF-8"));
osw.write(new BufferedReader(new InputStreamReader(new FileInputStream("utf8.txt"), Charset.forName("UTF-8"))).readLine() +" : "+ r.getString("content"));
osw.close();
c.close();
System.out.println("Done.");
catch (Exception e)
e.printStackTrace();
该示例的作用是打开使用密码“pass”加密的数据库“dummy.accdb”,并将第一个帖子从表“main”中拉出。然后它读取文本文件“utf8.txt”并写入一个文本文件“results.txt”,其中将包含“utf8.txt”的第一行加上它从数据库中获得的“content”字段的值。
在“utf8.txt”文件中,我存储了“♜♞♝♛♚♝♞♜♟♖♘♗♕♔♗♘♖♙”。 在数据库的“主”表的“内容”字段中,我存储了“♫♪あキタℳℴℯ♥∞۞♀♂”。
应用程序运行完毕后,“results.txt”有以下内容:“♜♞♝♛♚♝♞♜♟♖♘♗♕♔♗♘♖♙:?????萌?8?? ?”。
成功读写“utf8.txt”文本文件的UTF8字符,但未能从数据库中获取正确的字符。这就是问题所在。
更新。我想我应该提到数据库中的字段属于“备忘录”类型,我尝试将“Unicode 压缩”设置为“否”和“是”(在尝试之间重新创建帖子以确保没有压缩存在选择“否”)。据我了解,Access 在保存 Unicode 字符时使用 UTF-16,但压缩后会更改为 UTF-8。无论如何,这没有任何区别。
额外的问题,有人知道如何在 Java 中使用纯 ODBC 提供程序连接到数据库吗?或者其他什么方法?这将为我提供一个很好的解决方法。
更新。我一直在尝试将这四个提供给 getConnection:
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=./dummy.accdb"
"jdbc:odbc:Provider=Microsoft.Jet.OLEDB.4.0;Data Source=./dummy.accdb"
"jdbc:odbc:Driver=Microsoft.Jet.OLEDB.4.0;Data Source=./dummy.accdb"
"jdbc:odbc:Provider=Microsoft.ACE.OLEDB.12.0;Data Source=./dummy.accdb"
第一个给出错误“java.sql.SQLException: No proper driver found for Provider=Microsoft.Jet.OLEDB.4.0;Data Source=./dummy.accdb”,中间两个得到“java.sql .SQLException:[Microsoft][ODBC Driver Manager] 未找到数据源名称且未指定默认驱动程序”。最后一个得到“java.sql.SQLException: [Microsoft][ODBC Driver Manager] Data source name too long”。
我不明白 getConnection 想要什么。参数说明如下:“url - 一个jdbc:subprotocol:subname形式的数据库url”。嗯?我显然不明白这意味着什么。
任何人都知道通过 Java 连接到 Access 2007 数据库的其他工作方式吗?也许我尝试的提供程序不受支持,但其他一些可能是?
【问题讨论】:
您需要发布一个简约的、独立的示例来演示该问题,因为根据此处的答案:***.com/questions/1467412/…、p.put("charSet", "UTF8")
应该可以工作,因为您使用的是 JDBC ODBC 桥 (java.sun.com/j2se/1.4.2/docs/guide/jdbc/bridge.html)。在文件方面,你说你确定文件是用 UTF8 编写的(你必须故意这样做;Java 的默认值是平台编码,几乎可以肯定不是 UTF8)。
@Crowder:“这几乎肯定不是 UTF8”适用于 Windows。大多数现代 Linux 发行版都使用 UTF-8。我知道这与问题没有直接关系,我只是想避免任何人将其视为在所有情况下都是正确的陈述。
@T.J. Crowder:好的,我已经做了一个独立的例子,只是想弄清楚如何与你们分享。
原始帖子已被编辑以包含示例,请查看并给我您的意见。非常感谢。
@T.J Crowder:顺便说一句,你指的答案是指java.sun.com/j2se/1.4.2/docs/guide/jdbc/bridge.html那篇文章已经过时了,可能是五年前写的(底部的版权声明是2002年) .今天该文章中使用的一些关键类无法使用,例如“sun.jdbc.odbc.JdbcOdbcDriver”、“sun.jdbc.odbc.ee.DataSource”和“sun.jdbc.odbc.ee.ConnectionPoolDataSource”。他们要么有访问限制,要么根本无法解决。设置“charSet”在过去可能有用过一次,但很遗憾今天没有用。
【参考方案1】:
在 Access 中使用 jdbc 的替代方法是 Jackcess 库。使用这个库的优点是没有问题的翻译层(如 odbc)或任何外部系统依赖项。使用这个库的缺点是它不支持执行查询。
【讨论】:
【参考方案2】:由于您提到可以切换到 Access 以外的其他数据库,因此我敦促您这样做。在 Microsoft Office 产品上制作您的软件对我来说一直是维护的噩梦,因此请从此列表中选择其他任何内容:http://java-source.net/open-source/database-engines。
为此,我会使用 Apache Derby,或者只使用随任何当前 Sun Java 安装预装的 Java 数据库 JavaDB(实际上是重新打包的 Derby DB)
【讨论】:
【参考方案3】:现在 JDBC-ODBC 桥已从 Java SE 8 中删除,并且 Oracle 已确认此问题将永远无法修复(参考:here)一个不错的选择是使用UCanAccess。有关详细信息,请参阅
UCanAccess on SourceForge
Manipulating an Access database from Java without ODBC
【讨论】:
【参考方案4】:不支持utf-8:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6345277
【讨论】:
以上是关于如何通过 Java 从 MS Access 2007 数据库中读取 Unicode 字符?的主要内容,如果未能解决你的问题,请参考以下文章
如何通过编码将数据从 MS Access 导入 Sql Server [关闭]
如何通过 MS ACCESS 表执行 SQL Server 表的批量更新
尝试从 MS Access DB 检索字段值时,Java 中的希腊词作为问号 [重复]
如何从 ADO 记录集字段将图片加载到 MS-Access Image 控件中?