1

DbUtils を使用して SQL Server のストアド プロシージャから結果を取得する際に問題があります。

SQL Server Management Studio で実行するストアド プロシージャは、特定の入力値に対して実行すると 2 つの別個の結果セットを返しますが、他の値に対しては 1 つの結果セットのみを返します。次の図は、この問題を示しています。

1 つの結果セットが返されました。 1 つのテーブル データでの結果

2 つの結果セットが返されました。 2 つのテーブル データの結果

ここで直面している問題は、DbUtilsを使用して結果をBeanBeanListHandlerのリストに変換していることです。UserInfo

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

ストアド プロシージャが結果セットを 1 つだけ返す場合、正常に動作しています。ただし、2 つの結果セットが返される場合は、最初の結果セットのリストのみが表示されます。

JDBC を使用することで複数を使用できると思いますが、ResultSetこの DbUtils の処理方法がわかりません。

誰かが洞察を提供できますか?他の情報が必要な場合は、更新してください。提供します。

4

2 に答える 2

1

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

}
于 2016-05-19T21:12:20.740 に答える
1

正直なところ、そのストアド プロシージャが 1 回の実行で 2 つの結果セットを返す場合、より大きな問題が発生します。理想的には、SP から 2 つの結果を 1 つのテーブル結果として返す必要があり、それで問題ありません。

1) SP にアクセスできる人に連絡して、あなたのケースを彼らの注意を引くようにしてください。返される 2 つの結果からすべてのレコードを格納する一時テーブルを作成し、その一時テーブルのすべてのコンテンツを返すように依頼します。

2) そのオプションがない場合は、この記事で概説されているプロセスを試して、何の動きも得られない場合は結果を取得するために、retrieve-data-from-stored-procedure-which-has-multiple-result-setsを試すことができます。から 1)

HTH

デイブ

于 2016-04-15T14:20:36.703 に答える