2016-07-28 10 views
1

다음과 같이 oracle에 사용자 정의 유형을 생성했습니다.저장 프로 시저에 빈 목록 보내기

create or replace TYPE "ABC_OBJECT" AS OBJECT (
    ticket_no VARCHAR2(50), 
); 

create or replace TYPE "ABC_OBJECT_LIST" IS TABLE OF ABC_OBJECT; 

ABC_OBJECT_LIST 유형은 저장 프로 시저의 입력 필드에 대한 데이터 유형으로 사용됩니다. 내 Java 코드에서 저장 프로 시저를 호출합니다. 목록 형식 입력을 처리하고 저장 프로 시저에 전달하기 위해 사용자 지정 TypeHandler를 작성했습니다. 모든 것은 작동 중이고 저장 프로 시저에 값을 보내고 처리기에서 아래 코드를 사용하여 성공적으로 값을 검색 할 수 있습니다.

@Override 
    public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType arg3) throws SQLException { 
     List<Object> object = (List<Object>)parameter; 
     structDescriptor = getStructureDescriptor(con, PASSENGER_DETAILS_JDBC_OBJECT); 
     arrayDescriptor = getJDBCArrayDescriptor(con, PASSENGER_DETAILS_JDBC_OBJECT_LIST); 

     STRUCT[] structs = new STRUCT[objects.size()]; 
     for (int index = 0; index < objects.size(); index++) { 
     structs[index] = getJDBCDataObject(structDescriptor, con, objects.get(index)); 
     } 

     ARRAY oracleArray = getJDBCArrayObject(arrayDescriptor, con, structs); 
     ps.setArray(i, oracleArray); 
    } 

    private STRUCT getJDBCDataObject(final StructDescriptor structDescriptor, final Connection con, final Object object) { 
    STRUCT struct = null; 
    Object[] params = new Object[1]; 
    params[0] = "This is test text"; 


    struct = getJDBCStructureObject(structDescriptor, con, params); 
    return struct; 
    } 


    private STRUCT getJDBCStructureObject(final StructDescriptor structDescriptor, final Connection con, 
     final Object[] params) { 
    STRUCT struct = null; 
    try { 
     struct = new STRUCT(structDescriptor, con, params); 
    } catch (SQLException e) { 
     LOG.error("Error in creating JDBC structure Object.", e); 
    } 
    return struct; 
    } 

    private ARRAY getJDBCArrayObject(final ArrayDescriptor arrayDescriptor, final Connection con, 
     final STRUCT[] structs) { 
    ARRAY oracleArray = null; 
    try { 
     oracleArray = new ARRAY(arrayDescriptor, con, structs); 
    } catch (SQLException e) { 
     LOG.error("Error in creating JDBC Array Object.", e); 
    } 
    return oracleArray; 
    } 

그러나 목록에 최소한 하나의 개체 만 보내는 경우에만 작동합니다. 내가 빈 목록을 보내려고하면 아래 오류가 발생합니다.

Caused by: org.springframework.jdbc.UncategorizedSQLException: Could not set parameters for mapping: 

나는 아래를 사용하여 해결책을 찾았습니다.

preparedStatement.setNull(i, Types.ARRAY); 

하지만 작동하지 않았습니다. 나는 또한 내 저장 프로 시저에서 DEFAULT NULL 정의를 시도했지만 그 또한 작동하지 않았다. 다음과 같이 시도했다.

preparedStatement.setArray(i, new ARRAY(arrayDescriptor, con, new STRUCT[]{null})); 

잘못된 또는 잘못된 인수 예외가 발생했습니다. 또한 아래에서 시도했다.

preparedStatement.setNull(i,Types.Array, "ABC_OBJECT_LIST"); 

아래와 같은 오류가 발생합니다.

Caused by: org.springframework.jdbc.BadSqlGrammarException: 
### Error querying database. Cause: java.sql.SQLException:ORA-06550: line 1, column 7: 
PLS-00306: wrong number or types of arguments in call to 'PROCESSAUTOTICKETING' 
ORA-06550: line 1, column 7: 
PL/SQL: Statement ignored 

검색 좀하지만 대부분 등 정수, 문자열과 같은 기본 유형을위한 솔루션을 찾았지만 나열되지 않고 내가 찾은 솔루션 (의 setNull)가 작동하지 않았다.

MyBatis (주석)를 사용하여 저장 프로 시저를 호출하고 있습니다. null을 입력으로 보내거나 저장 프로 시저에 빈 목록이 될 수 있습니다.

+0

마지막 시도는 빈 배열이 아니며, 하나의 요소가있는 배열이며 null입니다. 'oracleArray'가 비어있을 때 어떻게 정의되고 채워지는지 보여주지 않았습니다. 그리고'setNull'에 배열 타입이 없습니다. [도움이 될 수 있습니다] (http://stackoverflow.com/a/29356270/266304). –

+0

@AlexPoole : 많은 옵션을 시도 했으므로 null 요소가있는 배열을 보내려고했는데 작동하는지 확인해 보았지만 그렇지 않았습니다. (처리기 코드 단편으로 내 질문이 업데이트되었습니다. 고마워요 – Raghav

+0

당신의 두 번째 것을'preparedStatement.setNull (i, Types.ARRAY, "ABC_OBJECT_LIST");로 시도 했습니까? - 그게 무슨 오류가 있었는지 말하지 않았습니까? –

답변

0

나는 히트 및 평가판 옵션의 긴 목록을 마침내이 문제를 해결했습니다. 해결 방법은 아래와 같이 Oracle Type에 NULL을 정의하는 것이 었습니다.

create or replace TYPE "ABC_OBJECT" AS OBJECT (
    ticket_no VARCHAR2(50) NULL, 
); 

create or replace TYPE "ABC_OBJECT_LIST" IS TABLE OF ABC_OBJECT NULL; 

이것은

preparedStatement.setArray(i, new ARRAY(arrayDescriptor, con, null)); 

이리스트는 자바 코드에 비어있는 경우 프로 시저에 널 전달 가능하게 아래로의 배열 typehandler 널 전달할 수있다.

희망이 있으면 다른 사람의 시간을 절약 할 수 있습니다.