带有BLOB参数的Oracle存储过程

时间:2013-11-05 23:24:20

标签: java oracle stored-procedures blob

您好我正在使用这项技术(Oracle SP),因此我遇到了一些问题,

具体来说我想在Store Procedure上插入BLOB对象,目前我使用spring,jboss,java和oracle,我的SP比以下简单:

PROCEDURE SAVE_DATA(data IN BLOB, date IN DATE) IS
next_id number;
BEGIN
  select s_id.nextval into next_id from dual;

  INSERT INTO DATA_TABLE( id, data , date)
  values
  (next_id, data , date);
  COMMIT;

  EXCEPTION
   WHEN OTHERS THEN
     RAISE_APPLICATION_ERROR(-20101,''||SQLCODE ||'-'||SUBSTR(SQLERRM,1,500));
  END SAVE_FAILED_EMAIL;

所以在java方面,我做了类似的事情:

  WrappedConnection wrappedCon = (WrappedConnection) this.getDataSource().getConnection();
        con = (OracleConnection) wrappedCon.getUnderlyingConnection();
        byte[] bytes= IOUtils.toByteArray(input);
        blobObj=con.createBlob(bytes);

  execute(new CallableStatementCreator() {

        public CallableStatement createCallableStatement(Connection con)
                throws SQLException {
             String procedure = "call SAVE_DATA(?,?)";

                CallableStatement stm=con.prepareCall(procedure);

                stm.setBlob(1, blobObj);
                stm.setDate(2, date);
            return stm;
        }
    }, new CallableStatementCallback<Map<Integer,Object>>() {

        public Map<Integer, Object> doInCallableStatement(CallableStatement cs) 
        throws SQLException,DataAccessException {
            cs.execute();
            return null;
        }} 
    );
    con.commit();
    con.close();

但是当我运行这部分代码时,我得到了DB端的下一个异常 “ORA-22927指定了无效的LOB定位器”

1 个答案:

答案 0 :(得分:1)

这个有点棘手。你在这里遇到的第一个问题是Oracle需要一个专有的BLOB和CLOB实例;这是来自Spring OracleLobHandler的javadoc:

  

虽然大多数数据库都能够使用DefaultLobHandler,Oracle   9i(或更具体地说,Oracle 9i JDBC驱动程序)只接受   通过自己专有的BLOB / CLOB API创建的Blob / Clob实例   另外不接受PreparedStatement的大流   相应的setter方法。

但是当您在JBoss工作时,您还需要NativeJdbcExtractor,因此Spring可以从JBoss thread pool wrapper解包底层连接,然后在Spring JdbcTemplate中插入lob。

所以,这是您需要更改的代码:

// ...
final byte[] bytes= IOUtils.toByteArray(input);

final OracleLobHandler lobHandler = new OracleLobHandler();
final lobHandler.setNativeJdbcExtractor(new JBossNativeJdbcExtractor());
// ...
new CallableStatementCreator() {

    public CallableStatement createCallableStatement(Connection con)
            throws SQLException {
         String procedure = "call SAVE_DATA(?,?)";

            CallableStatement stm=con.prepareCall(procedure);

            lobHandler.getLobCreator().setLobAsBytes(smt, 1, bytes, bytes.length);
            stm.setDate(2, date);
        return stm;
    }
}
// ...