1

我在使用DbUtils从SQL Server中的存储过程中检索结果时遇到问题。Apache DbUtils:处理从存储过程返回的多个结果集

在SQL Server Management Studio中执行时,存储过程在为特定输入值执行时返回两个单独的结果集,但对于其他值,它只返回一个结果集。以下图片说明问题:

一个结果集返回: Results with 1 Table Data

两个结果集返回: Result with 2 Table Data

我这里面临的问题是我使用的是DbUtils BeanListHandler转换的结果到UserInfo豆的列表中。

List<UserInfo> userList = (List<UserInfo>) run.query(STORED_PROC, new BeanListHandler(UserInfo.class), refId); 

当存储过程只返回一个结果集时,它工作正常。 但是,在返回两个结果集的情况下,它只给出第一个结果集的列表。

我认为通过使用JDBC我们可以得到使用多个ResultSet,但我不知道如何处理这个DbUtils。

有人可以提供一个见解吗?如果需要其他信息,请更新我提供的信息。

+0

任何人可以帮助。我不清楚我的查询吗? –

+0

你可以发布存储过程的内容吗? – Dave

+0

@Dave我无法访问Stored Proc中的查询。我只能执行它才能获得结果。 –

回答

1

对于QueryRunner对象进行子类化,然后调整适当的query方法来处理多个结果集就足够简单。用下面的代码,我能够用

ResultSetHandler<List<UserInfo>> h = new BeanListHandler<UserInfo>(UserInfo.class); 
MyQueryRunner run = new MyQueryRunner(ds); 
String sql = 
     "EXEC dbo.Gain_Web_GetCompanyRepByIndRefID @RefID=?"; 
List<UserInfo> result = run.query(sql, h, 2); 

检索UserInfo对象的完整列表,MyQueryRunner

package com.example.so36623732; 

import java.sql.Connection; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.util.List; 

import javax.sql.DataSource; 

import org.apache.commons.dbutils.QueryRunner; 
import org.apache.commons.dbutils.ResultSetHandler; 

public class MyQueryRunner extends QueryRunner { 

    public MyQueryRunner(DataSource ds) { 
     super(ds); 
    } 

    /** 
    * Executes the given SELECT or EXEC SQL query and returns a result object. 
    * The <code>Connection</code> is retrieved from the 
    * <code>DataSource</code> set in the constructor. 
    * @param <T> The type of object that the handler returns 
    * @param sql The SQL statement to execute. 
    * @param rsh The handler used to create the result object from 
    * the <code>ResultSet</code>. 
    * @param params Initialize the PreparedStatement's IN parameters with 
    * this array. 
    * @return An object generated by the handler. 
    * @throws SQLException if a database access error occurs 
    */ 
    public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException { 
     Connection conn = this.prepareConnection(); 

     return this.<T>query(conn, true, sql, rsh, params); 
    } 

    /** 
    * Calls query after checking the parameters to ensure nothing is null. 
    * @param conn The connection to use for the query call. 
    * @param closeConn True if the connection should be closed, false otherwise. 
    * @param sql The SQL statement to execute. 
    * @param params An array of query replacement parameters. Each row in 
    * this array is one set of batch replacement values. 
    * @return The results of the query. 
    * @throws SQLException If there are database or parameter errors. 
    */ 
    @SuppressWarnings("unchecked") 
    private <T> T query(Connection conn, boolean closeConn, String sql, ResultSetHandler<T> rsh, Object... params) 
      throws SQLException { 
     if (conn == null) { 
      throw new SQLException("Null connection"); 
     } 

     if (sql == null) { 
      if (closeConn) { 
       close(conn); 
      } 
      throw new SQLException("Null SQL statement"); 
     } 

     if (rsh == null) { 
      if (closeConn) { 
       close(conn); 
      } 
      throw new SQLException("Null ResultSetHandler"); 
     } 

     PreparedStatement stmt = null; 
     ResultSet rs = null; 
     T result = null; 
     List<T> allResults = null; 

     try { 
      stmt = this.prepareStatement(conn, sql); 
      this.fillStatement(stmt, params); 
      rs = this.wrap(stmt.executeQuery()); 
      allResults = (List<T>)rsh.handle(rs); 
      while (stmt.getMoreResults()) { 
       rs = stmt.getResultSet(); 
       result = rsh.handle(rs); 
       allResults.addAll((List<T>)result); 
      } 

     } catch (SQLException e) { 
      this.rethrow(e, sql, params); 

     } finally { 
      try { 
       close(rs); 
      } finally { 
       close(stmt); 
       if (closeConn) { 
        close(conn); 
       } 
      } 
     } 

     return (T) allResults; 
    } 

} 
+0

真棒改变它到快速代码。谢谢 :) –

1

说实话,如果该存储过程在一次执行中返回2个结果集,则会产生更大的问题。理想情况下,您希望将2个结果作为SP的单个表结果返回,然后您应该可以。

1)尝试联系有权访问SP的人员并引起您的注意。让他们创建一个临时表来存储返回的2个结果中的所有记录,然后仅返回该临时表中的所有内容。

2)如果你没有这样的选择,你可以试试这个文章retrieve-data-from-stored-procedure-which-has-multiple-result-sets中概述的方法得到的结果,如果你无法从任何1移动)

HTH

戴夫

+0

谢谢你的答案。我尝试使用本机Jdbc,并与多个结果集一起工作,但代码冗长。有没有什么办法或Api类似于Dbutils,我们可以用Beans/Pojo –

相关问题