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

     2023-05-07     92

关键词:

【中文标题】如何在 SQL for MS Access 中实现分页?【英文标题】:How do I implement pagination in SQL for MS Access? 【发布时间】:2009-12-14 12:25:24 【问题描述】:

我正在使用 ASP.NET 通过 OdbcConnection 类访问 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? 的子查询有关?

对此的任何帮助将不胜感激;我在谷歌上的搜索产生了无益的结果:(

【问题讨论】:

这个 Q 有 59 次观看(当时),我没有看到一个赞成票。这只是 DBA 的事情吗? 【参考方案1】:

如果您希望在 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

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

【讨论】:

谢谢!尽管由于 ODBC SQL 解析器,我仍然遇到了一些问题(请参阅我的答案)。 当然,是的 slaps head 我认为也可以使用 HAVING 子句,但我不确定 JET - 这就像尝试使用涂有损坏的 SQL玻璃。 @Codesleuth:每个数据库引擎都有自己的 SQL 方言。如果您想使用 Jet/ACE 作为后端,您需要学习它的 SQL 方言,而不是无理地期望它与您已经碰巧知道的任何 SQL 方言完全一样。我质疑基本设置的智慧,即在 Web 应用程序后面使用 Jet/ACE 数据存储。它可以很好地适用于大多数只读操作的小用户群,但无法扩展。 很明显,我使用 Access 数据库的原因是因为数据库引擎的选择超出了我的控制范围。我每天都是 SQL Server 程序员,这就是为什么这些差异让我发疯的原因。例如,链接 INNER JOIN 语句似乎需要在每组连接周围加上括号;我不明白为什么这是必要的,但我现在已经学会了,我可以从现在开始使用它。如果我按照自己的方式,这将完全在 SQL Server 中。数据库已经难以应付我们的 15 个用户,所以也许我会尽快更改它。 @Codesleuth:如果您使用的是特定的数据库引擎并且您对 SQL 方言的差异感到沮丧,那么问题出在您的不熟悉,而不是方言。【参考方案2】:

有关原始答案,请参阅 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

这里的区别在于,当按客户端名称排序时,我需要分页才能工作,并且我需要所有列(嗯,实际上只是一个子集,但我在最外层的查询中对其进行排序)。

【讨论】:

【参考方案3】:

我使用这段 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

【讨论】:

【参考方案4】:

这是使用 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 行。

【讨论】:

这是我正在寻找的解决方案 --> 使用 da 上的填充参数仅获取我需要的内容【参考方案5】:

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

【讨论】:

【参考方案6】:
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 条记录。

【讨论】:

在 MS ACCESS 中实现 INTERSECT (INNER JOIN)

...发布时间】:2012-05-0815:41:04【问题描述】:我一直在研究如何将我拥有的UNION转换为INTERSECT,但MSAccess中没有INTERSECT关键字。如果我想要这两个select语句的交集而不是它们的并集,那么下面的代码使用内连接会是什么样子,我一... 查看详情

如何在 vb.net 中实现交易方式?

】如何在vb.net中实现交易方式?【英文标题】:Howtoimplementtransactionwayinvb.net?【发布时间】:2008-11-1808:59:06【问题描述】:我使用连接到MS-Access数据库的VB.net(200%)开发了一个应用程序,我使用TableAdapter和Dataset连接到AccessDB文件。... 查看详情

如何在 Access 2003 中实现版本控制?

】如何在Access2003中实现版本控制?【英文标题】:HowtoimplementversioncontrolinAccess2003?【发布时间】:2012-08-1517:12:49【问题描述】:我有一个需要修复的Access2003数据库,而以前的开发人员没有使用任何形式的版本控制,并且他的代... 查看详情

如何使用 C# 在 access 数据库中实现“右外连接”查询?

】如何使用C#在access数据库中实现“右外连接”查询?【英文标题】:Howtoimplement"RightOuterJoin"queryinaccessdatabaseusingC#?【发布时间】:2012-07-2305:12:46【问题描述】:我想编写RightOuterJoin查询以从access数据库中检索数据。如何... 查看详情

如何在 Access 中实现自反主键/外键关系?

】如何在Access中实现自反主键/外键关系?【英文标题】:HowcanIimplementareflexiveprimary/foreignkeyrelationshipinAccess?【发布时间】:2019-01-0823:08:01【问题描述】:MSOffice265专业增强版,Access2007-2016我是新手。我有一张名为pedigree的表。我... 查看详情

如何在 SQL 中实现桶值?

】如何在SQL中实现桶值?【英文标题】:HowtoachievethebucketvaluesinSQL?【发布时间】:2018-07-2307:08:35【问题描述】:我有这样的时间表(tablename=testSch)IDAmountscheduleDate17230.002018-07-1317272.002018-07-2717314.002018-08-1017356.002018-08-2417398.002018-09- 查看详情

如何在 SQL 中实现这种双重联接?

】如何在SQL中实现这种双重联接?【英文标题】:HowcanIachievethisdoublejoininSQL?【发布时间】:2013-02-0107:15:19【问题描述】:我有这个查询,它连接了存储在缓存表中的事件的名称。SELECTOccurrenceCache.occurrence_date,CalendarItem.summaryFROMOcc... 查看详情

我们如何在sql CTE中实现动态查询?

】我们如何在sqlCTE中实现动态查询?【英文标题】:HowcanweimplementdynamicqueryinsqlCTE?【发布时间】:2015-04-0206:08:01【问题描述】:如何在sqlCTE中实现动态查询?【问题讨论】:HowdoIaskagoodquestion-这不仅不清楚而且严重无法回答....你... 查看详情

如何在 asp.net 中实现“Access-Control-Allow-Origin”标头

】如何在asp.net中实现“Access-Control-Allow-Origin”标头【英文标题】:Howtoimplement"Access-Control-Allow-Origin"headerinasp.net【发布时间】:2011-09-2421:17:02【问题描述】:是否可以在asp.net中实现“Access-Control-Allow-Origin”标头【问题讨... 查看详情

如何在 SQL 中实现后备语言概念

】如何在SQL中实现后备语言概念【英文标题】:HowdoIimplementfallbacklanguageconceptinSQL【发布时间】:2014-12-1210:07:54【问题描述】:我有一个场景有不同的语言记录,我需要在单独的行中获取所有数据,如果某些数据不是所需的语言... 查看详情

如何在 Spark SQL(PySpark) 中实现自增

】如何在SparkSQL(PySpark)中实现自增【英文标题】:HowtoimplementautoincrementinsparkSQL(PySpark)【发布时间】:2016-10-2504:20:43【问题描述】:我需要在我的sparksql表中实现一个自动增量列,我该怎么做。请指导我。我正在使用pyspark2.0谢谢卡... 查看详情

[react]写例子说明react如何在jsx中实现for循环

[react]写例子说明React如何在JSX中实现for循环map方法 个人简介我是歌谣,欢迎和大家一起交流前后端知识。放弃很容易,但坚持一定很酷。欢迎大家一起讨论主目录与歌谣一起通关前端面试题 查看详情

如何在 SQL 中实现聚合? (这与 GroupBy 无关)

】如何在SQL中实现聚合?(这与GroupBy无关)【英文标题】:HowtoimplementanAggregationinSQL?(ThisisnotaboutGroupBy)【发布时间】:2018-06-2903:51:22【问题描述】:在大学项目的范围内,我应该实现我的数据库的聚合。我得到了一个类似于这个... 查看详情

如何在 PL/sql 中实现 NegEx?

】如何在PL/sql中实现NegEx?【英文标题】:HowtoimplementNegExinPL/sql?【发布时间】:2013-08-3119:38:17【问题描述】:我在正则表达式方面的技能充其量是微不足道的。但是,我有一项任务需要阅读医学类型的文本,并标记不同类型的单... 查看详情

如何在 SQL 表中实现这种数据结构

】如何在SQL表中实现这种数据结构【英文标题】:HowtoimplementthisdatastructureinSQLtables【发布时间】:2012-06-0520:50:25【问题描述】:我有一个问题可以总结如下:假设我正在实现一个员工数据库。对于每个人取决于他的职位,应填写... 查看详情

如何在 jOOQ for MySQL 8 中实现 JSON_SET()

】如何在jOOQforMySQL8中实现JSON_SET()【英文标题】:HowtoimplementJSON_SET()injOOQforMySQL8【发布时间】:2020-01-0215:33:36【问题描述】:我有一个带有JSONcol的表--------------------------------------Col1|Col2|JSON_col|Key1|Key2|------------------------------ 查看详情

如何在 Xamarin.Forms for android / ios 中实现特定布局

】如何在Xamarin.Formsforandroid/ios中实现特定布局【英文标题】:HowtoachievespecificlayoutinXamarin.Formsforandroid/ios【发布时间】:2016-06-2417:35:55【问题描述】:我想在页面上添加多个标签并将它们一个接一个地放置。当他们到达屏幕的尽... 查看详情

如何在 Erlang 中实现以下循环?

】如何在Erlang中实现以下循环?【英文标题】:HowcanIimplementthefollowingloopinErlang?【发布时间】:2021-02-1922:05:02【问题描述】:我有以下伪代码:for(inti=0;i<V;i++)for(intj=0;j<V;j++)if((i!=j)&&(tuplei,jbelongtoE))R[i]:=i,j;我想使用erlang... 查看详情