2012-11-22 50 views
2

我正在寫數據從Java到Access數據庫在Windows 32位。當我寫一條記錄時,我需要檢索行ID /主鍵,這樣我可以a)更容易地更新記錄,如果我想和b)交叉引用其他數據到該記錄。JAVA寫入訪問數據庫和檢索和索引

當在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(); 
    } 

我已經能夠做的唯一一件事情就是寫一個新的記錄,然後運行一個不同的查詢來獲得行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接口,它提供了我需要的基本功能,這對我的應用程序來說更具吸引力。

+0

您應該能夠選擇@@對連接實例的身份。 – Fionnuala

回答

0

不知道,如果這個工程的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); 
+0

謝謝。它不適用於MS Access。進一步閱讀表明沒有解決方案。我可以通過閱讀索引一次,然後保留一個內部計數器來解決問題,除非索引非常重要。 –