2012-01-30 12 views
5

Yığın halinde jdbc preparedStatement kullanarak ve bundan oluşturulan oluşturulan anahtarları almaya çalışırken bir sorunum var.JDBC PreparedStatement, Toplu Güncelleştirme ve oluşturulan Anahtarlar

kodu:

 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"); 
     } 
     } 

ilk stmt.executeBatch() yöntemine başarısız olur.

hatası:

[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) 

Benim için çok açık ...

O Toplu güncellemeler için çalışmıyor gibi görünüyor? Sadece açıklama veya hazır beyan için. Bu durumda, ben ... ben daha iyi benim toplu insert yapmaya çalışacağım ve ardından her yaratılan elemanı için üretilen anahtarları bulmak için başka bir sorgu kaçardım Yardımlarınız için

Teşekkür,

F

düşünüyorum

cevap

0

Oracle JDBC sürücüsüne oluşturulmuş anahtarları alacağınızı söylemelisiniz.

Ayrıntılar için aşağıdaki soruya verilen cevabı inceleyin: PreparedStatement with Statement.RETURN_GENERATED_KEYS.

DÜZENLEME 1/31/12: Bu yaklaşım toplu iş ile çalışmazsa (ve toplu iş ile denemedim), toplu iş yerine yalnızca otomatik yanıtlamayı kapatabilir, tüm verileriniz için ekler ekleyebilir, ve sonra işlemek. Denemelerimde bu yaklaşımın performans cezası sadece% 3'tü. SO: MySQL batch stmt with Statement.RETURN_GENERATED_KEYS'da da benzer bir öneri buldum.

+0

Bu bağlantı sadece bir adet hazırlık kullanılarak yapılmıştır. Sorun, toplu olarak yürütülen bir hazırlıkStatement içinde oluşturulan anahtarları almayı denediğimde ... Biraz farklı. – Farid

+0

@Farid: Deyimi hazırlarken RETURN_GENERATED_KEYS değerini belirtmeyi denediniz mi? Gibi bir şey: stmt = connection.prepareStatement (sql, Statement.RETURN_GENERATED_KEYS); – Olaf

+0

Evet, aynı hata. – Farid