【问题标题】:Attempting to return more rows than what is available试图返回比可用行更多的行
【发布时间】:2023-04-06 12:11:01
【问题描述】:

下面是我的存储过程的示例。 当用户尝试获取的行数 (@PageSize) 多于 最后一页 (@PageNumber) 中当前可用的行数时,会出现一个问题,然后返回的结果是零,而不是即使小于传递的 PageSize 参数,也返回可用的内容。

此调用返回结果

exec [dbo].[CustomersPaginationProc] @LocationID ='0',@PageNumber=17999,@PageSize=10,@SortColumn=N'Name',@SortOrder=N'ASC'

虽然此调用没有

exec [dbo].[CustomersPaginationProc] @LocationID ='0',@PageNumber=17999,@PageSize=20,@SortColumn=N'Name',@SortOrder=N'ASC'

程序详情:

    ALTER PROCEDURE [CustomersPaginationProc]
    -- Add the parameters for the stored procedure here
    @LocationID VARCHAR(50) = NULL
    @PageNumber INT = NULL, 
    @PageSize INT = NULL,
    @SortColumn NVARCHAR(20) = NULL,
    @SortOrder NVARCHAR(4) = NULL
 AS BEGIN
 SET NOCOUNT ON;

 WITH CTE_Results AS 
(
     SELECT 
          cs.LocationID
        , cs.Name
     FROM Customers cs with (nolock)  
     WHERE
        (@LocationID IS NULL OR cs.LocationID LIKE '%' + @LocationID + '%')
),
CTE_TotalRows AS 
(
     SELECT COUNT(*) AS MaxRows FROM CTE_Results
)
SELECT * FROM CTE_Results, CTE_TotalRows
     ORDER BY
            CASE WHEN (@SortColumn IS NOT NULL AND @SortColumn = 'LocationID' AND @SortOrder= 'ASC')
                        THEN CTE_Results.LocationID
            END ASC
      OFFSET @PageSize * (@PageNumber) ROWS
      FETCH NEXT @PageSize ROWS ONLY
      OPTION (RECOMPILE)
END

【问题讨论】:

  • 如果一页有 10 行时有 17999 页,那么如果每页有 20 行,则页数将是该页数的一半(~9000)。因此,传入 PageNumber 和 PageSize 以用于您的计算并不是最好的方案。
  • 另外,为什么要在两个 CTE 之间进行交叉连接?
  • @MarkSinkinson,你有什么更好的建议?在我的场景中,前端表允许选择不同的行数。
  • 这似乎按预期工作。如果您请求的页面比现有数据更远,我希望得到一个空页面。也许这种方法会更好:stackoverflow.com/questions/109232/…
  • @usefulBee 您当然不应该允许您的用户同时选择页码和页面大小。例如,SO 声誉联盟允许选择一个或另一个 stackexchange.com/leagues/1/month/stackoverflow

标签: sql-server stored-procedures pagination


【解决方案1】:

我不明白你为什么要做乘法?为什么要完全加入?这可以简化,并在第二个参数超过可用行数时起作用。

declare @startRows int = 95
declare @nextRows int = 10

--create 100 rows
;WITH
    E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
    E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
    cteTally(N) AS 
    (
        SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E2
    )

select N 
from cteTally
order by N
offset @startRows rows
fetch next @nextRows rows only

【讨论】:

  • 虽然从技术上讲它是一个完全连接,但恰好在 CTE_TotalRows 中只有一行,所以它与没有 where 子句的完全连接相同。 rextester.com/BLRG57519
  • 谢谢。我相信我遵循了以下文章中发布的代码:dotnetdaily.net/featured/…
猜你喜欢
  • 1970-01-01
  • 2019-03-20
  • 1970-01-01
  • 2019-04-05
  • 1970-01-01
  • 2014-12-23
  • 2017-08-22
  • 1970-01-01
  • 2021-05-21
相关资源
最近更新 更多