Читать Blob из PL / SQL через Spring - PullRequest
0 голосов
/ 30 марта 2011

Я пытаюсь получить значение Blob через PL / SQL, Spring и JDBC.

Вот мой 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 равен нулю.

Исключение в потоке "main" java.lang.NullPointerException в org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData (RowMapperResultSetExtractor.java:91) в org.springframework.jdbc.core.JdbcTemplate.processResultSet (JdbcTemplate.java:1120) в org.springframework.jdbc.core.JdbcTemplate.extractOutputParameters (JdbcTemplate.java:1089) в org.springframework.jdbc.core.JdbcTemplate $ 5.doInCallableStatement (JdbcTemplate.java:996) в org.springframework.jdbc.core.JdbcTemplate.execute (JdbcTemplate.java:935) в org.springframework.jdbc.core.JdbcTemplate.call (JdbcTemplate.java:984) в org.springframework.jdbc.core.simple.AbstractJdbcCall.executeCallInternal (AbstractJdbcCall.java:364) в org.springframework.jdbc.core.simple.AbstractJdbcCall.doExecute (AbstractJdbcCall.java:349) в org.springframework.jdbc.core.simple.SimpleJdbcCall.executeFunction (SimpleJdbcCall.java:137)

Я прошел этот вопрос, который должен работать для меня. Но я думаю, что способ использования OracleLobHandler неправильный.

Кто-нибудь может пролить свет на то, где я иду не так?

Ответы [ 2 ]

0 голосов
/ 19 сентября 2013
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 голосов
/ 30 марта 2011

Не берите в голову, я понял, как сделать это с типом возврата BLOB, а не с курсором.

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