我正在将数据从 Java 写入 Windows 32 位上的 Access 数据库。当我写一条记录时,我需要检索行 ID/主键,以便我可以 a) 轻松更新记录,如果我愿意,并且 b) 将其他数据交叉引用到该记录。
当在 C 中做了类似的事情时,我可以制作一个可更新的游标,它允许我编写新记录并同时检索行 ID。使用 Java,看起来我应该能够做到这一点,但它会使用以下代码引发异常。
con = openAccessDatabase();
String selectString = "SELECT ID, RunCount FROM SpeedTable";
try {
PreparedStatement selectStatement = con.prepareStatement(selectString,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet idResult = selectStatement.executeQuery();
int id;
for (int i = 0; i < nWrites; i++) {
idResult.moveToInsertRow();
idResult.updateObject(1, null); // this line makes no difference whatsoever !
idResult.updateInt(2, i);
idResult.insertRow(); // throws java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver]Error in row
id = idResult.getInt(1);
}
selectStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
我唯一能做的就是写一条新记录,然后运行一个不同的查询来取回 Row id ...
String insertString = "INSERT INTO SpeedTable (RunCount) VALUES (?)";
String idString = "SELECT ID FROM SpeedTable ORDER BY ID DESC";
//
try {
ResultSet idResult = null;
PreparedStatement preparedStatement, idStatement;
preparedStatement = con.prepareStatement(insertString,
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
idStatement = con.prepareStatement(idString,
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
for (int i = 0; i < nWrites; i++) {
// write the data into the database
preparedStatement.setInt(1, i);
preparedStatement.execute();
// re-run the query to get the index back from the database.
idResult = idStatement.executeQuery();
idResult.next();
int lastIndex = idResult.getInt(1);
idResult.close();
}
这可行,但当表中有超过 1000 条记录时,它变得非常慢。如果程序的两个部分同时开始编写,也存在返回错误 ID 的风险(不太可能但并非不可能)。
我知道至少有一个建议是不使用 Java 或不使用 Access,但它们不是选项。它也是免费开源软件包的一部分,所以我不愿意为任何东西付费。编写我自己的 C JNI 接口来提供我的应用程序所需的基本功能就更不吸引人了。