2010-07-06 5 views
5

Pracuję nad aplikacją do przetwarzania wsadowego i chcę przechowywać dane wejściowe i wyjściowe jako pliki w polach BLOB w bazie danych Oracle. Wersja Oracle to 10g r2.Jak umieścić duże (lub co najmniej nietrywialne) obiekty BLOB w Oracle za pomocą JDBC?

Użycie metody PreparedStatement.setBinaryStream(), jak poniżej, spowoduje wstawienie małego pliku tekstowego do bazy danych, ale nie mam większego szczęścia z większym obrazem.

Czy robię coś nie tak? Czy można to zrobić z JDBC? Czy będę musiał zawracać głowę DBA? Dzięki za pomoc.

EDYCJA: Problem został rozwiązany. I został uaktualniony kod do próbki roboczej:

import java.io.File; 
import java.io.FileInputStream; 
import java.io.OutputStream; 
import java.sql.Blob; 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.ResultSet; 
import java.sql.Statement; 


public class WriteBlobDriver { 
    public static void main(String[] args) { 
     Connection con = null; 
     try { 
      Class.forName("oracle.jdbc.driver.OracleDriver"); 
      con = DriverManager.getConnection(
        "blahblah", 
        "blahblah", 
        "blahblah"); 
      con.setAutoCommit(false); 
      Statement statement = con.createStatement(); 
      //statement.executeUpdate("UPDATE BATCH_GC_JOBS SET INPUT_BATCH_FILE = EMPTY_BLOB() WHERE JOB_ID = 'a'"); 

      //Get blob and associated output stream 
      ResultSet resultSet = statement.executeQuery("SELECT INPUT_BATCH_FILE FROM BATCH_GC_JOBS WHERE JOB_ID = 'a' FOR UPDATE"); 
      resultSet.next(); 
      Blob blob = resultSet.getBlob(1); 
      OutputStream outputStream = ((oracle.sql.BLOB)blob).getBinaryOutputStream(); 

      // Buffer to hold chunks of data to being written to the Blob. 
      byte[] buffer = new byte[10* 1024]; 
      int nread = 0; 

      //Write file to output stream 
      File file = new File("C:\\TEMP\\Javanese_cat.jpg"); 
      FileInputStream fileInputStream = new FileInputStream(file); 
      while ((nread = fileInputStream.read(buffer)) != -1) { 
       outputStream.write(buffer, 0, nread); 
      } 

      //Cleanup 
      fileInputStream.close(); 
      outputStream.close(); 
      statement.close(); 
      con.commit(); 
      con.close();    
      System.out.println("done!"); 
     } catch (Exception e){ 
      e.printStackTrace(); 
     } 
    } 
} 

Odpowiedz

3

Nie sądzę, można zaktualizować lub wstawić do BLOB/CLOB z JDBC w jednym kroku (dla danych> 4k). Od this example from Oracle, wydaje się, trzeba:

  1. Włóż pusty LOB z funkcji SQL empty_clob()
  2. Wybierz dla aktualizacji lob Po włożeniu
  3. uzyskać LOB w java z ResultSet.getBlob() następnie dostać wyjście strumieniowo z blob.setBinaryStream (od oracle.sql.BLOB.getBinaryOutputStream() jest przestarzała)
  4. zapisu do tego strumienia wyjściowego
  5. zamknąć strumienia wyjściowego po zakończeniu

Zrobiłbyś coś podobnego w Pl/SQL (WYBIERZ DLA AKTUALIZACJI LOB, a następnie napisz do niego).

+0

Vincent, dziękuję za przemyślaną odpowiedź, która łączy się z oficjalną dokumentacją Oracle. Niestety, gdy próbowałem podążać za ich przykładem, zacząłem otrzymywać błędy ORA-01002, gdy tylko wysłałem zapytanie FOR UPDATE. – Phil

+0

@Phil: ORA-01002 nie wydaje się być związany z BLOB. Czy najpierw wyłączyłeś automatyczne zatwierdzanie? (potrzebna byłaby transakcja, aby to działało => wyłącz autocommit) –

+0

Dzięki, to zadziałało! – Phil

1

Po prostu zapamiętaj, getBinaryOutputStream został wycofany. Powinieneś używać setBinaryStream, jeśli zamiast tego używasz oracle.sql.BLOB.

Powiązane problemy