Paginação com SQL Server 2008 R2 no PHP

Paginação com SQL Server 2008 R2 no PHP e PDOFinalizando com a série de artigos sobre paginação com PHP + PDO, hoje vou demonstrar como montar uma paginação com SQL Server 2008 R2. O SQL Server é um banco extremamente poderoso e amplamente utilizado em vários tipos de sistemas incluindo ERPs com grande massa de dados.
 
Por esses motivos é muito comum esses sistemas possuírem tabelas com milhares de registros o que pode trazer problemas de performance para listar esses dados. Infelizmente até a versão 2008 R2 ainda não existia comandos nativos para paginação, então uma maneira encontrada para driblar esse problema foi a utilização da CTE (Common Table Expression).
Observação: A partir do SQL Server 2012 já existem comandos nativos OFFSET e FETCH para paginação de dados nativamente. 
 
Alguns posts sobre SQL Server que podem interessar:
 
Pretendo postar aqui o básico sobre CTE para podermos entender como será montada a paginação, CTEs podem ser utilizadas para diversas finalidades e para obter informações detalhadas sobre essa função aconselho o leitor ler a documentação oficial da Microsoft. Segundo a própria documentação podemos definir CTE como “Um conjunto de resultados nomeado temporário. Ela é derivada de uma consulta e definida no escopo de execução de uma única instrução SELECT, INSERT, UPDATE e DELETE“.

Basicamente podemos executar uma determinada consulta envolvendo ou não várias tabelas e utilizar esses registros para diversas finalidades, inclusive utilizando recursividade de consultas. Dentro desse contexto ainda vamos usar ROW_NUMBER() em conjunto com a clausula OVER().

Definições segundo a documentação oficial:
ROW_NUMBER(): Retorna o número sequencial de uma linha em uma partição de um conjunto de resultados, iniciando em 1 para a primeira linha de cada partição.

OVER(): Determina o particionamento e a ordenação de um conjunto de linhas antes da aplicação da função de janela associada. Isto é, clausula OVER define uma janela ou conjunto de linhas especificado pelo usuário em um conjunto de resultados de consulta. Uma função de janela computa um valor cada linha na janela.

Com essas informações básicas fica mais fácil de entender como será escrita a instrução de paginação, a ideia é escrever um SELECT usando CTE onde serão retornados os dados da tabela artigos e o número da linha usando ROW_NUMBER(). A partir desse CTE poderemos limitar a quantidade de registros e também definir qual o intervalo de registros que vamos exibir.

Exemplo:

Acima temos um exemplo de paginação com SQL Server, onde criamos uma CTE com o aliás “Paginado“, estou executando um SELECT simples e retornando o número da linha além das colunas da tabela, com a clausula OVER() ordenei os registros por id. Com essa CTE armazenada nesse escopo basta executar outra consulta sobre os resultados dela limitando a quantidade de registros retornada com a clausula TOP e na condição WHERE definir qual o intervalo que será retornado usando uma expressão matemática e comparando com a coluna linha, funciona de forma muito similar a uma VIEW.
Agora que já sabemos basicamente como funcionam CTEs, ROW_NUMBER() e OVER(), é hora de por a mão na massa criando o banco de dados, tabela e inserindo os dados fictícios.
 
Abaixo segue o script para criar o banco de dados “blog” e  a tabela artigos “artigos“:

Vamos inserir os 35 registros para teste como fizemos nos artigos anteriores, mas diferente do MySQL e do PostgreSQL não vou usar procedure ou function. No SQL Server podemos usar uma “gambiarra” que funciona bem para esses testes com carga de dados, após a instrução INSERT adicionamos “GO” seguido da quantidade de registros que queremos inserir.
 

Com isso já temos toda a parte de banco de dados finalizada, agora vamos para o principal o script da index.php mas agora com toda a lógica PHP de consulta e paginação, para que esse código funcione é importante mencionar que a extensão pdo_sqlsrv.dll (Windows) ou pdo_dblib.so (Linux) tem que estar habilitada no PHP, script segue abaixo:
 

Criando script de paginação com SQL Server

index.php

Post relacionado:  Formulário de Contato com AJAX + PHP + MySQL

Observação: A folha de estilo CSS foi postado no artigo Paginação de Dados no PHP com PDO – Introdução.

Post relacionado:  Construindo CRUD genérico com PHP e PDO

O script está bem comentado, mas vou explicar os pontos que considero chave para que funcione a paginação da maneira que planejamos. Nesse e nos outros artigos poderemos observar que a sintaxe PDO para consulta será idêntica para todos os SGBDs, isso porque essa biblioteca abstrai todas as particularidades de cada SGBD.

1 – Define 2 constantes no início do script, sendo a primeira QTDE_REGISTROS, para identificar quantos registros quero exibir por página, nesse caso apenas 5. Segunda constante RANGE_PAGINAS, serve para identificar quantas opções de páginas para navegação vou exibir antes e depois da página em destaque, nesse exemplo quero apenas 1 página (2 – 3 – 4).

2 – Nesse trecho fazemos uma validação do parâmetro (page) recebido via GET, verificando se o parâmetro page existe e se o valor é numérico, caso uma das validações não seja verdadeira atribuímos o valor “1” para variável $pagina_atual.

 
3 – Nessa linha temos a mágica, com o auxílio da CTE conseguimos motar nossa paginação com SQL Server através da consulta sendo parametrizada pelos valores recebidos e calculados.

4 – O segredo para saber quantas páginas serão necessárias é saber quantos registros serão retornados, podemos fazer isso executando um COUNT(*) na tabela. Com esse resultado basta dividi-lo pela quantidade de registros que iremos exibir por página, nesse caso pela constante QTDE_REGISTROS. Esse valor também serve para sabermos qual será a última página.

5 – Nesse conjunto de linhas fica toda a mágica da paginação, coloquei os nomes das variáveis bem intuitivos. Observem que para deixar o código mais legível estou usando em alguns pontos operadores TERNÁRIOS, para não poluir o código com vários IFs simples. Observem que para calcular a quantidade de páginas basta dividir o total de registros pela constante QTDE_REGISTROS por página $ultima_pagina = ceil($valor->total_registros / QTDE_REGISTROS).

6 – O código abaixo utiliza classes que criei no CSS para esconder ou exibir os botões de Primeira, Anterior, Próxima e Última página, conforme a necessidade.

Paginação Inicial

Paginação Final
 
Abaixo temos o resultado final quando acessamos a primeira página, notem que não temos opções para o primeiro e nem registro anterior.
 
Paginação de dados início
 
Agora acessando a página “3” temos opções baseadas no range, com 1 página anterior e 1 página posterior, além das opções de primeira, anterior, próxima e última página.
 
Paginação de dados no meio
 
E para finalizar, acessando a última página “7” temos a opção de exibir uma página anterior “6” e os botões anterior e primeira página.
 
Paginação de dados no fim
 
Um detalhe importante, observem que mesmo trabalhando com 3 SGBDs diferentes durante os 3 artigos, sempre utilizamos a mesma sintaxe para consultar os dados. Isso porque estamos utilizando a biblioteca PDO do PHP que dá essa flexibilidade para acessar diferentes SGBDs como a mesma sintaxe.

Bom pessoal, neste artigo demonstrei como construir uma paginação com SQL Server, assim chegamos ao final dessa série de artigos sobre paginação de dados, é evidente que existem diversas maneiras de se montar esse layout de paginação, com variações de CSS, HTML e lógica PHP. Na internet existem diversos plugins para esse tipo de funcionalidade, os principais frameworks para PHP possuem métodos para isso, mas antes de usar soluções prontas é interessante saber como funciona, quais as limitações do SGBD que você está usando em seu projeto para se trabalhar com paginação.

Espero que tenha gostado, até a próxima …

Show Buttons
Hide Buttons