打开连接上的 UCanAccess 异常 - 引用的列上不存在唯一约束
Posted
技术标签:
【中文标题】打开连接上的 UCanAccess 异常 - 引用的列上不存在唯一约束【英文标题】:UCanAccess exception on open connection - UNIQUE constraint does not exist on referenced columns 【发布时间】:2020-01-29 12:59:43 【问题描述】:我正在尝试使用 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 "T22EB41B92-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 "T22EB41B92-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();
在创建连接以读取某些表时,有什么方法可以关闭此约束检查?
【问题讨论】:
根据堆栈跟踪,您似乎连接成功。但是,由于ALTER TABLE
查询而引发错误。您是否正在执行包含ALTER TABLE
查询的语句?
制作备份副本,然后在 Access 中打开数据库并对其执行“压缩和修复数据库”操作。看看有没有帮助。
@BankBuilder 我不执行任何语句。 try catch 块是我试图执行的唯一事情。这意味着,我只想打开连接。
@Gord 感谢您的建议。不幸的是,它没有帮助。
我需要一些东西来重现这个问题,请继续在 sourceforge 上打开的线程
【参考方案1】:
我无法发布用于重现问题的数据库!因为它是一个非常复杂的数据库,有很多表和关系,它不属于我。由于一般数据保护条例,我不允许分享它(即使没有数据)。
此外,我不想更改数据库中的任何内容,因此我想关闭约束检查以便能够仅连接到数据库并读取某些表的行。
最后我复制了数据库并删除了表之间的所有关系,然后代码可以连接到数据库, 但: 连接需要 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");
Database、DatabaseBuilder、Row 和 Table 来自“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
【讨论】:
以上是关于打开连接上的 UCanAccess 异常 - 引用的列上不存在唯一约束的主要内容,如果未能解决你的问题,请参考以下文章
如何将 UCanAccess 连接到使用数据库密码加密的 Access 数据库?
使用 iso-8859-1 在 wildfly 中打开 ucanaccess/jackcess 数据库
mysql和eclipse已经连接上但是没有创建表回出现异常吗?