简体   繁体   English

java - 在oracle存储过程中传递数组

[英]java - passing array in oracle stored procedure

I have a Java app accessing an oracle stored procedure.我有一个访问 oracle 存储过程的 Java 应用程序。 The arguments to the stored procedure include an array type.存储过程的参数包括数组类型。 I do it like the following...我这样做如下...

con = this._getConnection();  
Connection narrowdConn = (Connection)WSJdbcUtil.getNativeConnection( (WSJdbcConnection)con );  

callable = con.prepareCall("{call MY_PKG.MY_PROCEDURE(?, ?)}");  


ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor("VARCHAR2_ARR", narrowdConn);  
ARRAY arrayArg1 = new ARRAY(arrayDescriptor, con, docNames);  
ARRAY arrayArg2 = new ARRAY(arrayDescriptor, con, docTypes);  

callable.setArray(1, arrayArg1);  
callable.setArray(2, arrayArg2);  

callable.execute();  

Now, I am getting this Exception...现在,我得到了这个异常......

java.sql.SQLException: invalid name pattern: MY_PKG.VARCHAR2_ARR

VARCHAR2_ARR is a public TYPE, defined inside an Oracle Package like the following: VARCHAR2_ARR 是一个公共 TYPE,在 Oracle 包中定义,如下所示:

TYPE VARCHAR2_ARR IS TABLE OF VARCHAR2(50);类型 VARCHAR2_ARR 是 VARCHAR2(50) 的表;

And used as such in my stored proc...并在我的存储过程中使用...

PROCEDURE MY_PROCEDURE  
    (V_ARR_ARG1  IN VARCHAR2_ARR,  
     V_ARR_ARG2  IN VARCHAR2_ARR)  

the type VARCHAR2_ARR is a PLSQL type, you won't be able to interface it directly from java. VARCHAR2_ARR类型是 PLSQL 类型,您将无法直接从 java 接口它。 I suggest you look into this thread on AskTom regarding a similar question.我建议您在 AskTom 上查看有关类似问题的此线程

Here are a couple suggestions:这里有几个建议:

  • create a SQL TYPE that you can bind from java创建一个可以从 java 绑定的 SQL TYPE
  • insert into a temporary table from java and read from it in plsql从java插入临时表并在plsql中读取

In both cases you will have to either modify the PLSQL procedure or add a new translation procedure.在这两种情况下,您都必须修改 PLSQL 过程或添加新的翻译过程。

我们需要在创建数据源时设置 accessToUnderlyingConnectionAllowed falg true

I did stuck at this problem.我确实遇到了这个问题。 Hope this illustration might help you:希望这个插图可以帮助你:

Steps to create the procedure in oracle.在 oracle 中创建过程的步骤。

  • Create type of the desired object as:创建所需对象的类型为:
CREATE OR REPLACE TYPE STUDENT_TYPE IS OBJECT
( ID NUMBER,
  NAME VARCHAR2(50));
  • Create another object of array as:创建另一个数组对象:
CREATE OR REPLACE TYPE STUDENT_ARRAY IS TABLE OF STUDENT_TYPE;
  • Create procedure to accepting array of object and do the desired operation, I am here just inserting the entries in table as:创建过程以接受对象数组并执行所需的操作,我在这里只是将表中的条目插入为:
CREATE OR REPLACE PROCEDURE SP_INSERT_STUDENT_RECORD_IN_BULK(
IN_STUDENT_RECORDS STUDENT_ARRAY) IS
BEGIN 
  FOR i IN IN_STUDENT_RECORDS.first.. IN_STUDENT_RECORDS.last
   LOOP
    BEGIN 
      INSERT INTO STUDENT(ID,NAME) VALUES
      (IN_STUDENT_RECORDS(i).ID, IN_STUDENT_RECORDS(i).NAME)
    END;
   END LOOP:
END SP_INSERT_STUDENT_RECORD_IN_BULK;

Code snippet to call Procedure through Java通过 Java 调用过程的代码片段

import org.springframework.jdbc.core.*;
import oracle.jdbc.OracleConnection;
....
List<Student> students = getStudentList();
try(Connection hikariCon = dataSource.getConnection()){
    if(hikariCon.isWrapperFor(OracleConnection.class)){
        OracleConnection con = hikariCon.unwrap(OracleConnection.class);
        Object[] students = students.stream().map(student -> {
            return con.createStruct(STUDENT_TYPE, new Object[]{
                student.getId(),
                student.getName()
            });
        }).collect(Collectors.list()).flatMap(List::stream).toArray();
        
        SimpleJdbcCall jdbcCall = new SimpleJdbcCall(dataSource)
                                .withProcedureName("SP_INSERT_STUDENT_RECORD_IN_BULK")
                                .declareParameters(
                                new SqlParameter("IN_STUDENT_RECORDS", Types.ARRAY));
        jdbcCall.execute(con.createOracleArray(STUDENT_ARRAY,students))
    }
} catch(Exception e){
    log.error("Error due to- {}",e,getMessage());
}

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

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