2010-07-06 23 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

相關問題