当前位置:  开发笔记 > 前端 > 正文

如何从SQL返回结果页面?

如何解决《如何从SQL返回结果页面?》经验,为你挑选了3个好方法。

许多应用程序都有网格,一次一页地显示数据库表中的数据.其中许多还允许用户选择每页的记录数,按任何列排序,并在结果中来回导航.

在不将整个表格带到客户端然后过滤客户端上的数据的情况下,实现此模式的好算法是什么.如何将您想要显示的记录带给用户?

LINQ是否简化了解决方案?



1> Michael Stum..:

在MS SQL Server 2005及更高版本上,ROW_NUMBER()似乎工作:

T-SQL:使用ROW_NUMBER()进行分页

DECLARE @PageNum AS INT;
DECLARE @PageSize AS INT;
SET @PageNum = 2;
SET @PageSize = 10;

WITH OrdersRN AS
(
    SELECT ROW_NUMBER() OVER(ORDER BY OrderDate, OrderID) AS RowNum
          ,OrderID
          ,OrderDate
          ,CustomerID
          ,EmployeeID
      FROM dbo.Orders
)

SELECT * 
  FROM OrdersRN
 WHERE RowNum BETWEEN (@PageNum - 1) * @PageSize + 1 
                  AND @PageNum * @PageSize
 ORDER BY OrderDate
         ,OrderID;


对于高页码,`ROW_NUMBER()`分页仿真或SQL Server 2012的`OFFSET .. FETCH`子句可能非常慢:http://www.4guysfromrolla.com/webtech/042606-1.shtml.在这种情况下,[搜索方法](http://stackoverflow.com/a/19610367/521799)可能是更好的选择,因为它允许在恒定时间内进行分页.

2> Rory MacLeod..:

我建议使用LINQ,或尝试复制它的功能.我有一个应用程序,我使用LINQ Take和Skip方法来检索分页数据.代码看起来像这样:

MyDataContext db = new MyDataContext();
var results = db.Products
    .Skip((pageNumber - 1) * pageSize)
    .Take(pageSize);

运行SQL Server Profiler显示LINQ正在将此查询转换为SQL,类似于:

SELECT [ProductId], [Name], [Cost], and so on...
FROM (
    SELECT [ProductId], [Name], [Cost], [ROW_NUMBER]
    FROM (
       SELECT ROW_NUMBER() OVER (ORDER BY [Name]) AS [ROW_NUMBER], 
           [ProductId], [Name], [Cost]
       FROM [Products]
    )
    WHERE [ROW_NUMBER] BETWEEN 10 AND 20
)
ORDER BY [ROW_NUMBER]

简单来说:
1.过滤行并使用ROW_NUMBER函数按所需顺序添加行号.
2.过滤(1)以仅返回页面上所需的行号.
3.按行号排序(2),这与您想要的顺序相同(在本例中,按名称).



3> Lukas Eder..:

在数据库中基本上有两种分页方式(我假设你使用的是SQL Server):

使用OFFSET

其他人已经解释了ROW_NUMBER() OVER()排名功能如何用于执行页面.值得一提的是,SQL Server 2012最终包含对SQL标准OFFSET .. FETCH子句的支持:

SELECT first_name, last_name, score
FROM players
ORDER BY score DESC
OFFSET 40 ROWS FETCH NEXT 10 ROWS ONLY

如果您正在使用SQL Server 2012并且向后兼容性不是问题,那么您应该更喜欢这个子句,因为SQL Server在极端情况下会更好地执行它.

使用SEEK方法

在SQL中执行分页有一种完全不同的,快得多但却鲜为人知的方法.这通常被称为"搜索方法",如本博客文章中所述.

SELECT TOP 10 first_name, last_name, score
FROM players
WHERE (score < @previousScore)
   OR (score = @previousScore AND player_id < @previousPlayerId)
ORDER BY score DESC, player_id DESC

@previousScore@previousPlayerId值是来自前一页的最后一条记录的相应值.这允许您获取"下一页".如果ORDER BY方向是ASC,只需使用>.

使用上述方法,您无法在未先读取前40条记录的情况下立即跳转到第4页.但通常情况下,你不想跳得那么远.相反,您可以获得更快的查询,该查询可能能够在固定时间内获取数据,具体取决于您的索引.此外,无论基础数据是否发生变化,您的页面都将保持"稳定"状态(例如,在第4页上,当您在第4页时).

例如,这是在Web应用程序中延迟加载更多数据时实现分页的最佳方法.

注意,"搜索方法"也称为键集寻呼.

推荐阅读
吻过彩虹的脸_378
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有