2016-07-28 54 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: 

我已經使用Google搜索並找到了使用下面的解決方案。

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 

我GOOGLE了,但大多找到了原始的類型,如整數,字符串等解決方案,但沒有列出,我找到了解決辦法(的setNull)沒有工作。

我正在使用MyBatis(註釋)來調用存儲過程。有什麼辦法來處理這個發送null作爲輸入或可能是存儲過程的空白列表。

+0

你最後一次嘗試不是一個空數組,它是一個具有單個元素的數組,它是null。你沒有顯示oracleArray是如何定義/填充的,當它是空的。你的'setNull'缺少數組類型。 [這可能會有所幫助](http://stackoverflow.com/a/29356270/266304)。 –

+0

@AlexPoole:正如我想了很多選擇,所以只是嘗試發送一個數組與空元素以及以檢查是否工作,但它沒有:(我已更新我的問題處理程序的代碼段。請看看是否謝謝 – 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; 

這允許在類型處理器陣列傳遞null如下

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

這使傳遞null存儲過程如果該列表是在Java代碼空。

希望這節省了一些人的時間。