我的漫漫程序之旅

          專注于JavaWeb開發
          隨筆 - 39, 文章 - 310, 評論 - 411, 引用 - 0
          數據加載中……

          SQL之通用查詢分頁存儲過程

          --創建測試表
          if object_id('person'is not null
            
          drop table person

          create table person 
          (
            id 
          int primary key identity(1,1),
            username 
          varchar(50),
            age 
          int,
            remark 
          varchar(100)
          )

          --插入測試數據
          declare @i int
          set @i = 0
          while @i < 100
           
          begin
             
          insert into person values('zdw' + convert(varchar(5),@i),@i,convert(varchar(5),@i))
             
          set @i = @i + 1
            
          end
          go

          select * from person

           
          /*   
            * 分頁存儲過程
            * 功能描述:對指定表中滿足條件的記錄按指定列進行分頁查詢,分頁可以順序、倒序   
            * 查詢可以指定頁大小、指定查詢任意頁、指定輸出字段列表    
            
          */
             
          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   
           
            
          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   
              
          --測試
          exec sp_page  'person','id',0,0,'*',5,10,8,'','','id != 77'
          對于比較簡單的分頁需求,一句sql搞定。
          --第一個10表示pagesize,第二個10用pagesize*(pagenum-1)來算
          --
          比如取第2頁10 * (2-1) ,第3頁 10 * (3 -1)
          select top 10 * from person where id not in (select top 10 id from person)
          大家還有什么好的分頁sql都拿出來分享下吧。



          posted on 2008-11-05 09:44 々上善若水々 閱讀(1734) 評論(0)  編輯  收藏 所屬分類: 數據庫

          主站蜘蛛池模板: 望江县| 弥渡县| 望城县| 丹巴县| 东至县| 灵山县| 康马县| 兴隆县| 紫阳县| 康定县| 河池市| 温泉县| 常熟市| 克什克腾旗| 商河县| 扎鲁特旗| 南昌市| 永和县| 黄大仙区| 德清县| 桓仁| 新晃| 德格县| 宁海县| 和静县| 陕西省| 京山县| 新营市| 高安市| 施甸县| 莒南县| 迁安市| 霍邱县| 龙州县| 鲁甸县| 股票| 安徽省| 鱼台县| 沅陵县| 平顶山市| 科技|