2010-01-28 14 views
15

Sto utilizzando le classi Spring JdbcTemplate e StoredProcedure. Sto avendo problemi a far funzionare la classe della stored procedure per me.Stored procedure Spring - i risultati di ritorno dalla procedura sono sempre vuoti

Ho una stored procedure su un database Oracle. La sua firma è

CREATE OR REPLACE PROCEDURE PRC_GET_USERS_BY_SECTION 
(user_cursor OUT Pkg_Types.cursor_type 
, section_option_in IN Varchar2 
, section_in IN Varchar2) AS .... 

dove

TYPE cursor_type IS REF CURSOR; 

ho creare la seguente classe di stored procedure per ottenere informazioni dalla procedura dell'oracolo

private class MyStoredProcedure extends StoredProcedure 
{ 
    public MyStoredProcedure(JdbcTemplate argJdbcTemplate) 
    { 
     super(argJdbcTemplate, "PRC_GET_USERS_BY_SECTION"); 
     declareParameter(new SqlOutParameter("output", OracleTypes.CURSOR)); 
     declareParameter(new SqlParameter("input1", Types.VARCHAR)); 
     declareParameter(new SqlParameter("input2", Types.VARCHAR)); 
     compile();   
    } 


    public Map<String, Object> execute() { 

     Map<String, Object> inParams = new HashMap<String, Object>(); 
     inParams.put("input1", "BG"); 
     inParams.put("input2", "FE"); 
     Map output = execute(inParams); 
     return output; 
    } 
} 

sto chiamando questo in un metodo in una delle le mie classi DAO

public List<String> getUserListFromProcedure() throws BatchManagerException 
{ 
    MyStoredProcedure sp = new MyStoredProcedure(this.jdbcTemplate); 
    Map<String, Object> result = new HashMap<String, Object>(); 
    try 
    { 
     result = sp.execute(); 
    } 

    catch(DataAccessException dae) 
    { 

    } 
    System.out.println(result.size()); 
    return null; 
} 

Tuttavia, la dimensione della mappa è sempre 0, quindi non viene restituito nulla. So che ci sono delle righe sul database che corrispondono ai miei criteri di input. Inoltre ho avuto il codice di lavoro che utilizzava java.sql.CallableStatement per interagire con il proc memorizzato oracle - quindi proc è buono. È sbagliato mischiare OraceleTypes.CURSOR con la stored procedure di Spring? Cos'altro posso usare? Ho anche provato lo SqlReturnResultSet e anche questo non ha funzionato.

risposta

7

Il problema qui è che il modo in cui Oracle esegue le stored procedure non è conforme a JDBC. Gli SP di Oracle restituiscono i dati dei risultati tramite i parametri OUT o restituiscono valori che sono cursori e devono essere gestiti appositamente. Ciò significa che non è possibile utilizzare alcuna delle cose JDBC di Spring che presuppone la conformità con JDBC, devi farlo tu stesso.

In pratica, questo significa che devi usare JdbcTemplate e CallableStatementCallback, il che significa molto più codice JDBC manuale di quello che ti piacerebbe, ma devo ancora trovare un modo per evitarlo.

In un leggero accenno, ho il sospetto che la specifica JDBC sia stata scritta per conformarsi strettamente al modo Sybase (e, per associazione, SQL Server) di fare le cose, perché il modo in cui le stored procedure sono gestite in JDBC è notevolmente adatto per quei sistemi (e inadatto per Oracle).

+7

Ciao, grazie per il tuo feedback. Ho ottenuto questo lavoro con la mia procedura memorizzata Oracle. Il problema era con il parametro di output che avevo dichiarato. I seguenti lavori declareParameter (nuovo SqlOutParameter ("output", oracle.jdbc.OracleTypes.CURSOR, nuovo RowMapper() {public String mapRow (ResultSet argResults, int argRowNum) genera SQLException {return argResults.getString (1);}})); Questo sta funzionando per me ora. Grazie – aos

+2

Dovresti aver risposto alla tua domanda e averla selezionata come risposta accettata. Grazie per la pubblicazione comunque. –

4

Il problema è semplice se non si passa un RowMapper mentre si dichiara l'outparam che è un CURSORE. La primavera tornerà {} I.e cursore vuoto.

declareParameter(new SqlOutParameter("output", OracleTypes.CURSOR)); - returns empty {} 
declareParameter(new SqlOutParameter("output", OracleTypes.CURSOR, new ApplicationMapper()); - returns result 

Dove ApplicationMapper è il mio mappatore personalizzato che implementa RowMapper.

Problemi correlati