简体   繁体   English

将String数组传递给具有string_varray类型的Oracle存储过程

[英]Passing String array into Oracle stored procedure with string_varray type

I have a Store Procedure in Oracle 12c DB with following signature: 我在Oracle 12c DB中具有以下签名的存储过程:

create or replace PROCEDURE myproc(param1 IN NUMBER, param2 IN STRING_ARRAY, param3 IN STRING_ARRAY, outparam OUT BOOLEAN) IS

Here STRING_ARRAY defined in following way: 在这里STRING_ARRAY通过以下方式定义:

create or replace TYPE STRING_ARRAY AS VARRAY(1000) OF VARCHAR2(4000);

In my dao layer I am invoking it in following way: 在我的dao层中,我通过以下方式调用它:

SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(jdbcTemplate).withProcedureName("myschema.myproc");


    SqlTypeValue param2ArrayValue = new AbstractSqlTypeValue() {
        protected Object createTypeValue(Connection conn, int sqlType, String typeName) throws SQLException {
            ARRAY array = ((OracleConnection) conn).createARRAY("myschema.STRING_ARRAY", param2Values);
            return array;
        }
    };


    SqlTypeValue param3ArrayValue = new AbstractSqlTypeValue() {
        protected Object createTypeValue(Connection conn, int sqlType, String typeName) throws SQLException {
            ARRAY array = ((OracleConnection) conn).createARRAY("myschema.STRING_ARRAY", param3Values);
            return array;
        }
    };

    SqlParameterSource inParams = new MapSqlParameterSource().addValue("param1", param1Value)
                                                             .addValue("param2", param2ArrayValue)
                                                             .addValue("param3", param3ArrayValue);

    Map<String, Object> outParams = simpleJdbcCall.execute(inParams);
    logger.info("RetFlag:::::" + outParams.get("outparam"));

I am getting following exception:: 我收到以下异常::

org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback; uncategorized SQLException for SQL [{call myschema.myproc(?, ?, ?, ?)}]; SQL state [99999]; error code [17004]; Invalid column type: 1111; nested exception is java.sql.SQLException: Invalid column type: 1111 
Caused by: java.sql.SQLException: Invalid column type: 1111

I have referred the following link:: Spring Forum link 1 我引用了以下链接:: Spring论坛链接1

Can anyone provide any solution to this?? 谁能为此提供任何解决方案?

I have followed the following steps: 我已按照以下步骤操作:

I had change the data type of my StoredProcedure OUT param from boolean to number: 我已将StoredProcedure OUT参数的数据类型从布尔值更改为数字:

create or replace PROCEDURE myproc(param1 IN NUMBER, param2 IN STRING_ARRAY, param3 IN STRING_ARRAY, return_flag OUT NUMBER) IS

Created a Custom Class by inheriting StoredProcedure class of spring-jdbc module 通过继承spring-jdbc模块的StoredProcedure类创建了一个自定义类

public class MyCustomProcedure extends StoredProcedure{

    public MyCustomProcedure(JdbcTemplate jdbcTemplate, String procedureName) {
      super(jdbcTemplate, procedureName);
      declareParameter(new SqlParameter("param1", Types.NUMERIC));
      declareParameter(new SqlParameter("param2", Types.ARRAY, "STRING_ARRAY"));
      declareParameter(new SqlParameter("param3", Types.ARRAY, "STRING_ARRAY"));
      declareParameter(new SqlOutParameter("return_flag", Types.NUMERIC));
    }

    public boolean execute(Long param1, String[] param2, String[] param3) {
       Boolean resultFlag= null;
       BigDecimal outputReturned  = null;
       Map resultMap = null;
       AbstractSqlTypeValue customArrayTypeParam2 = null;
       AbstractSqlTypeValue customArrayParamType3 = null;

       try (final Connection connectionWrapper = getJdbcTemplate().getDataSource().getConnection()) {
        customArrayTypeParam2 = new MyCustomOracleArrayType(connectionWrapper, param2);
        customArrayTypeParam3 = new MyCustomOracleArrayType(connectionWrapper, param3);
           resultMap = super.execute(param1, customArrayTypeParam2, customArrayTypeParam3);
         }catch(Exception e){
            e.printStackTrace();
         }

        if (MapUtils.isNotEmpty(resultMap)) {
             outputReturned = (BigDecimal) resultMap.get("return_flag");
        if ((Integer.valueOf(outputReturned.intValue())).equals(Integer.valueOf(1))) {
            resultFlag= true;
        }
    } else {
        resultFlag= false;
    }
    return resultFlag;
   }
 }

Please find below my CustomOracleArrayType class 请在我的CustomOracleArrayType类下面找到

public class MyCustomOracleArrayType extends AbstractSqlTypeValue {
    private final Connection oracleCon;
    private final Object[] values;

    public MyCustomOracleArrayType(final Connection oracleCon, final Object[] values) {
        this.oracleCon = oracleCon;
        this.values = values;
    }

    @Override
    protected Object createTypeValue(final Connection con, final int sqlType, final String typeName)
            throws SQLException {
        Array array =  ((OracleConnection)oracleCon).createOracleArray("STRING_ARRAY", values);
        return array;
    }
  }

I have done following modification in Spring Configuration file for injecting MyCustomProcedure class: 我在Spring Configuration文件中做了以下修改,以注入MyCustomProcedure类:

<bean id="myCustomProcedure" class="mypackage.MyCustomProcedure">
   <constructor-arg index="0" type="org.springframework.jdbc.core.JdbcTemplate" ref="jdbcTemplate"/>
   <constructor-arg index="1" type="java.lang.String" value="myproc"/>
</bean>
<bean id="myService" class="mypackage.MyServiceImpl">
  <property name="myCustomProcedure" ref="myCustomProcedure"/>
</bean>
<!--jdbcTemplate already defined in my spring config file along with dataSource -->

That's all,I just invoke execute() method of MyCustomProcedure in traditional way from my service layer. 就是这样,我只是从服务层以传统方式调用MyCustomProcedure的execute()方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM