存储过程sql server中的分页

时间:2015-02-20 06:39:38

标签: c# asp.net sql-server stored-procedures

我已经为存储过程实现了分页,它一个接一个地显示2个表记录。分页逻辑适用于第一个表记录,但第二个表不相应地显示记录。

这是我的存储过程。我哪里错了?

CREATE PROCEDURE sp_PagedItems
(@Page int,
 @RecsPerPage int)
AS
   SET NOCOUNT ON

   CREATE TABLE #TempItems
   (
        ID int IDENTITY,
        Name varchar(50),
        Price int
   )  

   INSERT INTO #TempItems (Name, Price)
      SELECT 
         Name, Price 
      FROM tblItems 
      ORDER BY Price  

   CREATE TABLE #TempItems1
   (
        ID int IDENTITY,
        Name varchar(50),
        Price int
   ) 

   INSERT INTO #TempItems1 (Name, Price)
      SELECT Name, Price  
      FROM tblItems1 
      ORDER BY Price 

   DECLARE @FirstRec int, @LastRec int

   SELECT @FirstRec = (@Page - 1) * @RecsPerPage
   SELECT @LastRec = (@Page * @RecsPerPage + 1)

   SELECT *
   FROM #TempItems 
   WHERE ID > @FirstRec AND ID < @LastRec 

   SELECT *
   FROM #TempItems1 
   WHERE ID > @FirstRec AND ID < @LastRec 

   -- Turn NOCOUNT back OFF
   SET NOCOUNT OFF

执行它:

Exec sp_PagedItems 1, 10

第一个表在第1页显示10条记录,而第二个表只显示7条记录。

3 个答案:

答案 0 :(得分:1)

如果您使用的是SQL Server 2012或更高版本,请尝试使用OFFSET FETCH语句

https://technet.microsoft.com/en-us/library/gg699618%28v=sql.110%29.aspx

答案 1 :(得分:0)

使用SQL从表中分页数据几乎总是会在使用系统生成的ID时遇到麻烦。

您实际进行分页的方式取决于RDBMS支持的SQl,但可以在任何地方使用的一般方法如下:

  1. 通过订购等方式进行正常选择
  2. 从一开始就循环记录,随时计算
  3. 当你到达(pageCount * recordsPerPage)+1时,开始收集记录
  4. 当你到达(pageCount + 1)* recordsPerPage时,停止收集记录
  5. 听起来非常低效,但通常不像它看起来那么糟糕,因为如果你允许排序那么用户所追求的记录通常就在前面。

答案 2 :(得分:0)

是的,这可能会起作用,原因是多个条目中存在相同的id或id。

要解决,在插入临时表后,在选择中,您必须使用ROW_NUMBER() OVER (order by id ) AS rowID,我的所作所为:

--set end page no. from calculation of pageno * pagesize
 SELECT   
   @start = CASE WHEN @pageindex > 1   
          THEN   
      ((@PageIndex-1)*@PageSize)+1    
       ELSE   
      @PageIndex   
     END   

 SET @end = @PageIndex*@PageSize  
-- use cte 
;WITH CTE AS    
(    
 your select query 
  --suppose activityID is a column in select query , we used for row_number
)    
--now use cte with rownumber filter
select * from  
(  
 SELECT ROW_NUMBER() OVER (ORDER BY activityID DESC) as rowID,    
 *, noofRows= (SELECT count(activityID) FROM CTE)    
 FROM CTE   
 where CTE.activityTargetID is not null  
) cte  
WHERE    
 rowID between @start AND @end   

ORDER BY CTE.activityID DESC