miércoles, noviembre 15, 2006

SQL --Paginación de registros desde Stored Procedures

A veces es necesario por determinadas circunstancias que los registros que devuelve un stored procedure al recordset llegue con paginación incorporada y esta paginación no tengamos que hacerla en el cliente, asp, vb, etc.
El método que propongo no es único ni más bueno o más malo, es un método más que se puede utilizar. La idea es crear una tabla temporal donde grabaremos los datos de la consulta que queremos paginar y a través de un índice de página ir devolviendo los registros de n en n.

Pero lo mejor para una buena explicación es trabajar con un ejemplo.
En el ejemplo extraemos un listado de la base de datos Northwind de productos ordenados por categorías, extraemos los campos ID del producto, nombre del producto y nombre de la categoría. El Stored Procedure recibe dos parámetros:

- Index, el número de página que queremos mostrar
- NumRegs, el número máximo de registros a mostrar por página.

Create Procedure Paginacion_Registros

--Número de página a mostrar

@index integer
-- Total de resgistros por página

@NumRegs integer
As

-- Declaramos dos variables que serán los índices mayor
-- y menor del filtro de paginación

Declare @Maximo numeric
Declare @Minimo numeric

-- Y asignamos los valores que le corresponden a cada página
-- la asignación de los límites se realiza de la siguiente forma:
-- si index = 1 y NumRegs = 10, entonces los registros a mostrar
-- son del 1 al 10, si index = 2, los registros a mostrar son del 11 al 20
-- y asi sucesivamente.

Select @Maximo = (@index * @NumRegs)
Select @Minimo = @Maximo - (@NumRegs - 1)

-- Creamos la tabla temporal para la paginación,
-- con un campo auto numérico que será el que nos
-- sirva de índice a la hora de extraer los registros.

Create Table #tmpListado (
nOrden INT IDENTITY(1,1),
IDProducto numeric,
NombreProducto varchar(40),
NombreCategoria varchar(15)
)

-- Insertamos en la tabla temporal directamente del select

Insert #tmpListado Select Products.ProductID, Products.ProductName,
Categories.CategoryName
From Products, Categories
Where Products.CategoryID = Categories.CategoryID
order by Categories.CategoryName

-- Una vez tenemos los datos en la tabla temporal los extraemos
-- con un select filtrados por los valores de paginación
-- @Maximo y @Minimo

Select IDProducto, NombreProducto, NombreCategoria
FROM #tmpListado
WHERE (nOrden BETWEEN @Minimo AND @Maximo)

Si pruebas el ejemplo y vas cambiando el valor de index veras como va paginando el Stored Procedure.