¿Cómo implementar la paginación independiente del motor de base de datos?

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

  •  09-06-2019
  •  | 
  •  

Pregunta

Tarea:Implementar paginación de registros de bases de datos adecuados para diferentes RDBMS.El método debería funcionar para motores convencionales: MSSQL2000+, Oracle, MySql, etc.

No publique soluciones específicas de RDBMS, sé cómo implementar esto para la mayoría de los motores de bases de datos modernos.Estoy buscando la solución universal.Por el momento, solo me vienen a la mente soluciones basadas en tablas temporales.

EDITAR:
Estoy buscando una solución SQL, no una biblioteca de terceros.

¿Fue útil?

Solución

Habría habido una solución universal si las especificaciones SQL hubieran incluido la paginación como estándar.El requisito de que cualquier lenguaje RDBMS se denomine lenguaje RDBMS tampoco incluye soporte de paginación.

Muchos productos de bases de datos admiten SQL con extensiones patentadas del lenguaje estándar.Algunos de ellos admiten paginación como MySQL con la cláusula de límite, Rowid con Oracle;cada uno se manejó de manera diferente.Otros DBMS necesitarán agregar un campo llamado rowid o algo así.

No creo que se pueda tener una solución universal (cualquiera es libre de demostrar que estoy equivocado aquí; abierto al debate) a menos que esté integrada en el propio sistema de base de datos o a menos que haya una empresa, digamos ABC, que utilice Oracle, MySQL, SQL Server y decide que todos los distintos sistemas de bases de datos proporcionen su propia implementación de paginación por parte de sus desarrolladores de bases de datos, proporcionando una interfaz universal para el código que la utiliza.

Otros consejos

La forma más natural y eficiente de realizar paginación es utilizar la construcción LIMIT/OFFSET (TOP en el mundo Sybase).Una forma independiente de DB tendría que saber en qué motor se está ejecutando y aplicar la construcción SQL adecuada.

Al menos, así es como lo he visto en el código de las bibliotecas independientes de bases de datos.Puede abstraer la lógica de paginación una vez que obtenga los datos del motor con la consulta específica.

Si realmente está buscando una única solución de oración SQL, ¿podría mostrar lo que tiene en mente?Como el SQL para la solución de tabla temporal.Probablemente eso le brindará sugerencias más relevantes.

EDITAR:

Quería ver qué estabas pensando porque no podía ver una manera de hacerlo con tablas temporales y no usar una construcción específica del motor.Usó construcciones específicas en el ejemplo.Todavía no veo una manera de implementar la paginación en la base de datos solo con SQL estándar (implementado).Podrías traer toda la tabla en SQL estándar y la página en la aplicación, pero eso es obviamente estúpido.

Entonces, la pregunta ahora sería más como "¿Hay alguna forma de implementar la paginación sin usar límite/compensación o equivalente?" Y supongo que la respuesta es "Muyamente, no". Puede intentar usar cursores, pero también caerá presas de oraciones/comportamiento específicos de la base de datos allí.

Una idea loca (léase estúpida) que se me acaba de ocurrir sería agregar una columna de página a la tabla, digamos crear prueba de tabla (id int, nombre varchar, teléfono varchar, página int) y luego puede obtener la página 1 con select * de la tabla donde página = 1.Pero eso significa tener que agregar código para mantener esa columna, lo cual, nuevamente, solo se puede hacer trayendo toda la base de datos o usando construcciones específicas de la base de datos.Eso además de tener que agregar una columna diferente por cada orden posible y muchas otras fallas.

No puedo proporcionar pruebas, pero realmente creo que no se puede hacerlo con sensatez.

Proceda como de costumbre:
Empiece por implementarlo según el estándar.Y luego manejar los casos de las esquinas, es decir.los DBMS que no implementan el estándar.La forma de manejar los casos extremos depende de su entorno de desarrollo.

Está buscando un enfoque "universal".La forma más universal de paginar es mediante el uso de cursores, pero la paginación basada en cursores no encaja muy bien en un entorno sin estado como una aplicación web.

He escrito sobre el estándar y las implementaciones (incluidos los cursores) aquí:http://troels.arvin.dk/db/rdbms/#select-limit-offset

SubSonic puede hacer esto por usted si puede tolerar el código abierto...http://subsonicproject.com/querying/webcast-using-paging/

Aparte de eso, sé que NHib también lo hace.

JPA te permite hacerlo con la clase Query:

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

le proporciona los primeros 10 resultados del conjunto de resultados.

Si desea una solución SQL sin formato independiente de DBMS, me temo que no tiene suerte.Todos los proveedores lo hacen de manera diferente.

@Vinko Vrsalovic,

Como escribí en la pregunta, sé cómo hacerlo en la mayoría de las bases de datos.Quiero encontrar una solución universal u obtener una prueba de que no existe.

Aquí hay una solución estúpida basada en una tabla temporal.Obviamente es malo, así que no es necesario comentarlo.

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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top