database - framework - tutorial django
¿Cómo implementar la paginación independiente del motor de base de datos? (6)
Habría una solución universal si las especificaciones de SQL hubieran incluido la búsqueda 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 propietarias del lenguaje estándar. Algunos de ellos admiten paginación como MySQL con la cláusula de límite, Rowid con Oracle; cada uno manejado de manera diferente. Otros DBMS necesitarán agregar un campo llamado rowid o algo así.
No creo que puedas tener una solución universal (cualquiera puede probar que estoy equivocado aquí, abierta a debate) a menos que esté integrada en el sistema de base de datos o a menos que haya una compañía que diga ABC que use Oracle, MySQL, SQL Server y decida que todos los diversos sistemas de bases de datos proporcionen su propia implementación de paginación por parte de los desarrolladores de su base de datos, proporcionando una interfaz universal para el código que la usa.
Tarea: implementar la búsqueda de registros de bases de datos adecuados para diferentes RDBMS. El método debería funcionar para motores convencionales: MSSQL2000 +, Oracle, MySql, etc.
Por favor, no publique soluciones específicas RDBMS, sé cómo implementar esto para la mayoría de los motores de base de datos modernos. Estoy buscando la solución universal. Solo soluciones temporales basadas en tablas vienen a mi mente en este momento.
EDITAR:
Estoy buscando una solución SQL, no una biblioteca de terceros.
@Vinko Vrsalovic,
como escribí en cuestión, sé cómo hacerlo en la mayoría de las DB. Yo qué encontrar solución universal o obtener una prueba de que no existe.
Aquí hay una solución estúpida basada en la tabla temporal. Obviamente es malo, así que no hay necesidad de comentar al respecto.
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
JPA te permite hacerlo con la clase Query:
Query q = ...;
q.setFirstResult (0);
q.setMaxResults (10);
te da los primeros 10 resultados en el conjunto de resultados.
Si desea una solución de SQL sin procesar independiente de DBMS, me temo que no tiene suerte. Todos los vendedores lo hacen de manera diferente.
La forma más natural y eficiente de hacer paginación es usando la construcción LIMIT / OFFSET (TOP en Sybase world). Una forma independiente de DB debería saber en qué motor se está ejecutando y aplicar la construcción de SQL adecuada.
Al menos, así lo he visto en el código de las bibliotecas independientes de DB. Puede abstraer la lógica de búsqueda una vez que obtenga los datos del motor con la consulta específica.
Si realmente está buscando una sola solución de oración SQL, ¿podría mostrar lo que tiene en mente? Como el SQL para la solución de tabla temporal. Eso probablemente te brinde sugerencias más relevantes.
EDITAR:
Quería ver qué estabas pensando porque no podía ver una forma de hacerlo con tablas temporales y no utilizar una construcción específica del motor. Usaste constructos específicos en el ejemplo. Todavía no veo una forma de implementar paginación en la base de datos con solo SQL estándar (implementado). Podría traer toda la tabla en SQL estándar y página en la aplicación, pero eso es obviamente estúpido.
Entonces, la pregunta ahora sería más como "¿Hay alguna manera de implementar la paginación sin usar LIMIT / OFFSET o equivalente?" y supongo que la respuesta es "Sanely, no". Podría intentar usar los cursores pero también será presa de las oraciones / comportamientos específicos de la base de datos.
Una idea de wacko (léase estúpida) que me acaba de ocurrir sería añadir una columna de página a la tabla, digamos create table test (id int, nombre varchar, phone varchar, page int) y luego puede obtener la página 1 con select * de la tabla donde page = 1. Pero eso significa tener que agregar código para mantener esa columna, lo cual, de nuevo, solo podría hacerse trayendo toda la base de datos o utilizando construcciones específicas de la base de datos. Eso además de tener que agregar una columna diferente por cada posible orden y muchos otros defectos.
No puedo proporcionar pruebas, pero realmente creo que no puedes hacerlo de forma sana.
Proceda como de costumbre:
Comience por implementarlo de acuerdo con el estándar. Y luego maneje los casos de esquina, es decir, los DBMS que no implementan el estándar. Cómo manejar los casos de esquina depende de su entorno de desarrollo.
Usted está buscando un enfoque "universal". La forma más universal de paginar es mediante el uso de cursores, pero la paginación basada en cursor no encaja muy bien con un entorno que no es de 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 usted puede tolerar el código abierto ... http://subsonicproject.com/querying/webcast-using-paging/
Aparte de eso, sé que NHib también lo hace