Imitando la cláusula ROWS de InterBase

Home  RSS

2001
2002
2003
2004
2005
2006
2007
Letras
Libros
Pensar
Cosas

La cláusula ROWS

InterBase ahora tiene, a partir de su versión 6.5, una nueva cláusula, ROWS, que permite al cliente seleccionar desde qué fila a qué fila va a traer sus resultados.

FireBird también a implementado algo por el estilo, con su cláusula FIRST...SKIP... Este es un momento triste para los usuarios de estas bases de datos: es la primer diferencia importante en el core de la base de datos.

Pues bien, para usuarios que quieran tener algo portable, o que quieran que funcione con versiones anteriores, acá tienen un método para hacerlo.

La alternativa

La idea consiste en realizar un procedimiento almacenado, que devuelva únicamente al cliente los registros comprendidos entre dos registros determinados.

El siguiente ejemplo muestra cómo realizar esto para la tabla COUNTRY de la base de datos de ejemplo de empleados que se distribuye con InterBase y FireBird.

CREATE PROCEDURE LIST_COUNTRIES (
  FIRST_ROW INTEGER,
  LAST_ROW INTEGER
) RETURNS (
  COUNTRY_NAME VARCHAR(128)
) AS
  DECLARE VARIABLE CURRENT_ROW INTEGER;
BEGIN
  CURRENT_ROW = 0;
  FOR
    SELECT COUNTRY
    FROM COUNTRY
    ORDER BY COUNTRY
    INTO :COUNTRY_NAME
  DO BEGIN
    CURRENT_ROW = CURRENT_ROW + 1;
    IF ((CURRENT_ROW >= FIRST_ROW) AND (CURRENT_ROW <= LAST_ROW)) THEN
      SUSPEND;
  END
END

Básicamente, el código lleva la cuenta de dónde está en la consulta, y va devolviendo los registros apropiados. Nótese que FIRST_ROW y LAST_ROW son one-based, es decir, el primer registro se considera con índice 1.

Ahora, para realizar la consulta del segundo al octavo país de la tabla resultado (segundas y octavas filas inclusive), podemos realizar la siguiente consulta.

SELECT *
FROM LIST_COUNTRIES(2, 8)

Con este esquema, podemos realizar paginación de resultados de forma sencilla, definiendo un tamaño de página, y calculando

FIRST_ROW = número de página (zero-based) * registros por página
LAST_ROW = FIRST_ROW + registros por página

¿Qué ganamos? ¿Qué perdimos?

Perdimos la inocencia con este terrible suceso de fork... pero me voy por las ramas.

Con este método ganamos en portabilidad, porque funcione en varias versiones de los servidores. Por otro lado, perdemos en portabilidad con otras bases de datos, porque el SELECT de un procedimiento almacenado es algo muy poco estandarizado. Aunque, bien pensado, no existe un forma realmente portable de ofrecer esta funcionalidad de forma estándar.

Lo que seguramente hemos perdido es la flexibilidad a la hora de armar consultas. Como los procedimientos almacenados se compilan una única vez, las "columnas" formadas por los parámetros de salida están fijos. Aunque, nuevamente cambiando el punto de vista, esto nos ofrece una interfaz más rígida, lo que es deseable cuando se desea tener mayor control sobre cómo se van a usar los datos.