【问题标题】:JAVA Writing to Access database and retrieving and indexJAVA写入Access数据库并检索和索引
【发布时间】:2012-11-11 06:13:08
【问题描述】:

我正在将数据从 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 接口来提供我的应用程序所需的基本功能就更没有吸引力了。

【问题讨论】:

  • 您应该能够针对连接实例选择@@identity。

标签: java ms-access resultset


【解决方案1】:

不确定这是否适用于 MS Access,但您可以尝试:

st.executeUpdate("INSERT INTO SpeedTable (RunCount) VALUES (1000)", Statement.RETURN_GENERATED_KEYS);
ResultSet rs = st.getGeneratedKeys();
rs.next();
long id = rs.getLong(1);

【讨论】:

  • 谢谢。它不适用于 MS Access。进一步阅读表明没有解决方案。我会变通,可能通过读取索引一次然后保留一个内部计数器,除非索引非常关键的情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-24
  • 1970-01-01
相关资源
最近更新 更多