Переместить курсор ResultSet обратно в Firebird


Я использую Firebird. Я узнал, что в Firebird мы не можем переместить курсор результирующего набора обратно. Он поддерживается только TYPE_FORWARD_ONLY, в то время как TYPE_SCROLL_INSENSITIVE еще не поддерживается. В моем приложении я хочу переместить курсор результирующего набора на одну строку назад, как с помощью этого resultSet.previous(). Я хочу знать, могу ли я каким-либо образом переместить курсор назад.

Смотрите эту документацию Firebird:

Спецификация JDBC 3.0 определяет три типа результирующих наборов
  • TYPE_FORWARD_ONLY : результирующий набор не прокручивается, курсор может перемещаться только вперед. Если используется уровень изоляции TRANSACTION_READ_COMMITTED, то результирующий набор вернет все строки, которые удовлетворяют условию поиска в точке момент набора результатов.следующий звонок. В других случаях результирующий набор будет возвращен только строки, которые были видны в момент начала транзакции.
  • TYPE_SCROLL_INSENSITIVE : результирующий набор прокручивается, курсор может двигаться назад и вперед, можно расположить на указанную строку. Только строки, удовлетворяющие условия на момент выполнения запроса видны.
  • TYPE_SCROLL_SENSITIVE : не поддерживается Firebird и Jaybird. Водитель позволяет приложению запрашивать этот тип результирующего набора, однако в соответствии с Спецификация JDBC, тип "понижен" до предыдущего типа и соответствующее предупреждение добавляется к объекту подключения.

Из-за отсутствующая поддержка прокручиваемых курсоров в Firebird, их поддержка (TYPE_SCROLL_INSENSITIVE result set type) реализуется путем выборки полного результирующего набора клиенту. Прокрутка происходит в памяти клиента. Это может отрицательно сказаться на использовании системной памяти и производительности при большом наборе результатов.

Это всего лишь один фрагмент кода, который, я думаю, будет полезен:

while (res.next()) {
    if (!id.equalsIgnoreCase(res.getString("NO_TRANSFERT"))) {
        res.previous();
        break;
    }
    xml = xml + "<" + tableName + ">n";
    for (int i = 1; i <= count; i++) {
        String columnName = rsmd.getColumnName(i);
        xml = xml + "<" + columnName + ">" + res.getString(i) + "</"
            + columnName + ">n";
    }
    xml = xml + "</" + tableName + ">nn";
}

Из чата, код, используемый для создания Statement:

public static ResultSet selectAll(String table) throws SQLException {
    String query = "SELECT * FROM " + table;
    PreparedStatement ps = connection.prepareStatement(query);
    ResultSet res = ps.executeQuery();
    return res;
}
1 2

1 ответ:

При создании Statement (или PreparedStatement) необходимо указать тип результирующего набора, в противном случае драйвер будет использовать значение по умолчанию (TYPE_FORWARD_ONLY).

Итак, чтобы получить прокручиваемый ResultSet, вам нужно использовать

PreparedStatement ps = connection.prepareStatement(query, 
            ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

См. javadoc из Connection.prepareStatement(sql, resultSetType, resultSetConcurrency).

Также имейте в виду, что ваш текущий код утечка ресурсов. Вы создаете PreparedStatement в методе и никогда не закрываете его. Возможно, потребуется реструктурировать код, чтобы закрыть оператор и результирующий набор в одном месте. Закрытие оператора в его текущем месте не будет работать, так как это также закроет ResultSet, прежде чем вы сможете его использовать.

Раскрытие: я являюсь разработчиком драйвера JDBC Сойка.