2009-12-14 3 views
10

J'accède à une base de données Microsoft Access 2002 (MDB) à l'aide d'ASP.NET via la classe OdbcConnection, qui fonctionne plutôt bien mais très lentement.Comment implémenter la pagination dans SQL pour MS Access?

Ma question porte sur la façon de mettre en œuvre la pagination dans SQL pour les requêtes à cette base de données, comme je sais que je peux mettre en œuvre la clause TOP comme:

SELECT TOP 15 * 
FROM table 

mais je suis incapable de trouver un moyen de limiter à un décalage comme peut être fait avec SQL Server en utilisant ROWNUMBER. Ma meilleure tentative a été:

SELECT ClientCode, 
    (SELECT COUNT(c2.ClientCode) 
     FROM tblClient AS c2 
     WHERE c2.ClientCode <= c1.ClientCode) 
    AS rownumber 
FROM tblClient AS c1 
WHERE rownumber BETWEEN 0 AND 15 

qui échoue avec:

erreur Source: Microsoft Jet Database Engine

Message d'erreur: Aucune valeur donnée pour un ou plusieurs paramètres requis.

Je ne peux pas résoudre cette erreur, mais je suppose qu'il a quelque chose à voir avec la sous-requête qui détermine un rownumber?

Toute aide serait appréciée avec ceci; mes recherches sur Google ont donné des résultats inutiles :(

+0

Ce Q a 59 vues (à l'époque) et je ne vois pas un seul upvote. Est-ce juste une chose DBA? –

Répondre

10

Si vous souhaitez appliquer la pagination dans MS Acces utiliser cette

SELECT * 
FROM (
    SELECT Top 5 sub.ClientCode 
    FROM (
     SELECT TOP 15 tblClient.ClientCode 
     FROM tblClient 
     ORDER BY tblClient.ClientCode 
    ) sub 
    ORDER BY sub.ClientCode DESC 
) subOrdered 
ORDER BY subOrdered.ClientCode 

Où 15 est le StartPos + PageSize, et 5 est le PageSize.

EDIT pour commenter:

L'erreur que vous recevez, est parce que vous essayez de re assigner un nom de colonne assigner au même niveau de la requête, à savoir rownumber. Si vous deviez changer votre requête:

SELECT * 
FROM (
    SELECT ClientCode, 
      (SELECT COUNT(c2.ClientCode) 
      FROM tblClient AS c2 
      WHERE c2.ClientCode <= c1.ClientCode) AS rownumber     
    FROM tblClient AS c1 
) 
WHERE rownumber BETWEEN 0 AND 15 

Il ne devrait pas vous donner une erreur, mais je ne pense pas que cela est le résultat de recherche de personnes que vous voulez.

+0

Merci! Bien que je recevais quelques problèmes encore en raison de l'analyseur SQL ODBC (voir ma réponse). – Codesleuth

+0

Jetez un oeil à la réponse éditée. –

+1

Bien sûr, oui * slaps head * J'aurais pu aussi utiliser une clause HAVING, mais je ne suis pas sûr avec JET - c'est comme essayer de travailler avec SQL enduit de verre brisé. – Codesleuth

3

Voir astander's answer la réponse originale, mais voici ma mise en œuvre finale qui tient compte des règles de l'analyseur ODBC (pour les 15 premiers enregistrements après avoir sauté 30):

SELECT * 
FROM (
    SELECT Top 15 -- = PageSize 
    * 
    FROM 
    (
    SELECT TOP 45 -- = StartPos + PageSize 
    * 
    FROM tblClient 
    ORDER BY Client 
) AS sub1 
    ORDER BY sub1.Client DESC 
) AS clients 
ORDER BY Client 

La différence ici est que j'ai besoin pagination à travailler quand trié par nom de client, et j'ai besoin de toutes les colonnes (enfin, en fait juste un sous-ensemble, mais je trier cela dans la requête externe).

1

J'utilise ce code SQL pour mettre en œuvre la mise en page avec accès

Select TOP Row_Per_Page * From [
Select TOP (TotRows - ((Page_Number - 1) * Row_Per_Page)
From SampleTable Order By ColumnName DESC
] Order By ColumnName ASC

J'ai publié un article avec quelques captures d'écran on my blog

0

One moyen facile d'utiliser la limite ou obtenir un pagina tion travaillant dans l'accès est d'utiliser la bibliothèque ADODB qui supporte la pagination pour de nombreux DB avec la même syntaxe. http://phplens.com/lens/adodb/docs-adodb.htm#ex8 Il est facile de modifier/remplacer la classe pager pour aller chercher le nombre requis de lignes au format tableau.

0

Il s'agit de la méthode de pagination simple utilisant les classes OleDbDataAdapter et Datatable. J'utilise une commande SQL différente pour plus de simplicité.

 Dim sSQL As String = "select Name, Id from Customer order by Id" 
     Dim pageNumber As Integer = 1 
     Dim nTop As Integer = 20 
     Dim nSkip As Integer = 0 
     Dim bContinue As Boolean = True 
     Dim dtData as new Datatable 
     Do While bContinue 

      dtData = GetData(sSQL, nTop, nSkip, ConnectionString) 

      nSkip = pageNumber * nTop 
      pageNumber = pageNumber + 1 

      bContinue = dtData.Rows.Count > 0 
      If bContinue Then 
       For Each dr As DataRow In dtData.Rows 
        'do your work here 
       Next 
      End If 
     Loop 

Voici la fonction GetData. Les codes ci-dessus retourneront 10 lignes de la table Customer chaque fois que la boucle fonctionnera jusqu'à la fin du fichier.