如何在SQL中为MS Access实现分页?

时间:2009-12-14 12:25:25

标签: sql ms-access pagination

我正在通过OdbcConnection类使用ASP.NET访问Microsoft Access 2002数据库(MDB),尽管速度非常慢,但它运行良好。

我的问题是如何在SQL中实现对此数据库的查询分页,因为我知道我可以将TOP子句实现为:

SELECT TOP 15 *
FROM table

但是我无法找到将此限制为偏移的方法,因为使用ROWNUMBER可以使用SQL Server。我最好的尝试是:

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

失败了:

  

错误来源:Microsoft JET数据库引擎

     

错误消息:没有给出一个或多个必需参数的值。

我无法解决此错误,但我认为它与确定rownumber的子查询有关?

任何帮助都会受到赞赏;我在谷歌上的搜索产生了无益的结果:(

6 个答案:

答案 0 :(得分:10)

如果您希望在MS Acces中应用分页,请使用此

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

其中15是 StartPos + PageSize ,其中5是 PageSize

编辑评论:

您收到的错误是因为您尝试在查询的同一级别引用列名分配,即 rownumber 。如果您要将查询更改为:

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

它不应该给你一个错误,但我不认为这是你想要的分页结果。

答案 1 :(得分:3)

请参阅astander's answer了解原始答案,但这是我的最终实现,它考虑了一些ODBC解析器规则(跳过30后的前15条记录):

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

这里的区别在于我需要按客户端名称排序时才能使用分页,我需要所有列(好吧,实际上只是一个子集,但我在最外面的查询中排序)。

答案 2 :(得分:1)

我使用此SQL代码实现Access

的分页

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

我发表了一篇包含一些截图的文章 on my blog

答案 3 :(得分:1)

这是使用OleDbDataAdapter和Datatable类进行分页的简单方法。为简单起见,我使用不同的SQL命令。

        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

这是GetData函数。

    Private Function GetData(ByVal sql As String, ByVal RecordsToFetch As Integer, ByVal StartFrom As Integer, ByVal BackEndTableConnection As String) As DataTable
    Dim dtResult As New DataTable
    Try
        Using conn As New OleDb.OleDbConnection(BackEndTableConnection)
            conn.Open()
            Using cmd As New OleDb.OleDbCommand
                cmd.Connection = conn
                cmd.CommandText = sql
                Using da As New OleDb.OleDbDataAdapter(cmd)
                    If RecordsToFetch > 0 Then
                        da.Fill(StartFrom, RecordsToFetch, dtResult)
                    Else
                        da.Fill(dtResult)
                    End If
                End Using
            End Using
        End Using
    Catch ex As Exception
    End Try
    Return dtResult
End Function

每次循环操作直到文件结束时,上述代码将从表Customer返回10行。

答案 4 :(得分:0)

在访问中使用限制或获取分页的一种简单方法是使用ADODB库,该库支持具有相同语法的许多DB的分页。 http://phplens.com/lens/adodb/docs-adodb.htm#ex8 它很容易修改/覆盖分页器类,以获取数组格式所需的行数。

答案 5 :(得分:0)

SELECT  *
FROM BS_FOTOS AS TBL1
WHERE ((((select COUNT(ID) AS DD FROM BS_FOTOS AS TBL2 WHERE TBL2.ID<=TBL1.ID)) BETWEEN  10 AND 15 ));

其结果仅10到15条记录。