Question

I am using Firebird. I have came to know that in Firebird we can't move the result set cursor back. It's only supported TYPE_FORWARD_ONLY while TYPE_SCROLL_INSENSITIVE is not supported yet. In my application I want to move the result set cursor one row back like using this resultSet.previous(). I want to know if there is any way I can move the cursor back.

Look this documentation of Firebird:

JDBC 3.0 specification defines three types of result sets

  • TYPE_FORWARD_ONLY: the result set is not scrollable, cursor can move only forward. When the TRANSACTION_READ_COMMITTED isolation level is used, the result set will return all rows that are satisfying the search condition at the moment of the ResultSet.next() call. In other cases result set will return only rows that were visible at the moment of the transaction start.
  • TYPE_SCROLL_INSENSITIVE: the result set is scrollable, the cursor can move back and forth, can be positioned on the specified row. Only rows satisfying the condition at the time of query execution are visible.
  • TYPE_SCROLL_SENSITIVE: is not supported by Firebird and Jaybird. Driver allows application to ask for this type of result set, however according to the JDBC specification, the type is “downgraded” to the previous type and corresponding warning is added to the connection object.

Due to a missing support of scrollable cursors in Firebird, their support (TYPE_SCROLL_INSENSITIVE result set type) is implemented by fetching the complete result set to the client. Scrolling happens in the memory on the client. This can have adverse effect on the system memory usage and performance when the result set is large.

This is just one piece of code I think it would be helpful:

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 + ">\n\n";
}

From the chat, the code used to create the Statement is:

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

Solution

When you create a Statement (or PreparedStatement), you need to specify the result set type, if you don't the driver will use the default (TYPE_FORWARD_ONLY).

So to get a scrollable ResultSet, you need to use

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

See the javadoc of Connection.prepareStatement(sql, resultSetType, resultSetConcurrency).

Also be aware that your current code is leaking resources. You are creating a PreparedStatement in a method and never closing it. You might want to restructure your code so you can close both the statement and the result set in the same place. Closing the statement in its current place won't work, as that would also close the ResultSet before you can use it.

Disclosure: I am a developer of the Jaybird JDBC driver.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top