close

最終版本,增加了倒排序功能,支持datetime類型  

CREATE  PROCEDURE  sp_page  
   @tb                  varchar(50),  --表名  
   @col                varchar(50),  --按該列來進行分頁  
   @coltype        int,                  --@col列的類型,0-數字類型,1-字符類型,2-日期時間類型  
   @orderby        bit,                  --排序,0-順序,1-倒序  
   @collist        varchar(800),--要查詢出的字段列表,*表示全部字段  
   @selecttype  int,                  --查詢類型,1-前頁,2-後頁,3-首頁,4-末頁,5-指定頁  
   @pagesize      int,                  --每頁記錄數  
   @page              int,                  --指定頁  
   @minid            varchar(50),  --當前頁最小號  
   @maxid            varchar(50),  --當前頁最大號  
   @condition    varchar(800)  --查詢條件  
AS  
/*  
功能描述:對指定表中滿足條件的記錄按指定列進行分頁查詢,分頁可以順序、倒序  
                 查詢可以指定頁大小、指定查詢任意頁、指定輸出字段列表  
作        者:pbsql  
版        本:1.01  
最後修改:2004-11-26  
*/  
DECLARE  @sql  nvarchar(4000),@where1  varchar(800),@where2  varchar(800)  
DECLARE  @i  int,@id  varchar(50)  
IF  @coltype=1  or  @coltype=2--字段類型為字符或日期時間要加上引號以作比較用  
BEGIN  
   SET  @minid=''''+@minid+''''  
   SET  @maxid=''''+@maxid+''''  
END  
IF  @condition  is  null  or  rtrim(@condition)=''--沒有查詢條件  
BEGIN  
   SET  @where1='  WHERE  '  
   SET  @where2='    '  
END  
ELSE--有查詢條件  
BEGIN  
   SET  @where1='  WHERE  ('+@condition+')  AND  '--本來有條件再加上此條件  
   SET  @where2='  WHERE  ('+@condition+')  '--原本沒有條件而加上此條件  
END  
SET  @sql=  
   CASE  @selecttype  
       WHEN  1--前頁  
       THEN  'SELECT  *  FROM  (SELECT  TOP  '+CAST(@pagesize  AS  varchar)+  
                 '  '+@collist+'  FROM  '+@tb+@where1+@col+  
                 CASE  @orderby  WHEN  0  THEN  '<'+@minid  ELSE  '>'+@maxid  END+  
                 '  ORDER  BY  '+@col+CASE  @orderby  WHEN  0  THEN  '  DESC'  ELSE  ''  END+  
                 ')  t  ORDER  BY  '+@col+CASE  @orderby  WHEN  0  THEN  ''  ELSE  'DESC'  END  
       WHEN  2--後頁  
       THEN  'SELECT  TOP  '+CAST(@pagesize  AS  varchar)+'  '+@collist+  
                 '  FROM  '+@tb+@where1+@col+  
                 CASE  @orderby  WHEN  0  THEN  '>'+@maxid  ELSE  '<'+@minid  END+  
                 '  ORDER  BY  '+@col+CASE  @orderby  WHEN  0  THEN  ''  ELSE  '  DESC'  END  
       WHEN  3--首頁  
       THEN  'SELECT  TOP  '+CAST(@pagesize  AS  varchar)+'  '+@collist+  
                 '  FROM  '+@tb+@where2+'ORDER  BY  '+@col+  
                 CASE  @orderby  WHEN  0  THEN  ''  ELSE  '  DESC'  END  
       WHEN  4--末頁  
       THEN  'SELECT  *  FROM  (SELECT  TOP  '+CAST(@pagesize  AS  varchar)+'  '+  
                 @collist+'  FROM  '+@tb+@where2+'ORDER  BY  '+@col+  
                 CASE  @orderby  WHEN  0  THEN  '  DESC'  ELSE  ''  END+')  t  ORDER  BY  '+  
                 @col+CASE  @orderby  WHEN  0  THEN  ''  ELSE  '  DESC'  END  
   END  
IF  @selecttype>=1  and  @selecttype<=4  
BEGIN  
   EXEC(@sql)  
   RETURN  
END  
ELSE  
BEGIN--指定頁  
   IF  @coltype=1  
       IF  @orderby  =0  
           SET  @id=''''''  
       ELSE  
           SET  @id=''''+CHAR(255)+''''  
   ELSE  
       IF  @coltype=2  
           IF  @orderby  =0  
               SET  @id='''1753-1-1'''  
           ELSE  
               SET  @id='''9999-12-31'''  
       ELSE  
           IF  @orderby  =0  
               SET  @id='-2147483648'  
           ELSE  
               SET  @id='2147483647'  
   SET  @i=0  
   --為減少之後SELECT  TOP  ...的數據量,此處每10000條循環一次,以盡可能接近所查詢頁  
   WHILE  @i<@pagesize*@page  
   BEGIN  
       IF  @i+10000<@pagesize*@page  
       BEGIN  
           IF  @orderby=0  
               SET  @sql='SELECT  @id=CASE  '+CAST(@coltype  AS  varchar)+  
                   '  WHEN  1  THEN  ''''''''+CAST(MAX('+@col+')  AS  varchar(50))+'+  
                   ''''''''''+  
                   '  WHEN  2  THEN  ''''''''+CONVERT(char(23),MAX('+@col+'),121)+'+  
                   ''''''''''+  
                   '  ELSE  CAST(MAX('+@col+')  AS  varchar)  END  FROM  (SELECT  TOP  10000  '+  
                   @col+'  FROM  '+@tb+@where1+@col+'>'+@id+'  ORDER  BY  '+@col+')  t'  
           ELSE  
               SET  @sql='SELECT  @id=CASE  '+CAST(@coltype  AS  varchar)+  
                   '  WHEN  1  THEN  ''''''''+CAST(MIN('+@col+')  AS  varchar(50))+'+  
                   ''''''''''+  
                   '  WHEN  2  THEN  ''''''''+CONVERT(char(23),MIN('+@col+'),121)+'+  
                   ''''''''''+  
                   '  ELSE  CAST(MIN('+@col+')  AS  varchar)  END  FROM  (SELECT  TOP  10000  '+  
                   @col+'  FROM  '+@tb+@where1+@col+'<'+@id+'  ORDER  BY  '+@col+'  DESC)  t'  
           EXEC  sp_executesql  @sql,N'@id  varchar(50)  OUTPUT',@id  OUTPUT  
           SET  @i=@i+10000  
           IF  @i+10000>=@pagesize*@page  
               BREAK  
       END  
       ELSE  
           BREAK  
   END  
   --上面的循環保證下面的子查詢最多只有10000條數據  
   IF  @orderby=0  
       SET  @sql='SELECT  TOP  '+CAST(@pagesize  AS  varchar)+'  '+@collist+  
                         '  FROM  '+@tb+@where1+@col+'>'+@id+'  AND  '+@col+'  NOT  IN'+  
                         '(SELECT  TOP  '+CAST(@pagesize*(@page-1)-@i  AS  varchar)+  
                         '  '+@col+'  FROM  '+@tb+@where1+@col+'>'+@id+'  ORDER  BY  '+@col+  
                         ')  ORDER  BY  '+@col  
   ELSE  
       SET  @sql='SELECT  TOP  '+CAST(@pagesize  AS  varchar)+'  '+@collist+  
                         '  FROM  '+@tb+@where1+@col+'<'+@id+'  AND  '+@col+'  NOT  IN'+  
                         '(SELECT  TOP  '+CAST(@pagesize*(@page-1)-@i  AS  varchar)+  
                         '  '+@col+'  FROM  '+@tb+@where1+@col+'<'+@id+'  ORDER  BY  '+@col+  
                         '  DESC)  ORDER  BY  '+@col+'  DESC'  
   EXEC(@sql)  
END  
GO  
------------------------  
--測試事例  
select  identity(int,1,1)  id,getdate()  dt,xx=cast(''  as  varchar(10))  into  #t  
 from  sysobjects  
update  #t  set  dt=dateadd(day,id-200,dt),  
                           xx='xxxx'+right('000000'+cast(id  as  varchar(10)),6)  
--exec  sp_page  '#t','id',0,0,'*',5,10,3,'','',''--按id順序取第三頁  
--exec  sp_page  '#t','id',0,1,'*',5,10,3,'','',''--按id倒序取第三頁  
--exec  sp_page  '#t','xx',1,0,'*',1,10,3,'xxxx000021','xxxx000030',''--按xx順序取前一頁  
--exec  sp_page  '#t','xx',1,1,'*',2,10,3,'xxxx000134','xxxx000143',''--按xx倒序取後一頁  
--exec  sp_page  '#t','dt',2,0,'*',4,10,3,'','',''--按dt順序取最後一頁  
exec  sp_page  '#t','dt',2,1,'*',3,10,3,'','',''--按dt倒序取首頁  
drop  table  #t  
-----------------------------------  
改善了一下性能,加了個返回總頁數  
 
CREATE  PROCEDURE  sp_page  
   @tb                  varchar(50),  --表名  
   @col                varchar(50),  --按該列來進行分頁  
   @coltype        int,                  --@col列的類型,0-數字類型,1-字符類型,2-日期時間類型  
   @orderby        bit,                  --排序,0-順序,1-倒序  
   @collist        varchar(800),--要查詢出的字段列表,*表示全部字段  
   @pagesize      int,                  --每頁記錄數  
   @page              int,                  --指定頁  
   @condition    varchar(800),--查詢條件  
   @pages            int  OUTPUT      --總頁數  
AS  
/*  
功能描述:對指定表中滿足條件的記錄按指定列進行分頁查詢,分頁可以順序、倒序  
                 查詢可以指定頁大小、指定查詢任意頁、指定輸出字段列表,返回總頁數  
作        者:pbsql  
版        本:1.10  
最後修改:2004-11-29  
*/  
DECLARE  @sql  nvarchar(4000),@where1  varchar(800),@where2  varchar(800)  
IF  @condition  is  null  or  rtrim(@condition)=''  
BEGIN--沒有查詢條件  
   SET  @where1='  WHERE  '  
   SET  @where2='    '  
END  
ELSE  
BEGIN--有查詢條件  
   SET  @where1='  WHERE  ('+@condition+')  AND  '--本來有條件再加上此條件  
   SET  @where2='  WHERE  ('+@condition+')  '--原本沒有條件而加上此條件  
END  
SET  @sql='SELECT  @pages=CEILING((COUNT(*)+0.0)/'+CAST(@pagesize  AS  varchar)+  
                 ')  FROM  '+@tb+@where2  
EXEC  sp_executesql  @sql,N'@pages  int  OUTPUT',@pages  OUTPUT--計算總頁數  
IF  @orderby=0  
   SET  @sql='SELECT  TOP  '+CAST(@pagesize  AS  varchar)+'  '+@collist+  
                     '  FROM  '+@tb+@where1+@col+'>(SELECT  MAX('+@col+')  '+  
                     '  FROM  (SELECT  TOP  '+CAST(@pagesize*(@page-1)  AS  varchar)+'  '+  
                     @col+'  FROM  '+@tb+@where2+'ORDER  BY  '+@col+')  t)  ORDER  BY  '+@col  
ELSE  
   SET  @sql='SELECT  TOP  '+CAST(@pagesize  AS  varchar)+'  '+@collist+  
                     '  FROM  '+@tb+@where1+@col+'<(SELECT  MIN('+@col+')  '+  
                     '  FROM  (SELECT  TOP  '+CAST(@pagesize*(@page-1)  AS  varchar)+'  '+  
                     @col+'  FROM  '+@tb+@where2+'ORDER  BY  '+@col+'  DESC)  t)  ORDER  BY  '+  
                     @col+'  DESC'  
IF  @page=1--第一頁  
   SET  @sql='SELECT  TOP  '+CAST(@pagesize  AS  varchar)+'  '+@collist+'  FROM  '+@tb+  
       @where2+'ORDER  BY  '+@col+CASE  @orderby  WHEN  0  THEN  ''  ELSE  '  DESC'  END  
EXEC(@sql)  
GO  

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 11 的頭像
    11

    冠霖的部落格

    11 發表在 痞客邦 留言(0) 人氣()