2010-07-06 26 views
5

我正在处理某个批处理应用程序,并且希望将输入和输出数据作为文件存储在Oracle数据库的BLOB字段中。 Oracle版本是10g r2。如何使用JDBC将大型(或至少非平凡)的BLOB放入Oracle?

使用下面的PreparedStatement.setBinaryStream()方法将插入一个小的文本文件到数据库中,但我没有任何运气与更大的图像文件。

我做错了什么?这可能与JDBC有关吗?我需要打扰DBA吗?谢谢你的帮助。

编辑:问题已解决。我已经更新了这个代码工作示例:

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

回答

3

我不认为你可以更新或插入一个步骤一个BLOB/CLOB与JDBC(用于数据> 4K)。从this example from Oracle,看来你需要:

  1. 插入一个空的LOB与SQL函数empty_clob()
  2. 选择用于更新的LOB您插入
  3. 获得LOB在Java中与ResultSet.getBlob()那么得到的输出与blob.setBinaryStream流(因为oracle.sql.BLOB.getBinaryOutputStream()已废弃)
  4. 写入此输出流
  5. 关闭在完成时输出流

你会在Pl/SQL中做类似的事情(SELECT FOR UPDATE LOB,然后写入它)。

+0

文森特,感谢您经过深思熟虑的答案链接到官方Oracle文档。不幸的是,一旦我试图按照他们的例子,我一发出查询FOR UPDATE就开始出现ORA-01002错误。 – Phil 2010-07-07 14:40:01

+0

@Phil:ORA-01002似乎没有BLOB相关。你先禁用自动提交吗? (你需要一个事务才能工作=>禁用自动提交) – 2010-07-07 14:46:26

+0

谢谢,工作! – Phil 2010-07-07 14:53:27

1

请记住,getBinaryOutputStream已被弃用。如果您使用oracle.sql.BLOB,则应该使用setBinaryStream