2010-01-28 109 views
15

我正在使用Spring的JdbcTemplate和StoredProcedure類。我無法讓存儲過程類爲我工作。Spring的存儲過程 - 從過程返回的結果始終爲空

我在oracle數據庫上有一個存儲過程。它的簽名是

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 .... 

其中

TYPE cursor_type IS REF CURSOR; 

我已創建以下存儲過程類從Oracle過程

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; 
    } 
} 

我的方法之一調用此獲取信息我的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; 
} 

但是,地圖的大小始終爲0,因此無法返回。我知道數據庫上有符合我輸入條件的行。我還有代碼工作,它使用java.sql.CallableStatement與oracle存儲過程交互 - 所以過程很好。將OraceleTypes.CURSOR與Spring的存儲過程混合是不對的?我還能使用什麼?我也試過SqlReturnResultSet,那也沒用。

回答

7

這裏存在的問題是Oracle執行存儲過程的方式與JDBC不兼容。 Oracle的SP通過OUT參數或返回值作爲遊標返回結果集數據,並且必須專門處理它們。這意味着你不能使用任何假定遵從JDBC的JDBC的東西,你必須自己去做。

實際上,這意味着您必須使用JdbcTemplateCallableStatementCallback,這意味着比您理想的更多的手動JDBC編碼,但是我還沒有找到避免這種情況的方法。我略微懷疑JDBC規範的編寫方式與Sybase(以及通過關聯SQL Server)的方式密切相關,因爲存儲過程在JDBC中處理的方式非常明顯非常適合這些系統(對甲骨文來說也不太合適)。

+7

嗨,感謝您的反饋。我使用了我的Oracle存儲過程。問題出在我聲明的輸出參數上。以下工作 declareParameter(new SqlOutParameter(「output」,oracle.jdbc.OracleTypes.CURSOR,new RowMapper(){public String mapRow(ResultSet argResults,int argRowNum)throws SQLException {return argResults.getString(1);}}) );這現在正在爲我工​​作。謝謝 – aos 2010-01-28 14:14:03

+2

您應該已經回答了您自己的問題,並將其選爲接受的答案。無論如何感謝張貼。 – 2012-09-25 17:22:07

4

這個問題很簡單,如果你在傳遞一個CURSOR的outparam時沒有傳遞RowMapper。 Spring將返回{}即空遊標。

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

ApplicationMapper是我的自定義映射器,它實現了RowMapper。