Как обработать несколько ResultSet'ов, возвращаемых из одного запроса

Рейтинг: 3Ответов: 2Опубликовано: 28.07.2023

Имеется маленькое андроид-приложение, в котором вызываются MSSQL-запросы.

Приходит ответ в ResultSet, но в нем отображается только первый курсор. Т.е. MSSQL-запрос возвращает 2 таблицы, а Resultset работает только с первой таблицей, насколько я понял.

Каким образом мне получить данные со второй таблицы?

Процедура event_blank_s возвращает 2 столбца:

void lod_data_to_list() {
    try {
        ResultSet rs = Connection_Class.getdata("exec event_blank_s '10' , 1");
        values = new ArrayList();
        valuesid = new ArrayList();

        while (rs.next()) {
            values.add(rs.getString("name"));
            valuesid.add(rs.getInt("id_event"));
        }
        ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, values);
         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        l_view.setAdapter(adapter);
    } catch (Exception ex) {
        Toast.makeText(this, ex.getMessage(), Toast.LENGTH_LONG).show();
    }
}

Метод, который возвращает ResultSet.

public static ResultSet getdata(String text) {
    ResultSet rs = null;
    try {
        //String query = text;
        Statement stmt = con.createStatement();
        rs = stmt.executeQuery(text);
        return rs;
    } catch (Exception ex) {
        Log.e("error here 2 : ", ex.getMessage() + "ResultSet getdata(Cionnection_Class)");
        return rs;
    }
}

Ответы

▲ 1Принят

Во-первых, для обработки множественных результатов следует применять метод Statement::execute(String sql), так как Statement::executeQuery возвращает только один ResultSet.

Во-вторых, для доступа к другим ResultSet'ам существует метод Statement::getMoreResults, который возвращает true, если следующий объект, возвращаемый из Statement, является результирующим набором.

По умолчанию данный метод закрывает текущий ResultSet.

Если нужно иметь несколько открытых результирующих наборов, следует вызывать метод Statement::getMoreResults(int current) с параметром Statement.KEEP_CURRENT_RESULT, а по завершении работы со всеми наборами вызвать этот же метод с параметром Statement.CLOSE_ALL_RESULTS.

Что касается чтения данных из базы, следует изолировать работу с базой в одном методе по принципу "один запрос -- одна сущность (entity)", при этом должен возвращаться экземпляр некоторого объекта, в который будут записаны необходимые данные из одного или нескольких ResultSet'ов.
Также следует закрывать Statement, используя try-with-resources.

Вариант чтения данных (код не тестировался):

public MyEntity readEntity(Connection con, String query) {
    MyEntity result = new MyEntity();

    try (Statement stmt = con.createStatement()) {
        boolean dataAvailable = stmt.execute(query);
        int rsCount = 0; 
        while (dataAvailable) {
            ResultSet rs = stmt.getResultSet();
            if (rsCount == 0) {
                readFirstResultSet(result, rs);
            } else {
                readSecondResultSet(result, rs);
            }
            rsCount++;
            dataAvailable = stmt.getMoreResults();
        }
    }

    return result;
}

private void readFirstResultSet(MyEntity result, ResultSet rs) {
    List<Foo> foos = new ArrayList<>();

    while (rs.next()) {
        foos.add(new Foo(rs.getString("bar"), rs.getInteger("baz")));
    }
    result.setFoos(foos);
}

private void readSecondResultSet(MyEntity result, ResultSet rs) {
    if (rs.next()) {
        result.setMoo(rs.getString("moo"));
        result.setBoo(rs.getObject("boo"));
    }
}

Ссылки:

▲ 0

Спасибо за наводку. Вот что у меня получилось

 public static ResultSet getdata_proc(String proc , int i_table_index)
    {
        ResultSet r_result = null;
        try (Statement stmt = con.createStatement();)
        {
            boolean results = stmt.execute(proc);
            int table_count = 0;
            do
            {
                if (results)
                {
                    r_result = stmt.getResultSet();

                    table_count++;
                    if(i_table_index == table_count)
                    {
                           return r_result;
                    }
                }
                results = stmt.getMoreResults();
            } while (results);
        }
        catch (SQLException e)
        {
            e.printStackTrace();
            return null;
        }
        return r_result;
    }