2010-07-06 16 views
5

Estoy trabajando en una aplicación para hacer un procesamiento por lotes, y quiero almacenar los datos de entrada y salida como archivos en campos BLOB en una base de datos Oracle. La versión de Oracle es 10g r2.¿Cómo coloco BLOB grandes (o al menos no triviales) en Oracle con JDBC?

Usando el método PreparedStatement.setBinaryStream() como a continuación, insertaré un pequeño archivo de texto en la base de datos, pero no estoy teniendo suerte con un archivo de imagen más grande.

¿Estoy haciendo algo mal? ¿Es esto posible con JDBC? ¿Tendré que molestar al DBA? Gracias por tu ayuda.

EDITAR: Se ha resuelto el problema. He actualizado el código para una muestra de trabajo:

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

Respuesta

3

No creo que se pueda actualizar o insertar en un BLOB/CLOB con JDBC en un solo paso (para datos> 4K). De this example from Oracle, parece que necesita para:

  1. insertar un LOB vacío con la función de SQL empty_clob()
  2. Seleccionar para una actualización del LOB ha insertado
  3. obtener el LOB en Java con ResultSet.getBlob() a continuación, obtener la salida transmitir con blob.setBinaryStream (ya oracle.sql.BLOB.getBinaryOutputStream() es obsoleto)
  4. escritura a este flujo de salida
  5. cerrar el flujo de salida cuando haya terminado

Haría algo similar en Pl/SQL (SELECCIONE PARA ACTUALIZAR un LOB, luego escriba en él).

+0

Vincent, gracias por su respuesta bien pensada que enlaza a la documentación oficial de Oracle. Desafortunadamente, una vez que traté de seguir su ejemplo comencé a recibir errores de ORA-01002 tan pronto como emití la consulta PARA ACTUALIZAR. – Phil

+0

@Phil: el ORA-01002 no parece estar relacionado con BLOB. ¿Desactivó la confirmación automática primero? (necesitaría una transacción para que esto funcione => desactivar la confirmación automática) –

+0

¡Gracias, eso funcionó! – Phil

1

Solo recuerda, getBinaryOutputStream ha quedado obsoleto. Debería estar usando setBinaryStream si está usando oracle.sql.BLOB en su lugar.

Cuestiones relacionadas