使用Oracle和sql server以及通用分页方法进行分页

use*_*706 7 sql sql-server oracle

我想在gridview或html表中实现分页,我将使用ajax填充.我应该如何编写查询以支持分页?例如,如果pagesize为20,当用户单击第3页时,必须在表格中显示41到60之间的行.起初我可以获取所有记录并将它们放入缓存中,但我认为这是错误的方法.因为数据可能非常庞大,数据可能会从其他会话中更改.那么我该如何实现呢?是否有任何通用方式(适用于所有数据库)?

小智 17

正如其他人所建议的那样,您可以在Oracle中使用rownum.虽然这有点棘手但你必须将查询嵌套两次.

例如,要对查询进行分页

select first_name from some_table order by first_name
Run Code Online (Sandbox Code Playgroud)

你需要像这样嵌套它

select first_name from
  (select rownum as rn, first_name from
    (select first_name from some_table order by first_name)
  ) where rn > 100  and rn <= 200
Run Code Online (Sandbox Code Playgroud)

原因是rownum是 where子句之后和order by子句之前确定的.要查看我的意思,您可以查询

select rownum,first_name from some_table order by first_name
Run Code Online (Sandbox Code Playgroud)

你可能会得到

4   Diane
2   Norm
3   Sam
1   Woody
Run Code Online (Sandbox Code Playgroud)

这是因为oracle评估了where子句(在本例中为none),然后分配rownums,然后按first_name对结果进行排序.您必须嵌套查询,以便它使用在排序行分配的rownum .

第二个嵌套与如何在where条件下处理rownum有关.基本上,如果您查询"rownum> 100",那么您将得不到任何结果.它是一个鸡和蛋的东西,它不能返回任何行,直到它发现rownum> 100,但由于它没有返回任何行,它从不增加rownum,所以它永远不会计为100.呃.第二级嵌套解决了这个问题.请注意,此时必须为rownum列添加别名.

最后,您的order by子句必须使查询具有确定性.例如,如果您有John Doe和John Smith,并且您只按名字排序,则两者可以从一次执行查询到下一次执行.

这里有文章http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.htmlhttp://www.oracle.com/technology/oramag/oracle/07-jan/o17asktom .html.现在我看到我的帖子有多长,我可能应该刚刚发布这些链接......


Ton*_*ews 4

不幸的是,限制查询返回的行范围的方法因数据库管理系统而异:Oracle 使用 ROWNUM(请参阅 ocdecio 的答案),但 ROWNUM 在 SQL Server 中不起作用。

也许您可以使用一个函数封装这些差异,该函数接受给定的 SQL 语句以及第一行和最后一行号,并为目标 DBMS 生成适当的分页 SQL - 即类似:

sql = paginated ('select empno, ename from emp where job = ?', 101, 150)
Run Code Online (Sandbox Code Playgroud)

这会返回

'select * from (select v.*, ROWNUM rn from ('
 + theSql
 + ') v where rownum < 150) where rn >= 101'
Run Code Online (Sandbox Code Playgroud)

对于 Oracle 以及 SQL Server 的其他内容。

但是,请注意,Oracle 解决方案正在将新列 RN 添加到您需要处理的结果中。