代码之家  ›  专栏  ›  技术社区  ›  aku

如何实现与数据库引擎无关的分页?

  •  7
  • aku  · 技术社区  · 16 年前

    任务:实现适合不同RDBMS的数据库记录分页。方法应该适用于主流引擎——MSSQLS2000+、Oracle、MySql等。


    我在寻找SQL解决方案,而不是第三方库。

    6 回复  |  直到 16 年前
        1
  •  5
  •   user20358    15 年前

    如果SQL规范将分页作为一种标准,那么就会有一个通用的解决方案。任何RDBMS语言被称为RDBMS语言的要求也不包括分页支持。

    许多数据库产品支持SQL,并对标准语言进行了专有扩展。其中一些支持分页,比如带有limit子句的MySQL,带有Oracle的Rowid;每个人的处理方式都不同。其他DBMS需要添加一个名为rowid的字段或类似的字段。

    我认为你不可能有一个通用的解决方案(任何人都可以自由地证明我错了,这是有争议的),除非它内置在数据库系统中,或者除非有一家公司使用Oracle,MySQL,SQL Server和他们决定让所有不同的数据库系统提供自己的分页实现,由数据库开发人员为使用它的代码提供通用接口。

        2
  •  3
  •   Vinko Vrsalovic    16 年前

    最自然、最有效的分页方法是使用LIMIT/OFFSET(Sybase world中的TOP)构造。独立于数据库的方法必须知道它在哪个引擎上运行,并应用适当的SQL构造。

    如果你真的在寻找一个单一的、一句SQL的解决方案,你能展示一下你的想法吗?类似于临时表解决方案的SQL。这可能会给你更多相关的建议。

    编辑:

    因此,现在的问题更像是“有没有一种方法可以实现分页而不使用限制/偏移量或等效项?”我猜答案是“理智地说,没有”。你可以尝试使用游标,但你也会成为数据库特定语句/行为的牺牲品。

    我不能提供证据,但我真的认为你不能理智地去做。

        3
  •  1
  •   Troels Arvin    16 年前


    首先,根据标准实施它。然后处理一些特殊情况,即未实现标准的DBMS。如何处理紧急情况取决于您的开发环境。

    您正在寻找一种“通用”方法。分页最普遍的方法是使用游标,但基于游标的分页不太适合web应用程序等非状态环境。

    我已经在这里介绍了标准和实现(包括游标): http://troels.arvin.dk/db/rdbms/#select-limit-offset

        4
  •  0
  •   user1151 user1151    16 年前

    亚音速可以为你做到这一点,如果你能容忍开源。。。 http://subsonicproject.com/querying/webcast-using-paging/

    除此之外,我知道NHib也会这样做

        5
  •  0
  •   jodonnell    16 年前

    JPA允许您使用查询类执行此操作:

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

    如果您想要一个独立于DBMS的原始SQL解决方案,恐怕您运气不好。所有供应商的做法都不同。

        6
  •  0
  •   aku    16 年前

    正如我在问题中所写的,我知道如何在大多数DBs中做到这一点。我想知道怎样才能找到普遍的解决方案,或者得到它不存在的证据。

    下面是一个基于临时表的愚蠢解决方案。这显然很糟糕,所以没必要对此发表评论。

    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