2008-10-27 23 views
71

No estoy tan familiarizado con Oracle como me gustaría. Tengo unos 250k registros, y quiero mostrarlos 100 por página. Actualmente tengo un procedimiento almacenado que recupera todo un cuarto de millón de registros en un conjunto de datos usando un adaptador de datos y conjunto de datos y el adaptador de datos. Método de relleno (conjunto de datos) en los resultados del proceso almacenado. Si tengo "Número de página" y "Número de registros por página" como valores enteros que puedo pasar como parámetros, ¿cuál sería la mejor manera de recuperar solo esa sección en particular? Digamos que si paso 10 como número de página y 120 como número de páginas, desde la declaración de selección me daría la 1880a hasta la 1200a, o algo así, mis cálculos en mi cabeza podrían estar apagados.Paginación con Oracle

que estoy haciendo esto en .NET con C#, pensaron que no es importante, si puedo hacerlo bien en el lado de SQL, entonces yo debería ser fresco.

Actualización: Pude usar la sugerencia de Brian, y está funcionando muy bien. Me gustaría trabajar en algo de optimización, pero las páginas vienen en 4 a 5 segundos en lugar de en un minuto, y mi control de paginación pudo integrarse muy bien con mis nuevos procesos almacenados.

Respuesta

112

Algo como esto debería funcionar: From 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) 
+0

Es rownum una palabra reservada? –

+3

Sí, es una columna 'incorporada' que admite Oracle, siempre comienza en 1 y se incrementa para cada fila. Por lo tanto, en este fragmento de código, si tiene 1000 filas, se aplica el orden de clasificación y luego a cada fila se le asigna un rownum. Las selecciones externas utilizan esos números de fila para ubicar la "página" que está buscando según su tamaño de página. –

+5

Esto es bueno, pero terriblemente lento en selecciones grandes, solo compruebe cuál será el momento de seleccionar 0 a 1000 y 500,000 a 501,000 ... Estaba usando este tipo de estructura selecta ahora estoy buscando una solución alternativa. – newhouse

109

Ask Tom de paginación y funciones analíticas muy, muy útiles.

Ésta es extracto de esa 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; 
+3

Esta es en realidad una implementación mucho mejor, aunque es difícil de encontrar en esa publicación. Cuando tiene muchas páginas grandes, la otra debe pasar también por todas las filas de las páginas anteriores. En consultas complicadas, esto significa que las páginas posteriores funcionan peor que las páginas anteriores. – tallseth

+0

@tallseth Tienes razón. Es difícil encontrarlo en esa página. Extracto es agregado. – Chobicus

4

intente lo siguiente:

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; 

través [tecnicume]

31

En aras de la exhaustividad, para personas que buscan una solución más moderna, en Oracle 12c hay algunas características nuevas que incluyen mejor paginación y manejo superior.

Paging

La paginación se ve así:

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

Top N Records

Obtención de los registros superiores se parece a esto:

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

Observe cómo ambos ejemplos de consulta anteriores tienen ORDER BY cláusulas. Los nuevos comandos los respetan y se ejecutan en los datos ordenados.

No pude encontrar una buena página de referencia de Oracle para FETCH o OFFSET, pero this page tiene una gran descripción de estas nuevas características.

5

Solo quiero resumir las respuestas y los comentarios. Hay una serie de formas de hacer una paginación.

Antes del oráculo 12c no había funcionalidad OFFSET/FETCH, así que échale un vistazo a whitepaper como lo sugirió @jasonk. Es el artículo más completo que encontré sobre diferentes métodos con una explicación detallada de las ventajas y desventajas.Llevaría mucho tiempo copiarlos y pegarlos aquí, así que no lo haré.

También hay un buen artículo de los creadores de jooq que explican algunas advertencias comunes con oráculo y otras bases de datos paginación. jooq's blogpost

Buenas noticias, ya que Oracle 12c tenemos una nueva funcionalidad OFFSET/FETCH. OracleMagazine 12c new features. Por favor refiérase a "Búsquedas Top-N y la paginación"

Puede comprobar la versión de Oracle mediante la emisión de la siguiente declaración

SELECT * FROM V$VERSION 
Cuestiones relacionadas