我正在尝试使用ucanaccess在我的java maven项目中创建到访问数据库(.accdb)的非常简单的连接。该数据库是一个外部数据库,我只需要阅读一些表的内容即可完成迁移任务。我不想也不应修改表或在数据库中写任何东西。我使用的Java代码非常简单:
try (Connection connection = DriverManager.getConnection(databaseURL);) {
} catch (SQLException ex) { ex.printStackTrace(); }
但是连接一开始就失败,但有以下例外:
net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::5.0.0 a UNIQUE constraint does not exist on referenced columns: T1 in statement [ALTER TABLE T2 ADD CONSTRAINT "T2{2EB41B92-C3AB-4A64-A53C-B83095D76202}" FOREIGN KEY (C2) REFERENCES T1 (C1) ]
at net.ucanaccess.jdbc.UcanaccessDriver.connect(UcanaccessDriver.java:231)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:677)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:251)
at myproject.Application.main(Application.java:42)
Caused by: java.sql.SQLSyntaxErrorException: a UNIQUE constraint does not exist on referenced columns: T1 in statement [ALTER TABLE T2 ADD CONSTRAINT "T2{2EB41B92-C3AB-4A64-A53C-B83095D76202}" FOREIGN KEY (C2) REFERENCES T1 (C1) ]
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.JDBCStatement.executeUpdate(Unknown Source)
at net.ucanaccess.converters.LoadJet.exec(LoadJet.java:1510)
at net.ucanaccess.converters.LoadJet.access$000(LoadJet.java:74)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadForeignKey(LoadJet.java:695)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadTableFKs(LoadJet.java:918)
at net.ucanaccess.converters.LoadJet$TablesLoader.recreate(LoadJet.java:807)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadTableData(LoadJet.java:877)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadTableData(LoadJet.java:871)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadTableData(LoadJet.java:837)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadTablesData(LoadJet.java:1029)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadTables(LoadJet.java:1077)
at net.ucanaccess.converters.LoadJet$TablesLoader.access$3200(LoadJet.java:264)
at net.ucanaccess.converters.LoadJet.loadDB(LoadJet.java:1579)
at net.ucanaccess.jdbc.UcanaccessDriver.connect(UcanaccessDriver.java:218)
... 3 more
Caused by: org.hsqldb.HsqlException: a UNIQUE constraint does not exist on referenced columns: T1
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.TableWorks.checkCreateForeignKey(Unknown Source)
at org.hsqldb.TableWorks.addForeignKey(Unknown Source)
at org.hsqldb.StatementSchema.getResult(Unknown Source)
at org.hsqldb.StatementSchema.execute(Unknown Source)
at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
at org.hsqldb.Session.executeDirectStatement(Unknown Source)
at org.hsqldb.Session.execute(Unknown Source)
... 18 more
我试图将我的连接设为“只读”,因此它不会检查此约束,也不会引发异常。但是我没有成功。
try (Connection connection = DriverManager.getConnection(databaseURL + ";readonly=true");) {
} catch (SQLException ex) { ex.printStackTrace(); }
在创建用于读取某些表的连接时,有什么方法可以关闭此约束检查吗?
最后,我复制了数据库,并删除了表之间的所有关系,然后代码可以连接到数据库,但:它花了30分钟才能连接!!!!因此,即使我每次想运行我的代码时都设法从数据库中创建一个副本并删除所有表之间的所有关系(这在我的任务中实际上是不可能的),但我应该等待30分钟才能完成只需打开一个连接!!!我觉得这很荒谬,当不满足某些约束时,就不可能关闭约束检查并打开用于读取数据的连接!!!>
但是无论如何,最后(经过两天的搜索!),我找到了工作的解决方案。我不使用这种类型的DriverManager的任何连接:
Connection connection = DriverManager.getConnection(databaseURL)
相反,我使用DatabaseBuilder打开数据库并获取表并读取行!对于其他人,他们有同样的问题,只想连接到MS-Access数据库以读取一些数据,而不进行任何更改,我建议采用这种方式。这是非常容易和快速的!
String fileName = "my_database.accdb"; File file = new File(fileName); Database db = null; DatabaseBuilder databaseBuilder = new DatabaseBuilder(file); try { db = databaseBuilder.open(); } catch(IOException e) { e.printStackTrace(); } Table myTable = db.getTable("myAccessTableName"); for(Row row : myTable) { String firstName = row.getString("first_name"); String lastName = row.getString("last_name"); }
数据库,DatabaseBuilder,行和表均来自“ jackcess”。因此需要这些导入:
import com.healthmarketscience.jackcess.Database; import com.healthmarketscience.jackcess.DatabaseBuilder; import com.healthmarketscience.jackcess.Row; import com.healthmarketscience.jackcess.Table;
更多使用这种方式的例子可以在这里找到:Java Code Examples和这里:UCanAccess