Paginação com o Oracle

Não estou tão familiarizado com a Oracle quanto gostaria de estar. Eu tenho alguns registros de 250k e quero exibi-los 100 por página. Atualmente, tenho um procedimento armazenado que recupera todo o trimestre de um milhão de registros para um dataset usando um adaptador de dados, um dataset e o método dataadapter.Fill (dataset) nos resultados do procedimento armazenado. Se eu tiver “Número da Página” e “Número de registros por página” como valores inteiros que posso passar como parâmetros, qual seria a melhor maneira de recuperar apenas aquela seção em particular. Digamos, se eu passar 10 como um número de página, e 120 como número de páginas, a partir da declaração select que me daria de 1880 a 1200, ou algo assim, minha matemática na minha cabeça pode estar desligada.

Eu estou fazendo isso no .net com c #, pensei que não é importante, se eu posso acertar no lado do sql, então eu deveria ser legal.

Atualização: Consegui usar a sugestão de Brian e está funcionando muito bem. Eu gostaria de trabalhar em alguma otimização, mas as páginas estão chegando em 4 a 5 segundos, em vez de um minuto, e meu controle de paginação foi capaz de integrar muito bem com meus novos stored procedures.

Algo como isso deve funcionar: De Frans Bouma’s Blog

SELECT * FROM ( SELECT a.*, rownum r__ FROM ( SELECT * FROM ORDERS WHERE CustomerID LIKE 'A%' ORDER BY OrderDate DESC, ShippingDate DESC ) a WHERE rownum < ((pageNumber * pageSize) + 1 ) ) WHERE r__ >= (((pageNumber-1) * pageSize) + 1) 

Pergunte ao Tom sobre paginação e funções analíticas muito, muito úteis.

Este é um trecho da página:

 select * from ( select /*+ first_rows(25) */ object_id,object_name, row_number() over (order by object_id) rn from all_objects) where rn between :n and :m order by rn; 

No interesse da perfeição, para pessoas que procuram uma solução mais moderna, no Oracle 12c, há alguns novos resources, incluindo melhor paginação e melhor manuseio.

Paginação

A paginação se parece com isso:

 SELECT * FROM user ORDER BY first_name OFFSET 5 ROWS FETCH NEXT 10 ROWS ONLY; 

Top N Records

Obtendo os melhores registros é assim:

 SELECT * FROM user ORDER BY first_name FETCH FIRST 5 ROWS ONLY 

Observe como os exemplos de consulta acima têm ORDER BY . Os novos comandos respeitam isso e são executados nos dados classificados.

Não consegui encontrar uma boa página de referência Oracle para FETCH ou OFFSET mas esta página tem uma ótima visão geral desses novos resources.

Só quero resumir as respostas e comentários. Existem várias maneiras de fazer uma paginação.

Antes do oracle 12c não havia funcionalidade OFFSET / FETCH, então dê uma olhada no whitepaper como o @jasonk sugeriu. É o artigo mais completo que encontrei sobre diferentes methods, com explicações detalhadas de vantagens e desvantagens. Levaria um tempo significativo para copiá-los e colá-los aqui, então não farei isso.

Há também um bom artigo de criadores jooq explicando algumas ressalvas comuns com oracle e paginação de outros bancos de dados. post de blog de jooq

Boas notícias, desde o oracle 12c temos uma nova funcionalidade OFFSET / FETCH. Novos resources do OracleMagazine 12c . Por favor, consulte “Top-N Queries and Pagination”

Você pode verificar sua versão do oracle emitindo a seguinte declaração

 SELECT * FROM V$VERSION 

Tente o seguinte:

 SELECT * FROM (SELECT FIELDA, FIELDB, FIELDC, ROW_NUMBER() OVER (ORDER BY FIELDC) R FROM TABLE_NAME WHERE FIELDA = 10 ) WHERE R >= 10 AND R <= 15; 

via [tecnicume]