2011-01-18 17 views
9

Possiedo un'applicazione che elabora un file molto grande e invia i dati a un database Oracle (utilizzando Java 6, Oracle 9).BatchUpdateException: il batch non termina

In un ciclo, utilizzo un PreparedStatement ps e creo tutte le istruzioni SQL generate con ps.addBatch().

Ho una situazione in cui un BatchUpdateException bue viene generato da qualche parte durante il ps.executeBatch(). A quel punto, il batch si ferma per essere eseguito.

Mi piacerebbe che l'esecuzione del batch continuasse, così posso quindi verificare gli aggiornamenti non riusciti in un metodo processUpdateCounts(bue.getUpdateCounts()).

Javadoc sulla classe BatchUpdateException dice:

Dopo un comando in un aggiornamento batch non riesce a eseguire correttamente e BatchUpdateException è gettato, il conducente può o non può continuare a processo il comandi rimanenti nel lotto .

C'è un modo per forzare la continuazione o devo modificare il mio programma in modo che esegua l'istruzione individualmente?

risposta

5

appena trovato questo link: JDBC Batch Update Problem

A quanto pare, si dice che non c'è

NO WAY CON ORACLE LOTTO JDBC procedere dopo il primo fallimento,

quindi sto ricorrendo all'invio degli inserti uno per uno. Grazie

(mi dispiace per non guardare meglio per trovare il link sopra prima).

0

Poiché la specifica non sembra autorizzarla (come chiaramente dimostrato dal Javadoc), qualsiasi continuazione "forzata" dovrebbe essere eseguita in base al conducente. Una semplice soluzione alternativa conforme allo standard consisterebbe nel controllare l'array restituito getUpdateCounts() e "rieseguire" il batch per quelle istruzioni che non sono riuscite. Puoi rendere questo approccio un po 'più sofisticato inserendo una logica per il numero di tentativi.

Certo, questo sembra un po 'disordinato (tenendo traccia del "batch" aggiunto e quindi controllando l'output) ma funzionerebbe su tutti i database e le implementazioni dei driver. Solo un pensiero ...

3

esiste una soluzione che consente di utilizzare la funzione di batch. Invece di eseguire una semplice dichiarazione INSERT, è possibile eseguire un blocco PL/SQL che si occuperà con l'errore in modo appropriato:

BEGIN 
    INSERT INTO your_table VALUES (?,?,...?); 
EXCEPTION 
    WHEN OTHERS THEN 
     /* deal with the error. For example, log the error id and error msg 
     so that you can list them after the batch */ 
     INSERT INTO error_table VALUES (?, sqlerrm); 
END 

Le prestazioni dovrebbero essere alla pari con l'inserto batch (dovrebbe essere più veloce di esecuzione individuale del dichiarazioni). È anche possibile chiamare una stored procedure anziché un blocco PL/SQL.

1

Oracle stessa può, vedere qui: http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14250/oci04sql.htm#sthref616

Tuttavia, non sembra che questa funzionalità è esposta a JDBC, neppure nelle classi specifiche di Oracle.

A causa della gestione degli errori JDBC piuttosto inutile ("il driver può o non può continuare"), sto sempre impostando un punto di salvataggio prima del batch ed eseguendo un rollback a quel punto in caso di errore. Questo è l'unico modo conforme a JDBC per stabilire uno stato noto dopo un errore di Oracle Batch, per quanto ne so.

Problemi correlati