2011-03-29 68 views
0

我想通過PL/SQL,Spring和JDBC檢索Blob值。從PL/SQL通過Spring讀取Blob

這裏是我的PL/SQL

function GETBLOB(pjobid in number) 
RETURN bobrecCur 
is 
vbobrecCur bobrecCur; 
begin 
    OPEN vbobrecCur FOR 
    SELECT jobid, filecontent 
    FROM TESTBULKJOBDATAFILE 
    WHERE jobid = pjobid; 
    RETURN vbobrecCur; 
end GETBLOB 

我的Java代碼是

this.getDataJdbcCall = 
      new SimpleJdbcCall(this.jdbcTemplate) 
        .withFunctionName( SQL_READ_DATA) 
        .withoutProcedureColumnMetaDataAccess() 
        .declareParameters(
          new SqlOutParameter("abc", OracleTypes.CURSOR), 
          new SqlParameter("pjobid", OracleTypes.INTEGER) 
        ); 

Map input = new HashMap(); 
    input.put("pjobid", 99999); 

    ResultSet result = this.getDataJdbcCall.executeFunction(ResultSet.class , input); 
    DefaultLobHandler lob = new DefaultLobHandler(); 
    InputStream is = lob.getBlobAsBinaryStream(result, 1); 

我收到以下異常..基本上說ResultSet是空。

在org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:91) 在org.springframework.jdbc.core.JdbcTemplate.processResultSet(在JdbcTemplate的線程 「主」 顯示java.lang.NullPointerException 異常的.java:1120) 在org.springframework.jdbc.core.JdbcTemplate.extractOutputParameters(JdbcTemplate.java:1089) 在org.springframework.jdbc.core.JdbcTemplate $ 5.doInCallableStatement(JdbcTemplate.java:996) 的組織。 springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:935) at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:984) at org.springframework.jdbc.core.simple.AbstractJdbcCa在org.springframework.jdbc.core.simple.SimpleJdbcCall.executeFunction(SimpleJdbcCall。org.springframework.jdbc.core.simple.AbstractJdbcCall.doExecute(AbstractJdbcCall.java:349) 處使用ll.executeCallInternal(AbstractJdbcCall.java:364) 。 java:137)

我經歷了this問題應該爲我工作。但我認爲我使用OracleLobHandler的方式不對。

任何人都可以告訴我哪裏出錯了嗎?

回答

0

沒關係,我想出瞭如何用BLOB返回類型而不是Cursor來完成它。

CREATE OR REPLACE function GETDATA(pjobid in number) 
RETURN BLOB 
is 
begin 
    SELECT filecontent into pblob 
    from TESTDATA 
    where jobid = pjobid; 
    return pblob; 
end; 

而且在Java中我做了這個

this.getDataJdbcCall = 
      new SimpleJdbcCall(this.jdbcTemplate) 
        .withFunctionName(SQL_READ_DATA) 
        .withoutProcedureColumnMetaDataAccess() 
        .declareParameters(new SqlOutParameter("abc", OracleTypes.BLOB), 
          new SqlParameter("pjobid", OracleTypes.INTEGER)); 



    System.out.println("Reading data"); 

    Map input = new HashMap(); 
    input.put("pjobid", 99999); 

    Blob result = this.getDataJdbcCall.executeFunction(Blob.class, input); 

    InputStream is = result.getBinaryStream(); 

    byte[] b = new byte[1000]; 
    while (true) { 
     if (is.read(b) == -1) 
      break; 

     System.out.print(new String(b)); 
    } 
0
package test; 

import java.util.List; 
import java.util.Map; 

import org.springframework.jdbc.core.JdbcTemplate; 
import org.springframework.jdbc.datasource.DriverManagerDataSource; 

public class SelectBlobBug { 
    public static void main(String[] args) { 
     JdbcTemplate jdbcTemplate = new JdbcTemplate(new DriverManagerDataSource("jdbc:derby:test-db;create=true")); 

     jdbcTemplate.execute("DROP TABLE blob_test"); 
     jdbcTemplate.execute("CREATE TABLE blob_test (DATA BLOB NOT NULL)"); 
     byte[] binaryData = new byte[32700]; 
     for (int i = 0; i < binaryData.length; i++) { 
      binaryData[i] = (byte) i; 
     } 
     jdbcTemplate.update("INSERT INTO blob_test VALUES (?)", binaryData); 

     List<Map<String, Object>> result = jdbcTemplate.queryForList("SELECT * FROM blob_test"); 

     System.out.println(((byte[]) result.get(0).get("DATA")).length); // should be 32700 
    } 
} 
+0

這個解決方案可能適用於有限的(在這種情況下,32KB)或小大小的數據。但是,如果大小不可預知或大,你應該去流(我以前的答案) – javadeveloper 2013-09-23 01:14:34