SQLSERVER2000 存儲過程分頁

好久沒有用數據庫了。最近在做項目時突然發現6年前自己的分頁代碼有問題的。

這個問題客戶居然從來沒反饋過。原來是通過主鍵來分頁的,但排序條件加入後其實不能保證主鍵隊列也是排序的,因此 ... WHERE ZID > MAX(...) ... 的做法不對的。

現在改進,使用 NOT IN 的方法。思路是:比如顯示第3頁,每頁10條記錄,那麼取出30條記錄,但是過濾掉前20條,這樣排序是解決了,但效率應該降低了。

貼代碼:

CREATE PROCEDURE sp_GetPageData
 @sSelect NVARCHAR(100), --select 子句
 @sFrom NVARCHAR(200),   --from 子句
 @sWhere NVARCHAR(200),  --where 子句
 @sOrder NVARCHAR(50),   --order by 子句
 @iCurPageNo int,        --當前頁碼
 @iPageSize int,         -- 分頁大小
 @iRecordCount int out   --輸出總數據條目數量  
  
AS

DECLARE @iPageCount int   --分頁數量
DECLARE @SQLString NVARCHAR(800)        --總SQL
DECLARE @ParmDefinition NVARCHAR(50)    --參數定義
DECLARE @sWhereIn NVARCHAR(200)         --NOT IN 子句

 IF @iPageSize < 1

   SET @iPageSize = 10

--計算記錄數目
SET @SQLString = N'SELECT @iRecordCount = COUNT(*)  FROM ' + @sFrom +  N' WHERE' + @sWhere
--+ ' ORDER BY ' + @sOrder

SET @ParmDefinition = N'@iRecordCount int OUT'
print @SQLString

EXECUTE sp_executesql @SQLString,@ParmDefinition,@iRecordCount OUT
print N'@iRecordCount = ' + CAST(@iRecordCount AS varchar)

if (0 = @iRecordCount)
begin
 print 'data is null'
 return
end

--計算分頁
if (@iRecordCount % @iPageSize > 0)
  SET @iPageCount = @iRecordCount / @iPageSize + 1
ELSE
  SET @iPageCount = @iRecordCount / @iPageSize

--保證請求頁在頁碼範圍內
if (@iCurPageNo > @iPageCount)
 SET @iCurPageNo = @iPageCount
 
--返回數據
if (@iCurPageNo > 1)
BEGIN
  SET @sWhereIn = N' AND m.ZID NOT IN(SELECT TOP ' + CAST(@iPageSize * (@iCurPageNo - 1) AS VARCHAR) + N' m.ZID FROM ' + @sFrom +  N' WHERE' + @sWhere + ' ORDER BY ' + @sOrder + ')'
  SET @SQLString = N'SELECT TOP ' +  CAST(@iPageSize AS VARCHAR) + @sSelect + N' FROM ' + @sFrom +  N' WHERE' + @sWhere + @sWhereIn + ' ORDER BY ' + @sOrder
END
else  -- 第一頁
   SET @SQLString = N'SELECT TOP ' +  CAST(@iPageSize AS VARCHAR(8)) + @sSelect + N' FROM ' + @sFrom +  N' WHERE' + @sWhere + ' ORDER BY ' + @sOrder
 
print @SQLString

exec (@SQLString)

select RecordCount = @iRecordCount

go

 

--測試輸入

declare @iRecordCount int
exec sp_GetPageData
N' m.*, g.ZNAME GroupName ',
N'TB_USER m LEFT JOIN TB_GROUP g ON m.ZGROUP_ID = g.ZID ',
N' 1=1',
N' m.ZID DESC',
10,
1,
@iRecordCount out

print 'iRecordCount = ' + CAST(@iRecordCount AS VARCHAR)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章