paginação dinâmica
Olá a todos,
Acredito que eu deveria utilizar outro título, entretanto, o problema apresentado aqui, é para a solução do título.
É interessante eu explicar todo o problema, ou os acontecimentos, para não deixar "pontas soltas"
Eu estava desenvolvendo uma solução para o sistema que da minha empresa. O sistema é desenvolvido em PHP e utiliza-se do SGBD MsSQL 2008 R2. Basicamente é um portal, simples. Entretanto, o meu problema é com uma questão de performance.
Eu utilizo a classe LimitIterator da biblioteca SPL do php para a paginação. Nunca tive problemas em questões de performance. Até esse momento.
A base de dados tratada, possui atualmente mais de 2700 registros. A consulta é rápida, não vou negar, quanto a isso, não há problema algum.
Entretanto, como a LimitIterator utiliza-se de todos os objetos para, assim então, definir o range de seleção (página 2 -> objetos de 10 até 20, por exemplo), o processo demora tempo de mais, coisa entre 4-6 segundos. O que para a web atual, é um tempo demasiado extenso.
Como o mssql, diferente de outros SGBDs, não implementa o método skip, eu estava utilizando uma view com a função ROW_NUMBER(), o que me atendia perfeitamente.
Segue o código:
SELECT
noticia.rownumber,
noticia.id,
noticia.titulo,
noticia.resumo,
noticia.descricao,
noticia.datapublicacao
FROM
(
SELECT
ROW_NUMBER() OVER (ORDER BY datapublicacao DESC) AS rownumber,
*
FROM
noticia
) AS noticia'
Eu omiti alguns campos, o que não vai afetar em nada para a solução do problema.
Essa view resolve parcialmente o problema. Entretanto, uma vez criada essa view, não há nenhuma possibilidade de se obter uma ordenação diferente da definida. O padrão, é pela ordem decrescente da data de publicação. Mas, caso eu necessite de alguma ordem diferente da definida, não funcionará, pois o ROW_NUMBER() gera a numeração conforme o parâmetro de ordenação do OVER.
Conversando com alguns desenvolvedores, chegamos ao consenso de criar uma função, passando então a o nome da coluna e o tipo de ordenação (ASC|DESC) por parâmetro. No desenvolvimento da function, descobrimos que, para utilizar os parâmetros como string/varchar, o SQL deve ser executado através da função EXECUTE(). Através de um select normal, não funciona utilizar variáveis para definir a coluna e o parâmetro de ordenação, somente através do execute.
Segue o código funcional:
DECLARE
@column varchar(50),
@order varchar(4)
SET
@column = 'datapublicacao'
SET
@order = 'DESC'
execute (
'SELECT
noticia.rownumber,
noticia.id,
noticia.titulo,
noticia.resumo,
noticia.descricao,
noticia.datapublicacao
FROM
(
SELECT
ROW_NUMBER() OVER (ORDER BY '+ @column + ' ' + @order + ') AS rownumber,
*
FROM
noticia
) AS noticia'
)
O código acima resolve totalmente o meu problema. Entretanto, quando fui criar a function.
CREATE FUNCTION noticiapaginacao(@column varchar(50) , @order varchar(4))
RETURNS @noticiapaginacao TABLE (
rownumber INT,
id INT,
titulo VARCHAR(255),
resumo TEXT,
descricao TEXT,
datapublicacao DATETIME
) AS
BEGIN
execute (
'
INSERT @noticiapaginacao
SELECT
noticia.rownumber,
noticia.id,
noticia.titulo,
noticia.resumo,
noticia.descricao,
noticia.datapublicacao
FROM
(
SELECT
ROW_NUMBER() OVER (ORDER BY '+ @column + ' ' + @order + ') AS rownumber,
*
FROM
noticia
) AS noticia'
)
RETURNEND
Quando tento criar essa função, o seguinte erro é lançado.
Invalid use of a side-effecting operator 'EXECUTE STRING' within a function.
Pela simples tradução, pude perceber que, a função execute, não pode ser utilizada dentro de uma function. Minha intenção com isso é, dentro das possibilidades de ambas as ferramentas (MsSQL/PHP) encontrar uma solução para esse problema. Não me importo em fazer de uma maneira diferente, mas essa foi a mais lógica encontrada, já que o PHP em si, está tendo dificuldades em processar tamanha quantidade de dados.
Discussão (5)
Carregando comentários...