Como implementar a paginação independente do mecanismo de banco de dados?

StackOverflow https://stackoverflow.com/questions/61750

  •  09-06-2019
  •  | 
  •  

Pergunta

Tarefa:implementar paginação de registros de banco de dados adequados para diferentes RDBMS.O método deve funcionar para mecanismos convencionais - MSSQL2000+, Oracle, MySql, etc.

Por favor, não publique soluções específicas de RDBMS, eu sei como implementar isso para a maioria dos mecanismos de banco de dados modernos.Estou procurando a solução universal.Apenas soluções baseadas em tabelas temporárias vêm à minha mente no momento.

EDITAR:
Estou procurando uma solução SQL, não uma biblioteca de terceiros.

Foi útil?

Solução

Haveria uma solução universal se as especificações SQL incluíssem a paginação como padrão.O requisito para que qualquer linguagem RDBMS seja chamada de linguagem RDBMS também não inclui suporte de paginação.

Muitos produtos de banco de dados oferecem suporte a SQL com extensões proprietárias para a linguagem padrão.Alguns deles suportam paginação como MySQL com a cláusula limit, Rowid com Oracle;cada um tratado de forma diferente.Outros SGBDs precisarão adicionar um campo chamado rowid ou algo parecido.

Eu não acho que você possa ter uma solução universal (qualquer um é livre para provar que estou errado aqui; aberto ao debate), a menos que seja incorporado ao próprio sistema de banco de dados ou a menos que haja uma empresa, digamos ABC, que use Oracle, MySQL, SQL Server e eles decida fazer com que todos os vários sistemas de banco de dados forneçam sua própria implementação de paginação por seus desenvolvedores de banco de dados, fornecendo uma interface universal para o código que o utiliza.

Outras dicas

A maneira mais natural e eficiente de fazer paginação é usando a construção LIMIT/OFFSET (TOP no mundo Sybase).Uma maneira independente do DB teria que saber em qual mecanismo ele está sendo executado e aplicar a construção SQL adequada.

Pelo menos, é assim que tenho visto no código das bibliotecas independentes de banco de dados.Você pode abstrair a lógica de paginação depois de obter os dados do mecanismo com a consulta específica.

Se você realmente está procurando uma solução única para uma frase SQL, poderia mostrar o que tem em mente?Como o SQL para a solução de tabela temporária.Isso provavelmente lhe daria sugestões mais relevantes.

EDITAR:

Eu queria ver o que você estava pensando porque não consegui ver uma maneira de fazer isso com tabelas temporárias e não usar uma construção específica do mecanismo.Você usou construções específicas no exemplo.Ainda não vejo uma maneira de implementar a paginação no banco de dados apenas com SQL padrão (implementado).Você poderia trazer a tabela inteira no SQL padrão e na página da aplicação, mas isso é obviamente estúpido.

Portanto, a pergunta agora seria mais como "Existe uma maneira de implementar a paginação sem usar limite/deslocamento ou equivalente?" E acho que a resposta é "Suramente, não". Você pode tentar usar cursores, mas também será vítima de frases/comportamentos específicos do banco de dados.

Uma ideia maluca (leia-se estúpida) que acabou de me ocorrer seria adicionar uma coluna de página à tabela, digamos, criar teste de tabela (id int, nome varchar, telefone varchar, página int) e então você pode obter a página 1 com select * da tabela onde página = 1.Mas isso significa ter que adicionar código para manter essa coluna, o que, novamente, só poderia ser feito trazendo todo o banco de dados ou usando construções específicas do banco de dados.Isso além de ter que adicionar uma coluna diferente para cada ordenação possível e muitas outras falhas.

Não posso fornecer provas, mas realmente acho que você simplesmente não pode fazer isso de maneira sensata.

Proceda normalmente:
Comece implementando-o de acordo com o padrão.E então lide com os casos extremos, ou seja,os DBMSes que não implementam o padrão.Como lidar com os casos extremos depende do seu ambiente de desenvolvimento.

Você está procurando uma abordagem "universal".A maneira mais universal de paginar é através do uso de cursores, mas a paginação baseada em cursor não se adapta muito bem a um ambiente sem estado, como um aplicativo da web.

Escrevi sobre o padrão e as implementações (incluindo cursores) aqui:http://troels.arvin.dk/db/rdbms/#select-limit-offset

SubSonic pode fazer isso por você se você tolerar o código aberto ...http://subsonicproject.com/querying/webcast-using-paging/

Fora isso, eu sei que o NHib também faz isso

JPA permite fazer isso com a classe Query:

Query q = ...;
q.setFirstResult (0);
q.setMaxResults (10);

fornece os primeiros 10 resultados no conjunto de resultados.

Se você deseja uma solução SQL bruta independente de DBMS, infelizmente você está sem sorte.Todos os fornecedores fazem isso de maneira diferente.

@Vinko Vrsalovic,

como escrevi na pergunta, sei como fazer isso na maioria dos bancos de dados.Quero encontrar uma solução universal ou obter uma prova de que ela não existe.

Aqui está uma solução estúpida baseada em tabela temporária.É obviamente ruim, então não há necessidade de comentar sobre isso.

N - upper bound
M - lower bound

create #temp (Id int identity, originalId int)

insert into #temp(originalId)
select top N KeyColumn from MyTable
where ...

select MyTable.* from MyTable
join #temp t on t.originalId = MyTable.KeyColumn
where Id between M and M
order by Id asc

drop #temp
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top