2010-01-28 32 views
15

Tôi đang sử dụng các lớp JdbcTemplate và StoredProcedure của Spring. Tôi gặp sự cố khi nhận lớp thủ tục được lưu trữ để làm việc cho tôi.Thủ tục lưu trữ của Spring - kết quả quay lại từ quy trình luôn trống

Tôi có một quy trình được lưu trữ trên cơ sở dữ liệu oracle. chữ ký của nó là

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

nơi

TYPE cursor_type IS REF CURSOR; 

Tôi đã tạo ra lớp thủ tục lưu trữ sau đây để có được thông tin từ các thủ tục 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; 
    } 
} 

tôi kêu gọi này trong một phương pháp trong một trong những các lớp DAO của tôi

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

Tuy nhiên, kích thước của bản đồ luôn là 0, vì vậy không có gì trở lại. Tôi biết rằng có những hàng trên cơ sở dữ liệu phù hợp với tiêu chí đầu vào của tôi. Ngoài ra tôi đã có mã làm việc mà sử dụng java.sql.CallableStatement để tương tác với các oracle lưu trữ proc - vì vậy proc là tốt. Có sai khi trộn OraceleTypes.CURSOR với Quy trình lưu trữ của Spring không? Tôi có thể sử dụng những gì khác? Tôi cũng đã thử SqlReturnResultSet và điều đó cũng không hoạt động.

Trả lời

7

Vấn đề ở đây là cách thực hiện các thủ tục lưu sẵn của Oracle không tuân thủ JDBC. SPs của Oracle trả về dữ liệu resultset thông qua các tham số OUT hoặc trả về các giá trị là các con trỏ, và chúng phải được xử lý đặc biệt. Điều này có nghĩa là bạn không thể sử dụng bất kỳ công cụ JDBC nào của Spring mà giả định tuân thủ JDBC, bạn phải tự làm điều đó. Trong thực tế, điều này có nghĩa là bạn phải sử dụng JdbcTemplateCallableStatementCallback, có nghĩa là mã hóa JDBC thủ công hơn rất nhiều so với ý tưởng của bạn, nhưng tôi vẫn chưa tìm cách tránh điều này. Một chút sang một bên, tôi khá nghi ngờ rằng đặc tả JDBC được viết để phù hợp chặt chẽ với Sybase (và, bằng cách kết hợp, SQL Server) cách làm việc, bởi vì cách các thủ tục được lưu trữ được xử lý trong JDBC là một cách đáng chú ý phù hợp cho những hệ thống này (và phù hợp với người nghèo).

+7

Xin chào, Cảm ơn phản hồi của bạn. Tôi đã làm việc này với thủ tục lưu trữ Oracle của tôi. Vấn đề là với thông số đầu ra mà tôi đã khai báo. Các công trình sau đây declareParameter (new SqlOutParameter ("output", oracle.jdbc.OracleTypes.CURSOR, new RowMapper() {public String mapRow (ResultSet argResults, int argRowNum) ném SQLException {return argResults.getString (1);}})); Điều này đang làm việc cho tôi bây giờ. Cảm ơn – aos

+2

Bạn nên trả lời câu hỏi của riêng mình và chọn câu hỏi đó làm câu trả lời được chấp nhận. Cảm ơn bạn đã đăng bài. –

4

Vấn đề rất đơn giản nếu bạn không vượt qua một RowMapper trong khi khai báo outparam là CURSOR. Mùa xuân sẽ trả về {} I. con trỏ trống.

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

Trường hợp ApplicationMapper là người lập bản đồ tùy chỉnh của tôi triển khai RowMapper.

Các vấn đề liên quan