Apache DbUtils:处理从存储过程返回的多个结果集

     2023-02-16     110

关键词:

【中文标题】Apache DbUtils:处理从存储过程返回的多个结果集【英文标题】:Apache DbUtils : Handling multiple result sets returned from Stored Procedure 【发布时间】:2016-08-06 01:04:01 【问题描述】:

我在使用 DbUtils 从 SQL Server 中的存储过程中检索结果时遇到问题。

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

返回一个结果集:

返回两个结果集:

我在这里面临的问题是我正在使用 DbUtils BeanListHandler 将结果转换为 UserInfo bean 的列表。

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

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

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

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

【问题讨论】:

谁能帮忙。我不清楚我的查询吗? 能把存储过程的内容贴出来吗? @Dave 我无法访问存储过程中的查询。我只能执行它以获得结果。 您是否考虑过将org.apache.commons.dbutils.QueryRunner 子类化并用使用PreparedStatement#getMoreResults() 的代码覆盖适当的.query 方法? @GordThompson 感谢您的指点 (y) 将调查它 【参考方案1】:

说实话,如果该存储过程在一次执行中返回 2 个结果集,那么问题就更大了。理想情况下,您希望从 SP 将 2 个结果作为单个表结果返回,然后您应该没问题。

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

2) 如果您没有该选项,您可以尝试本文retrieve-data-from-stored-procedure-which-has-multiple-result-sets 中概述的过程以获取结果,如果您无法从 1) 中获得任何移动

HTH

戴夫

【讨论】:

感谢您的回答。我尝试使用本机 Jdbc 并使用多个结果集,但该代码很长。有什么方法或类似于 Dbutils 的 Api 我们可以将其更改为使用 Beans/Pojo 的快速代码【参考方案2】:

继承QueryRunner 对象然后调整适当的query 方法来处理多个结果集就足够简单了。使用以下代码,我能够使用

检索UserInfo对象的完整列表
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);

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;
    


【讨论】:

太棒了。谢谢:)

queryrunner类的八种结果处理集

...on;importjava.util.List;importjava.util.Map; importorg.apache.commons.dbutils.DbUtils;importorg.apache.commons.dbutils.QueryRunner;importorg.apache.commons.dbutils.handlers.ArrayHandler;importorg.apache.commons.dbutils.handlers.ArrayListHandler;importorg.apache.commons.dbutils.handlers.BeanHand... 查看详情

oracle存储过程中临时表的使用,该怎么处理

1、Oracle临时表分两种,事务级临时表和会话级临时表2、事务级临时表在事务结束后会被清空,会话级临时表在事务结束后不会清空而是在回话结束会自动清空。3、如果是在存储过程用临时表并不需要从临时表里把数据返回到存... 查看详情

从递归存储过程返回多行

】从递归存储过程返回多行【英文标题】:Returnmultiplerowsfromarecursivestoredprocedure【发布时间】:2015-03-0507:20:50【问题描述】:我想返回多行作为存储过程的结果。我正在递归调用这个存储过程,以读取所有嵌套值。这是我目前的... 查看详情

Teradata 存储过程 - 如何从错误处理程序中获取错误消息文本

】Teradata存储过程-如何从错误处理程序中获取错误消息文本【英文标题】:TeradataStoredProcedure-Howtogeterrormessagetextfromerrorhandler【发布时间】:2014-08-0718:45:09【问题描述】:除了SQLCODE和SQLSTATE之外,有没有办法返回实际的错误消息... 查看详情

如何从 MySQL 中的存储过程返回字符串值?

】如何从MySQL中的存储过程返回字符串值?【英文标题】:HowtoreturnaStringvaluefromaStoredProcedureinMySQL?【发布时间】:2021-08-1521:05:56【问题描述】:我想从存储过程中返回一个值,我可以在JPA存储库中的SpringBoot服务器中使用它。这是... 查看详情

调用另一个存储过程后从存储过程返回错误结果

】调用另一个存储过程后从存储过程返回错误结果【英文标题】:Gettingthewrongresultbackfromthestoredprocedureaftercallinganotherstoredprocedure【发布时间】:2011-11-0802:44:02【问题描述】:我们有一个用来创建用户的存储过程。在该存储过程中... 查看详情

Dapper 从存储过程返回打印消息

】Dapper从存储过程返回打印消息【英文标题】:Dapperreturnprintmessagefromstoredprocedure【发布时间】:2020-05-0110:04:23【问题描述】:我有一个无法修改的存储过程,我正在尝试获取PRINT消息,如果发生错误,该消息将返回。我的存储过... 查看详情

dbutils结果集处理器介绍

  common-dbutils.jar是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能。1、QueryRunner类①update方法:intupdate(Stringsql,Object...params)-->可执行增删改语句intupda... 查看详情

数据库基础_jdbc[5]_dbutil以及一个简单的数据库存储过程

DButil1.什么是DButilcommons-dbutils是Apache组织提供的一个开源JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能2.DButil常用的方法以及功能DbUtils:提供如关闭... 查看详情

使用 Apache 常用 DBCP 和 DBUtils 的连接池和并发

】使用Apache常用DBCP和DBUtils的连接池和并发【英文标题】:ConnectionPoolingusingApachecommonDBCPAndDBUtilsandconcurrency【发布时间】:2013-06-0914:25:42【问题描述】:我正在研究在不同线程中执行多个查询时的并发性。我使用ApacheDBCP和DBUtils不... 查看详情

Spring的存储过程-从过程返回的结果总是空的

】Spring的存储过程-从过程返回的结果总是空的【英文标题】:Spring\'sStoredProcedure-resultscomingbackfromprocedurealwaysempty【发布时间】:2011-01-1009:29:36【问题描述】:我正在使用Spring的JdbcTemplate和StoredProcedure类。我无法让存储过程类为... 查看详情

从存储过程调用返回变量作为变量的输出值

】从存储过程调用返回变量作为变量的输出值【英文标题】:Returnvariablefromstoredprocedurecallasoutputvalueforvariable【发布时间】:2019-02-0620:14:37【问题描述】:我目前正在运行一个存储过程,它运行成功,但在调用一个单独的过程之... 查看详情

如何从返回多个表的存储过程中选择特定表?

】如何从返回多个表的存储过程中选择特定表?【英文标题】:howtoselectaparticulartablefromastoredprocedurewhichreturnsmultipletable?【发布时间】:2009-10-2105:57:16【问题描述】:我有一个包含多个select语句的存储过程。在sqlserver中执行时,... 查看详情

如何使用 Apache DbUtils 调用 SQL 标量函数

】如何使用ApacheDbUtils调用SQL标量函数【英文标题】:HowtocallaSQLScalarfunctionusingApacheDbUtils【发布时间】:2013-12-1016:22:53【问题描述】:我正在尝试通过ApacheCommonDbUtils调用SQLServer存储的标量函数。我尝试过这样的事情:run.query("... 查看详情

从存储过程返回错误消息

】从存储过程返回错误消息【英文标题】:Returnerrormessagefromstoredprocedure【发布时间】:2016-01-2112:38:23【问题描述】:问题应该很简单,但我不知道答案,也不知道为什么我的存储过程不工作。CREATEPROCEDUREspTest_Delete@IDintASbegintrande... 查看详情

apache的dbutils框架学习

commons-dbutils简介commons-dbutils是Apache组织提供的一个开源JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。因此dbutils成为很多不喜欢hibernate的公司的首... 查看详情

如何从 T-SQL 存储过程返回表

】如何从T-SQL存储过程返回表【英文标题】:HowtoreturntablefromT-SQLStoredProcedure【发布时间】:2009-09-3013:16:12【问题描述】:这里是SQL新手,我正在寻找一个简单的代码示例来回答我认为是一个简单的问题。我需要编写一个按顺序执... 查看详情

从 C# 中的存储过程返回多个记录集

】从C#中的存储过程返回多个记录集【英文标题】:ReturnmultiplerecordsetsfromstoredprocinC#【发布时间】:2013-09-0121:13:23【问题描述】:我必须将ASP经典系统转换为C#我有一个存储过程,最多可以返回7个记录集(取决于传入的参数)。... 查看详情