2008-09-15 10 views
7

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.¿Cómo implementar la paginación independiente del motor de base de datos?

No publiques 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. Solo soluciones temporales basadas en tablas vienen a mi mente en este momento.

EDIT:
estoy en busca de solución SQL, no tercera biblioteca de partido.

Respuesta

5

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 propias 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 pueda tener una solución universal (cualquiera puede probar que estoy equivocado aquí, abierto a debate) a menos que esté integrada en el sistema de base de datos oa menos que una compañía diga ABC que usa Oracle, MySQL, SQL Server y ellos deciden que todos los diversos 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 usa.

+0

Sí, probé con diferentes soluciones, pero parece imposible crear una versión más o menos portátil. – aku

0

APP le permite hacerlo con la clase de consulta:

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

le da los primeros 10 resultados en el conjunto de resultados.

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

3

La forma más natural y eficiente de realizar paginación es usar el constructo 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 solución de sentencia SQL única, ¿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.

EDIT:

quería ver lo que estaba pensando, porque no podía ver una manera de hacerlo con tablas temporales y no usar 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 forma de implementar la búsqueda 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 agregar una columna de página a la tabla, digamos crear una prueba de tabla (id int, nombre varchar, varchar de teléfono, página int) y luego puede obtener la página 1 con select * from table 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 manera sensata.

1

Proceda como de costumbre:
Comience por implementarlo de acuerdo con la norma. 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.

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 la norma y las implementaciones (incluyendo cursores) aquí: http://troels.arvin.dk/db/rdbms/#select-limit-offset

+0

Troels Arvin, página bastante útil, gracias! – aku

0

@Vinko Vrsalovic,

como he escrito en cuestión sé cómo hacerlo en la mayoría de los DBs. Yo qué encontrar una 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 
+0

El problema con este enfoque es que aunque IDENTITY es SQL estándar, no está disponible en todas las bases de datos. Además, SELECT TOP no es SQL estándar ni se implementa ampliamente. Aparte de eso, la copia de datos puede ser una operación mucho más lenta en comparación con los métodos que no usan una tabla temporal. –

+0

¿Quizás se podría aplicar una vista en lugar de crear una tabla temporal? ¿Puedes crear una vista donde una de las columnas sea una columna de identidad? –

+0

@ 1800 INFORMACIÓN, ¿puedes mostrar un ejemplo – aku

Cuestiones relacionadas