segunda-feira, 25 de março de 2013

SQL Server 2000 - Paginação com Filtros e Ordenação

Bom, em se tratando de listagem de dados, algumas vezes encontramos a necessidade de fazer uma query que nos retorne muitos registros, neste momento é hora de pensar em dados paginados, onde é apresentado alguns registros a cada página, mas em muitos casos é necessário deixar disponível a ordenação a cargo do usuário, ao clicar no cabeçalho executa ordenação pela mesma.
Segue abaixo uma solução para criar uma Stored Procedure, que a consulta retorne apenas o que queremos evitando muitos registros ocultos ou depender de componentes externos, além de poder aplicar filtros e ordenação.

-----------------------------------------------------------------------
--Populando uma tabela para o exemplo
-----------------------------------------------------------------------
DECLARE @TABELA TABLE(
                      ID        INT
                     ,DESCRICAO VARCHAR(100)
                     ,NUMERO    INT
                     )
INSERT INTO @TABELA
                          SELECT  1, 'UM'    ,12
                    UNION SELECT  2, 'DOIS'  ,15
                    UNION SELECT  3, 'TRÊS'  ,26
                    UNION SELECT  4, 'QUATRO',20
                    UNION SELECT  5, 'CINCO' ,23
                    UNION SELECT  6, 'SEIS'  ,32
                    UNION SELECT  7, 'SETE'  ,14
                    UNION SELECT  8, 'OITO'  ,27
                    UNION SELECT  9, 'NOVE'  ,11
                    UNION SELECT 10, 'DEZ'   ,21

-----------------------------------------------------------------------
--Parâmetros da StoredProcedure
-----------------------------------------------------------------------
--Filtros
DECLARE @Filtro_ID        INT          --ID EXATO
DECLARE @Filtro_DESCRICAO VARCHAR(100) --PARTE DA DESCRICAO
DECLARE @Filtro_NUMERO    INT          --NUMERO EXATO

--Ordenação
DECLARE @Ordenacao      INT          --ATRAVEZ DO INDICE INFORMADO

--Paginação
DECLARE @NrPagina       INT          --INFORMA O NUMERO DA PÁGINA 
DECLARE @PorPagina      INT          --INFORMA REGISTROS POR PÁGINA
DECLARE @TemProxima     CHAR(1)      --RETORNA 'S' COM PROXIMA PÁGINA 
                                     --     OU 'N' SEM PROXIMA PÁGINA
-----------------------------------------------------------------------
--Valores para exemplificar este seriam os dados de entrada da Procedure
SET @Filtro_ID        = NULL
SET @Filtro_DESCRICAO = NULL
SET @Filtro_NUMERO    = NULL
SET @NrPagina         = 1
SET @PorPagina        = 3
SET @Ordenacao        = NULL
-----------------------------------------------------------------------

DECLARE @IndexInicial INT 
SET @IndexInicial = (@NrPagina * @PorPagina ) - @PorPagina 

--CRIANDO ESTRUTURA IGUAL TABELA MAS COM COLUNA ROWID ORDENADO E FILTRADO
DECLARE @TABELA_PRONTA TABLE(
                               ROWID     INT IDENTITY(1,1)
                              , ID        INT
                              , DESCRICAO VARCHAR(100)
                              , NUMERO INT
                              )

--INSERINDO DADOS PRONTOS PARA SEREM APRESENTADOS
INSERT INTO @TABELA_PRONTA (ID, DESCRICAO, NUMERO)
   SELECT E.ID ,E.DESCRICAO ,E.NUMERO      
     FROM @TABELA E
    WHERE ( E.ID = @ID OR @ID IS NULL )
      AND ( UPPER(E.DESCRICAO) LIKE '%'+UPPER(@DESCRICAO)+'%' 
            OR @DESCRICAO IS NULL )
      AND (E.NUMERO = @NUMERO OR @NUMERO IS NULL)
 ORDER BY CASE --ORDENACOES INTEIRAS
             WHEN @Ordenacao = 1 THEN E.ID
             WHEN @Ordenacao = 3 THEN E.NUMERO
          END,
          CASE --ORDENACOES VARCHAR
             WHEN @Ordenacao = 2 THEN E.DESCRICAO
          END


--PAGINAÇÃO
SET ROWCOUNT @PorPagina

SELECT E.ROWID
      ,E.ID
      ,E.DESCRICAO
      ,E.NUMERO
  FROM @TABELA_PRONTA E
 WHERE ROWID > @IndexInicial

SET ROWCOUNT 0

--Informando se existe próxima página
SELECT @TemProxima = CASE 
                        WHEN COUNT(ID) > (@NrPagina * @PorPagina ) THEN 
                           'S'
                        ELSE 
                           'N'
                     END
  FROM @TABELA

-----------------------------------------------------------------------
Até o próximo post.

Um comentário: