Fallo en FOUND_ROWS() usando el driver JDBC cuando las query es en una única tabla

publicado por Carlos Torres el 28/11/2016 18:41

Pera calcular el número de filas de una query que tiene limit (y offset), usamos SQL_CALC_FOUND_ROWS en la query y después realizamos una llamada a SELECT FOUND_ROWS()

Encontramos un bug (o feature) en FOUND_ROWS() / SQL_CALC_FOUND_ROWS cuando la query se realizan en en una única tabla jdbc.

String query = "SELECT SQL_CALC_FOUND_ROWS * FROM tabla LIMIT 10 OFFSET 100 ";
Connection connection;
PreparedStatement stmt;
...
stmt=connection.prepareStatement(query,ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet rs=stmt.executeQuery();
...
rs = stmt.executeQuery("SELECT FOUND_ROWS() AS cuenta");
if(rs.next()){
  out.print(rs.getInt("cuenta"));
}

Este código devolverá 1 ó 2, (incorrecto)

El driver jdbc no devuelve adecuadamente la cantidad de SQL_CALC_FOUND_ROWS de una query de una tabla simple, como la del ejemplo anterior.

Si que funciona cuando hay mas de una tabla involucrada (concatenación, join, etc.).

Esto ocurre porque el dirver jdbc en el PreparedStatement (o simplement Statement):

Statement st=conex.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

Porque la concurrencia de los cursores está establecida como actualizable concurrentemente.

Para resolverlo, cambiar a: ResultSet.CONCUR_READ_ONLY

Statement st=conex.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery("SELECT FOUND_ROWS()");

Devolverá el valor adecuado.


Añadir un comentario:

Nombre:

E-Mail:

Comentario: :

Enviar >>