Comment implémenter la pagination indépendante du moteur de base de données?

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

  •  09-06-2019
  •  | 
  •  

Question

Tâche: implémenter la pagination des enregistrements de base de données adaptée à différents SGBDR. La méthode devrait fonctionner pour les moteurs classiques - MSSQL2000 +, Oracle, MySql, etc.

N'envoyez pas de solutions spécifiques aux SGBDR, je sais comment les implémenter pour la plupart des moteurs de base de données modernes. Je cherche la solution universelle. Pour l'instant, seules des solutions basées sur des tables temporaires me viennent à l'esprit.

MODIFIER:
Je recherche une solution SQL, pas une bibliothèque tierce.

Était-ce utile?

La solution

Il y aurait eu une solution universelle si les spécifications SQL avaient inclus la pagination en tant que norme. La nécessité d'appeler un langage RDBMS un langage RDBMS n'inclut pas également la prise en charge de la pagination.

De nombreux produits de base de données prennent en charge SQL avec des extensions propriétaires du langage standard. Certains d'entre eux prennent en charge la pagination comme MySQL avec la clause limit, Rowid avec Oracle; chacun traité différemment. Les autres SGBD devront ajouter un champ appelé rowid ou quelque chose comme ça.

Je ne pense pas que vous puissiez avoir une solution universelle (n'importe qui est libre de me prouver le contraire ici; ouvert au débat) à moins que cela ne soit intégré au système de base de données ou à moins qu'une entreprise ne dise ABC utilisant Oracle, MySQL, SQL Serveur et ils décident de faire en sorte que tous les systèmes de base de données fournissent leur propre implémentation de pagination par leurs développeurs de base de données, fournissant une interface universelle pour le code qui l’utilise.

Autres conseils

La méthode la plus naturelle et la plus efficace pour la pagination consiste à utiliser la construction LIMIT / OFFSET (TOP dans Sybase). Un moyen DBindependent devrait connaître le moteur sur lequel il est exécuté et appliquer la construction SQL appropriée.

Du moins, c'est ce que j'ai vu dans le code des bibliothèques indépendantes de la base de données. Vous pouvez extraire la logique de pagination une fois que vous avez récupéré les données du moteur avec la requête spécifique.

Si vous recherchez réellement une solution unique, une phrase SQL, pouvez-vous montrer ce que vous avez en tête? Comme le code SQL pour la solution de table temporaire. Cela vous donnerait probablement des suggestions plus pertinentes.

EDIT:

Je voulais voir ce que vous pensiez parce que je ne voyais pas comment le faire avec des tables temporaires sans utiliser une construction spécifique à un moteur. Vous avez utilisé des constructions spécifiques dans l'exemple. Je ne vois toujours pas de moyen d'implémenter la pagination dans la base de données avec uniquement du SQL standard (implémenté). Vous pouvez apporter la totalité de la table en SQL standard et une page dans l'application, mais c'est évidemment stupide.

La question se présentera donc plutôt comme suit: "Existe-t-il un moyen de mettre en oeuvre la pagination sans utiliser LIMIT / OFFSET ou l’équivalent?" et je suppose que la réponse est "Sanely, no". Vous pouvez essayer d’utiliser des curseurs, mais vous serez également victime de phrases / comportements spécifiques à la base de données.

Une idée wacko (lu stupide) qui m'est venue à l’esprit serait d’ajouter une colonne de page à la table, par exemple test de création de table (id int, nom varchar, phone varchar, page int) et vous obtiendrez la page 1 with select * from table où page = 1. Mais cela signifie qu’il faut ajouter du code pour gérer cette colonne, ce qui, une fois encore, ne peut être effectué qu’en apportant la base de données complète ou en utilisant des constructions spécifiques à la base de données. Cela en plus d'avoir à ajouter une colonne différente pour chaque ordre possible et de nombreux autres défauts.

Je ne peux pas fournir de preuve, mais je pense vraiment que vous ne pouvez pas le faire sainement.

Procédez comme d'habitude:
Commencez par l'implémenter conformément à la norme. Et puis gérer les cas de coin, c'est-à-dire les SGBD qui n'implémentent pas la norme. La gestion des cas critiques dépend de votre environnement de développement.

Vous recherchez un " universel " approche. Le moyen le plus universel de paginer consiste à utiliser des curseurs, mais la pagination basée sur le curseur ne s’adapte pas très bien à un environnement sans état, comme une application Web.

J'ai écrit sur le standard et les implémentations (y compris les curseurs) ici: http://troels.arvin.dk/db/rdbms/#select- limite offset

SubSonic peut le faire pour vous si vous pouvez tolérer Open Source ... http://subsonicproject.com/querying/webcast-using-paging/

Autre que celui que je connais NHib fait aussi bien

JPA vous permet de le faire avec la classe Query:

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

vous donne les 10 premiers résultats du jeu de résultats.

Si vous souhaitez une solution SQL brute indépendante du SGBD, je crains que vous n’ayez pas de chance. Tous les vendeurs le font différemment.

@Vinko Vrsalovic,

comme je l'ai écrit dans la question, je sais comment le faire dans la plupart des bases de données. Je souhaite trouver une solution universelle ou obtenir la preuve qu'elle n'existe pas.

Voici une solution stupide basée sur une table temporaire. C'est évidemment mauvais, donc pas besoin de commenter.

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top