分頁存儲過程

據說分頁存儲過程效率很高,很好用,以前沒有用過今天剛接觸

在這裏整理了幾個可以用的分頁存儲過程,以備後用 。

一:

CREATE PROCEDURE usp_PagingLarge
@TableNames VARCHAR(300),    --表名,可以是多個表,但不能用別名
@PrimaryKey VARCHAR(100),    --主鍵,可以爲空,但@Order爲空時該值不能爲空
@Fields    VARCHAR(350),        --要取出的字段,可以是多個表的字段,可以爲空,爲空表示select *
@PageSize INT,            --每頁記錄數
@CurrentPage INT,        --當前頁,0表示第1頁
@Filter VARCHAR(200) = '',    --條件,可以爲空,不用填 where
@Group VARCHAR(200) = '',    --分組依據,可以爲空,不用填 group by
@Order VARCHAR(200) = '',   --排序,可以爲空,爲空默認按主鍵升序排列,不用填 order by
@RecordCount int = 0 output
AS
BEGIN
    DECLARE @SortColumn VARCHAR(200)
    DECLARE @Operator CHAR(2)
    DECLARE @SortTable VARCHAR(200)
    DECLARE @SortName VARCHAR(200)
    DECLARE @TmpSelect  NVarchar(200)
    IF @Fields = ''
        SET @Fields = '*'
    IF @Filter = ''
        SET @Filter = 'WHERE 1=1'
    ELSE
        SET @Filter = 'WHERE ' +  @Filter
    IF @Group <>''
        SET @Group = 'GROUP BY ' + @Group

    IF @Order <> ''
    BEGIN
        DECLARE @pos1 INT, @pos2 INT
        SET @Order = REPLACE(REPLACE(@Order, ' asc', ' ASC'), ' desc', ' DESC')
        IF CHARINDEX(' DESC', @Order) > 0
            IF CHARINDEX(' ASC', @Order) > 0
            BEGIN
                IF CHARINDEX(' DESC', @Order) < CHARINDEX(' ASC', @Order)
                    SET @Operator = '<='
                ELSE
                    SET @Operator = '>='
            END
            ELSE
                SET @Operator = '<='
        ELSE
            SET @Operator = '>='
        SET @SortColumn = REPLACE(REPLACE(REPLACE(@Order, ' ASC', ''), ' DESC', ''), ' ', '')
        SET @pos1 = CHARINDEX(',', @SortColumn)
        IF @pos1 > 0
            SET @SortColumn = SUBSTRING(@SortColumn, 1, @pos1-1)
        SET @pos2 = CHARINDEX('.', @SortColumn)
        IF @pos2 > 0
        BEGIN
            SET @SortTable = SUBSTRING(@SortColumn, 1, @pos2-1)
            IF @pos1 > 0
                SET @SortName = SUBSTRING(@SortColumn, @pos2+1, @pos1-@pos2-1)
            ELSE
                SET @SortName = SUBSTRING(@SortColumn, @pos2+1, LEN(@SortColumn)-@pos2)
        END
        ELSE
        BEGIN
            SET @SortTable = @TableNames
            SET @SortName = @SortColumn
        END
    END
    ELSE
    BEGIN
        SET @SortColumn = @PrimaryKey
        SET @SortTable = @TableNames
        SET @SortName = @SortColumn
        SET @Order = @SortColumn
        SET @Operator = '>='
    END

    DECLARE @type varchar(50)
    DECLARE @prec int
    SELECT @type=t.name, @prec=c.prec
    FROM sysobjects o
    JOIN syscolumns c on o.id=c.id
    JOIN systypes t on c.xusertype=t.xusertype
    WHERE o.name = @SortTable AND c.name = @SortName
    IF CHARINDEX('char', @type) > 0
    SET @type = @type + '(' + CAST(@prec AS varchar) + ')'
  
    DECLARE @TopRows INT
    SET @TopRows = @PageSize * @CurrentPage + 1
    print @TopRows
    print @Operator
    EXEC('
        DECLARE @SortColumnBegin ' + @type + '
        SET ROWCOUNT ' + @TopRows + '
        SELECT @SortColumnBegin=' + @SortColumn + ' FROM  ' + @TableNames + ' ' + @Filter + ' ' + @Group + ' ORDER BY ' + @Order + '
        SET ROWCOUNT ' + @PageSize + '
        SELECT ' + @Fields + ' FROM  ' + @TableNames + ' ' + @Filter  + ' AND ' + @SortColumn + '' + @Operator + '@SortColumnBegin ' + @Group + ' ORDER BY ' + @Order + '   
    ')
    DECLARE @str_Count_SQL nvarchar(500)
    SET @str_Count_SQL= 'SELECT @TotalCount=count('+@PrimaryKey+') FROM ' + @TableNames + ' ' + @Filter
    EXEC sp_executesql @str_Count_SQL,N'@TotalCount int=0 output',@RecordCount output
End
GO

===========================================================================

二:

ALTER  procedure Consignment
@tablename varchar(80) ,
@strOrder varchar(50) ,
@PageIndex int = 1,
@PageSize int = 15,
@strGetFields varchar(200) = '*',
@OutPut int output
as
Begin
Declare @strSql varchar(500)

DECLARE   @SQL   NVARCHAR(1000)
DECLARE   @R BIGINT
SET   @SQL=  N'select @R=count(*) from  '+@TableName
EXEC  SP_EXECUTESQL   @SQL,  N' @R BIGINT OUTPUT'@R OUTPUT
SET   @OutPut=  @R

if(@PageIndex =1)
Begin
  
set @strSql='select top '+str(@PageSize)+' '+@strGetFields+' from '+@tablename+' order by '+@strOrder
End
Else
  
set @strSql='select top '+str(@PageSize)+' '+@strGetFields+' from '+@tablename+' where ('+@strOrder
            
+' >= ( select Max('+@strOrder+') from ( select top '+str(@PageSize*@PageIndex)+' * from '+@tablename+' order by '
            
+@strOrder+' ) as tempTable)) order by '+ @strOrder
  
select @strSql 
exec(@strSql)

End

三:

alter procedure AllProce
@tablename varchar(200) ,   --表名
@strGetFields varchar(200= '*',  --查詢列名
@PageIndex int = 1 ,         --頁碼
@pageSize int = 15,         --頁面大小
@strWhere  varchar(100= '',     --查詢條件
@strOrder varchar(100= ''--排序列名
@intOrder bit = 0,        --排序類型  1爲升序
@CountAll bigint output              --返回紀錄總數用於計算頁面數    
as
begin
declare @strSql varchar(500)  --主語句
declare @strTemp varchar(100--臨時變量
declare @strOrders varchar(50--排序語句
declare @table varchar(70)

declare   @SQL   nvarchar(1000)
declare   @R bigint
set   @SQL=  N'select @R=count(*) from  '+convert(nvarchar(200),@TableName)
exec  SP_EXECUTESQL   @SQL,  N' @R BIGINT OUTPUT',  @R OUTPUT
set   @CountAll=  @R
if @intOrder = 0
begin
    
--爲0是升序
    set @strTemp = '>(select max'
    
set @strOrders =  ' order by  '+@strOrder+' asc '
end
else
begin
    
--否則爲降序
    set @strTemp = '<(select min'
    
set @strOrders = ' order by  '+@strOrder+' desc '
end
if @PageIndex =1        --第一頁直接讀出紀錄
begin
    
if @strWhere = ''
    
begin
         
set @strSql = 'select top '+str(@pageSize)+' '+@strGetFields+' from '+@tablename+' '+@strOrders
     
end
    
else  
    
begin
         
set @strSql = 'select top '+str(@pageSize)+' '+@strGetFields+ ' from '+@tablename+' where '+@strWhere+' '+@strOrders
    
    
end
end
else
begin
    
set @strSql = 'select top'+str(@pageSize)+' '+@strGetFields+' from '+@tablename+' where '+@strOrder+' '+@strTemp+' ('+@strOrder+')'
                  
+' from (select top '+str((@pageIndex-1)*@pageSize)+' '+@strGetFields+' from '+@tablename+ ' '+@strOrders+ ') as tempTable ) '+@strOrders
         
    
if @strWhere != ' '
    
begin
       
set @strSql = 'select top '+str(@pageSize)+ ' '+@strGetFields+' from '+@tablename+ ' where '+@strOrder+ ' '+@strTemp+' ('+@strOrder+''
                   
+' from(select top '+str((@pageIndex-1)*@pageSize)+' '+@strGetFields+' from '+@tablename+' where '+@strWhere+' ' +@strOrders+') as tempTable) where '+@strWhere+' '+@strOrders
   
    
end
end 
exec(@strSql)    
end
GO

 

 

============================================================================

 

     分頁查詢的方法已經很多很多,在這裏我也加入成爲其中一員。
      SQL Server中有一個Set Rowcount的的設置,它的意思是使命令的處理在響應指定的行數之後停止處理命令,利用這個特點,我們可以借用它來在一個千萬行級數據表中實現高性能分頁查詢。先來說說實現方式
      1、我們來假定Table中有一個已經建立了索引的主鍵字段ID(整數型),我們將按照這個字段來取數據進行分頁。
      2、頁的大小我們放在@PageSize中
      3、當前頁號我們放在@CurrentPage中
      4、如何讓記錄指針快速滾動到我們要取的數據開頭的那一行呢,這是關鍵所在!有了Set RowCount,我們就很容易實現了。
      5、如果我們成功地滾動記錄指針到我們要取的數據的開頭的那一行,然後我們把那一行的記錄的ID字段的值記錄下來,那麼,利用Top和條件,我們就很容易的得到指定頁的數據了。當然,有了Set RowCount,我們難道還用Top麼?
      看看Set Rowcount怎麼來幫我們的忙吧:

Declare @ID int
Declare @MoveRecords int

--@CurrentPage和@PageSize是傳入參數
Set @MoveRecords=@CurrentPage * @PageSize+1

--下面兩行實現快速滾動到我們要取的數據的行,並把ID記錄下來
Set Rowcount @MoveRecords
Select @ID=ID from Table1 Order by ID

Set Rowcount @PageSize
--最恨爲了減少麻煩使用*了,但是在這裏爲了說明方便,暫時用一下
Select * From Table1 Where ID>=@ID Order By ID
Set Rowcount 0
      大家可以試試看,在一個1千W記錄的表裏面,一下子方翻頁到第100頁(每頁100條),看看有多快!

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