2012-01-30 57 views
5

我在批量使用jdbc preparedStatement時遇到問題,並嘗試從此創建生成的密鑰。JDBC PreparedStatement,批量更新和生成的密鑰

的代碼:

 PreparedStatement stmt = null; 
    ... 
    connection.setAutoCommit(false); 
    stmt = connection.prepareStatement(insertSuspiciousElement,new String[] {"external_id","element_id"}); 
final int elementBatchSize = 5000; 
    int elementCount =0; 
     for(BlSuspiciousElement element : elements){ 
     externalIds.add(element.getExternalId()); 
     stmt.setInt(1, element.getBlElementType().getElementTypeId()); 
     stmt.setString(2, element.getFirstname()); 
     stmt.addBatch(); 
     elementCount++; 
     if(elementCount % elementBatchSize == 0){ 
      System.out.println("Running query with batch size for suspiciousElement"); 
      stmt.executeBatch(); 

      ResultSet keys = stmt.getGeneratedKeys(); 
      while(keys.next()){ 
       externalIdElementIdMapping.put(keys.getInt("external_id"),keys.getInt("element_id")); 
      } 
      keys.close(); 
      stmt.clearBatch(); 
      stmt.clearParameters(); 
      stmt.clearWarnings(); 
      System.out.println("Done query with batch size for suspiciousElement"); 
     } 
     } 

它未能在第一stmt.executeBatch()方法。

錯誤:

[30/01/12 15:54:41:684 CET] 00000029 RemoteExcepti E CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "processFullFeedForPepAndRelationUpdateOnly" on bean "BeanId(CoRelateEar#AmlKycToolBO.jar#FactivaDBUpdater, null)". Exception data: java.lang.ArrayIndexOutOfBoundsException 
at oracle.jdbc.driver.T4CNumberAccessor.unmarshalOneRow(T4CNumberAccessor.java:201) 
at oracle.jdbc.driver.T4C8Oall.readRXD(T4C8Oall.java:696) 
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:340) 
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192) 
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531) 
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207) 
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1044) 
at oracle.jdbc.driver.OraclePreparedStatement.executeForRowsWithTimeout(OraclePreparedStatement.java:10143) 
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10249) 
at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:230) 
at com.ibm.ws.rsadapter.jdbc.WSJdbcStatement.executeBatch(WSJdbcStatement.java:748) 

我都不明顯...

看來,它不適合批量更新工作?僅用於陳述或準備陳述。在這種情況下,我想我應該盡我批量插入,然後運行另一個查詢查找每個創建的元素生成的密鑰...

感謝您的幫助,

˚F

回答

0

我相信你應該告訴Oracle JDBC驅動程序你會檢索生成的密鑰。

查看以下問題的接受答案以獲取詳細信息:PreparedStatement with Statement.RETURN_GENERATED_KEYS

編輯1/31/12:如果這種方法不能用於批處理(而且我沒有用批處理方式),你可以代替批處理,只需關閉自動提交,插入所有數據,然後提交。在我的實驗中,這種方法的性能損失僅爲3%。我還在SO上發現了另一個類似的建議:MySQL batch stmt with Statement.RETURN_GENERATED_KEYS

+0

這個鏈接是關於只使用preparedStatement。我的問題是當我試圖檢索批處理執行的preparedStatement中生成的密鑰...稍有不同。 – Farid 2012-01-31 07:48:11

+0

@Farid:你在準備陳述時是否嘗試過指定RETURN_GENERATED_KEYS?就像:stmt = connection.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS); – Olaf 2012-01-31 14:17:38

+0

是的,同樣的錯誤。 – Farid 2012-01-31 15:52:46