【问题标题】:Read Blob from PL/SQL through Spring通过 Spring 从 PL/SQL 读取 Blob
【发布时间】:2011-07-25 14:42:27
【问题描述】:

我正在尝试通过 PL/SQL、Spring 和 JDBC 检索 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 );

我得到以下异常.. 基本上说结果集为空。

线程“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)

我经历了this 应该对我有用的问题。但是我觉得我使用OracleLobHandler的方式不对。

谁能解释我哪里出错了?

【问题讨论】:

    标签: java spring jdbc plsql blob


    【解决方案1】:

    没关系,我想出了如何使用 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 ) );
        }
    

    【讨论】:

      【解决方案2】:
      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
          }
      }
      

      【讨论】:

      • 此解决方案可能适用于有限(本例中为 32kb)或小型数据。但是,如果大小不可预测或很大,您应该选择流(我之前的回答)
      猜你喜欢
      • 2017-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-03
      • 2013-10-23
      • 1970-01-01
      • 2020-10-11
      • 2017-01-24
      相关资源
      最近更新 更多