微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

通用sqlserver分页存储过程

单主键:

CREATE   PROC  P_viewPage


    
/**/ /*

        nzperfect [no_mIss] 高效通用分页存储过程(双向检索) 2007.5.7  QQ:34813284

        敬告:适用于单一主键或存在唯一值列的表或视图

        ps:sql语句为8000字节,调用时请注意传入参数及sql总长度不要超过指定范围

           

    
*/


    
@TableName   VARCHAR ( 200 ),      -- 表名

     @FieldList   VARCHAR ( 2000 ),     -- 显示列名,如果是全部字段则为*

     @PrimaryKey   VARCHAR ( 100 ),     -- 单一主键或唯一值键

     @Where   VARCHAR ( 2000 ),         -- 查询条件 不含'where'字符,如id>10 and len(userid)>9

     @Order   VARCHAR ( 1000 ),         -- 排序 不含'order by'字符,如id asc,userid desc,必须指定asc或desc                                 

                                  -- 注意当@SortType=3时生效,记住一定要在最后加上主键,否则会让你比较郁闷

     @SortType   INT ,                -- 排序规则 1:正序asc 2:倒序desc 3:多列排序方法

     @RecorderCount   INT ,           -- 记录总数 0:会返回总记录

     @PageSize   INT ,                -- 每页输出的记录数

     @PageIndex   INT ,               -- 当前页数

     @TotalCount   INT  OUTPUT,       -- 记返回总记录

     @TotalPageCount   INT  OUTPUT    -- 返回总页数

AS

    
SET  NOCOUNT  ON


    
IF   ISNULL ( @TotalCount , '' =   ''   SET   @TotalCount   =   0

    
SET   @Order   =   RTRIM ( LTRIM ( @Order ))

    
SET   @PrimaryKey   =   RTRIM ( LTRIM ( @PrimaryKey ))

    
SET   @FieldList   =   REPLACE ( RTRIM ( LTRIM ( @FieldList )), '   ' , '' )


    
WHILE   CHARINDEX ( ' ' , @Order >   0   OR   CHARINDEX ( '  , ' , @Order >   0

    
BEGIN

        
SET   @Order   =   REPLACE ( @Order , ' , ' )

        
SET   @Order   =   REPLACE ( @Order , '  , ' )    

    
END


    
IF   ISNULL ( @TableName , '' =   ''   OR   ISNULL ( @FieldList , '' =   ''  

        
OR   ISNULL ( @PrimaryKey , '' =   ''

        
OR   @SortType   <   1   OR   @SortType   > 3

        
OR   @RecorderCount    <   0   OR   @PageSize   <   0   OR   @PageIndex   <   0         

    
BEGIN  

        
PRINT ( ' ERR_00 ' )       

        
RETURN

    
END     


    
IF   @SortType   =   3

    
BEGIN

        
IF  ( UPPER ( RIGHT ( @Order , 4 )) != '  ASC '   AND   UPPER ( RIGHT ( @Order , 5 )) != '  DESC ' )

        
BEGIN   PRINT ( ' ERR_02 ' RETURN   END

    
END


    
DECLARE   @new_where1   VARCHAR ( 1000 )

    
DECLARE   @new_where2   VARCHAR ( 1000 )

    
DECLARE   @new_order1   VARCHAR ( 1000 )   

    
DECLARE   @new_order2   VARCHAR ( 1000 )

    
DECLARE   @new_order3   VARCHAR ( 1000 )

    
DECLARE   @sql   VARCHAR ( 8000 )

    
DECLARE   @sqlCount   NVARCHAR ( 4000 )


    
IF   ISNULL ( @where , '' =   ''

        
BEGIN

            
SET   @new_where1   =   '   '

            
SET   @new_where2   =   '  WHERE   '

        
END

    
ELSE

        
BEGIN

            
SET   @new_where1   =   '  WHERE  '   +   @where  

            
SET   @new_where2   =   '  WHERE  '   +   @where   +   '  AND  '

        
END


    
IF   ISNULL ( @order , '' =   ''   OR   @SortType   =   1    OR   @SortType   =   2  

        
BEGIN

            
IF   @SortType   =   1  

            
BEGIN  

                
SET   @new_order1   =   '  ORDER BY  '   +   @PrimaryKey   +   '  ASC '

                
SET   @new_order2   =   '  ORDER BY  '   +   @PrimaryKey   +   '  DESC '

            
END

            
IF   @SortType   =   2  

            
BEGIN  

                
SET   @new_order1   =   '  ORDER BY  '   +   @PrimaryKey   +   '  DESC '

                
SET   @new_order2   =   '  ORDER BY  '   +   @PrimaryKey   +   '  ASC '

            
END

        
END

    
ELSE

        
BEGIN

            
SET   @new_order1   =   '  ORDER BY  '   +   @Order

        
END


    
IF   @SortType   =   3   AND    CHARINDEX ( ' , ' + @PrimaryKey + '   ' , ' + @Order ) > 0

        
BEGIN

            
SET   @new_order1   =   '  ORDER BY  '   +   @Order

            
SET   @new_order2   =   @Order   +   ' , '             

            
SET   @new_order2   =   REPLACE ( REPLACE ( @new_order2 , ' ASC, ' {ASC}, ' ), ' DESC, ' {DESC}, ' )            

            
SET   @new_order2   =   REPLACE ( REPLACE ( @new_order2 , ' )

            
SET   @new_order2   =   '  ORDER BY  '   +   SUBSTRING ( @new_order2 , 1 , LEN ( @new_order2 ) - 1 )            

            
IF   @FieldList   <>   ' * '

                
BEGIN             

                    
SET   @new_order3   =   REPLACE ( REPLACE ( @Order   +   ' , ' )                              

                    
SET   @FieldList   =   ' , '   +   @FieldList                     

                    
WHILE   CHARINDEX ( ' , @new_order3 ) > 0

                    
BEGIN

                        
IF   CHARINDEX ( SUBSTRING ( ' , ' + @new_order3 , CHARINDEX ( ' , @new_order3 )), ' + @FieldList + ' , ' ) > 0

                        
BEGIN  

                        
SET   @FieldList   =  

                            
@FieldList   +   ' , '   +   SUBSTRING ( @new_order3 , @new_order3 ))                        

                        
END

                        
SET   @new_order3   =  

                        
SUBSTRING ( @new_order3 , @new_order3 ) + 1 , LEN ( @new_order3 ))

                    
END

                    
SET   @FieldList   =   SUBSTRING ( @FieldList , 2 , LEN ( @FieldList ))                     

                
END             

        
END


    
SET   @sqlCount   =   ' SELECT @TotalCount=COUNT(*),@TotalPageCount=CEILING((COUNT(*)+0.0)/ '

                    
+   CAST ( @PageSize   AS   VARCHAR ) + ' ) FROM  '   +   @TableName   +   @new_where1

    

    
IF   @RecorderCount    =   0

        
BEGIN

             
EXEC  SP_EXECUTEsql  @sqlCount ,N ' @TotalCount INT OUTPUT,@TotalPageCount INT OUTPUT ' ,

                               
@TotalCount  OUTPUT, @TotalPageCount  OUTPUT

        
END

    
ELSE

        
BEGIN

             
SELECT   @TotalCount   =   @RecorderCount             

        
END


    
IF   @PageIndex   >   CEILING (( @TotalCount + 0.0 ) / @PageSize )

        
BEGIN

            
SET   @PageIndex   =    CEILING (( @TotalCount + 0.0 ) / @PageSize )

        
END


    
IF   @PageIndex   =   1   OR   @PageIndex   >=   CEILING (( @TotalCount + 0.0 ) / @PageSize )

        
BEGIN

            
IF   @PageIndex   =   1   -- 返回第一页数据

                 BEGIN

                    
SET   @sql   =   ' SELECT TOP  '   +   STR ( @PageSize +   '   '   +   @FieldList   +   '  FROM  '  

                               
+   @TableName   +   @new_where1   +   @new_order1

                
END

            
IF   @PageIndex   >=   CEILING (( @TotalCount + 0.0 ) / @PageSize )   -- 返回最后一页数据

                 BEGIN

                    
SET   @sql   =   ' SELECT TOP  '   +   STR ( @PageSize +   '   '   +   @FieldList   +   '  FROM ( '  

                               
+   ' SELECT TOP  '   +   STR ( ABS ( @PageSize * @PageIndex - @TotalCount - @PageSize )) 

                               
+   '   '   +   @FieldList   +   '  FROM  '

                               
+   @TableName   +   @new_where1   +   @new_order2   +   '  ) AS TMP  '

                               
+   @new_order1                     

                
END         

        
END     

    
ELSE

        
BEGIN

            
IF   @SortType   =   1    -- 仅主键正序排序

                 BEGIN

                    
IF   @PageIndex   <=   CEILING (( @TotalCount + 0.0 ) / @PageSize ) / 2    -- 正向检索

                         BEGIN

                            
SET   @sql   =   ' SELECT TOP  '   +   STR ( @PageSize +   '   '   +   @FieldList   +   '  FROM  '  

                                       
+   @TableName   +   @new_where2   +   @PrimaryKey   +   '  >  '

                                       
+   ' (SELECT MAX( '   +   @PrimaryKey   +   ' ) FROM (SELECT TOP  '

                                       
+   STR ( @PageSize * ( @PageIndex - 1 ))  +   '   '   +   @PrimaryKey  

                                       
+   '  FROM  '   +   @TableName

                                       
+   @new_where1   +   @new_order1   + '  ) AS TMP)  ' +   @new_order1

                        
END

                    
ELSE    -- 反向检索

                         BEGIN

                            
SET   @sql   =   ' SELECT TOP  '   +   STR ( @PageSize +   '   '   +   @FieldList   +   '  FROM ( '  

                                       
+   ' SELECT TOP  '   +   STR ( @PageSize +   '   '  

                                       
+   @FieldList   +   '  FROM  '

                                       
+   @TableName   +   @new_where2   +   @PrimaryKey   +   '  <  '

                                       
+   ' (SELECT MIN( '   +   @PrimaryKey   +   ' ) FROM (SELECT TOP  '

                                       
+   STR ( @TotalCount - @PageSize * @PageIndex +   '   '   +   @PrimaryKey  

                                       
+   '  FROM  '   +   @TableName

                                       
+   @new_where1   +   @new_order2   + '  ) AS TMP)  ' +   @new_order2  

                                       
+   '  ) AS TMP  '   +   @new_order1

                        
END

                
END

            
IF   @SortType   =   2    -- 仅主键反序排序

                 BEGIN

                    
IF   @PageIndex   <=   CEILING (( @TotalCount + 0.0 ) / @PageSize ) / 2    -- 正向检索

                         BEGIN

                            
SET   @sql   =   ' SELECT TOP  '   +   STR ( @PageSize +   '   '   +   @FieldList   +   '  FROM  '  

                                       
+   @TableName   +   @new_where2   +   @PrimaryKey   +   '  <  '

                                       
+   ' (SELECT MIN( '   +   @PrimaryKey   +   ' ) FROM (SELECT TOP  '

                                       
+   STR ( @PageSize * ( @PageIndex - 1 ))  +   '   '   +   @PrimaryKey  

                                       
+ '  FROM  ' +   @TableName

                                       
+   @new_where1   +   @new_order1   +   ' ) AS TMP)  ' +   @new_order1                                

                        
END  

                    
ELSE    -- 反向检索

                         BEGIN

                            
SET   @sql   =   ' SELECT TOP  '   +   STR ( @PageSize +   '   '   +   @FieldList   +   '  FROM ( '  

                                       
+   ' SELECT TOP  '   +   STR ( @PageSize +   '   '  

                                       
+   @FieldList   +   '  FROM  '

                                       
+   @TableName   +   @new_where2   +   @PrimaryKey   +   '  >  '

                                       
+   ' (SELECT MAX( '   +   @PrimaryKey   +   ' ) FROM (SELECT TOP  '

                                       
+   STR ( @TotalCount - @PageSize * @PageIndex +   '   '   +   @PrimaryKey  

                                       
+   '  FROM  '   +   @TableName

                                       
+   @new_where1   +   @new_order2   + '  ) AS TMP)  ' +   @new_order2  

                                       
+   '  ) AS TMP  '   +   @new_order1

                        
END   

                
END                          

            
IF   @SortType   =   3    -- 多列排序,必须包含主键,且放置最后,否则不处理

                 BEGIN

                    
IF   CHARINDEX ( ' , '   +   @PrimaryKey   +   '   ' , '   +   @Order =   0  

                    
BEGIN   PRINT ( ' ERR_02 ' RETURN   END

                    
IF   @PageIndex   <=   CEILING (( @TotalCount + 0.0 ) / @PageSize ) / 2    -- 正向检索

                         BEGIN

                            
SET   @sql   =   ' SELECT TOP  '   +   STR ( @PageSize +   '   '   +   @FieldList   +   '  FROM (  '

                                       
+   ' SELECT TOP  '   +   STR ( @PageSize +   '   '   +   @FieldList   +   '  FROM (  '

                                       
+   '  SELECT TOP  '   +   STR ( @PageSize * @PageIndex +   '   '   +   @FieldList

                                       
+   '  FROM  '   +   @TableName   +   @new_where1   +   @new_order1   +   '  ) AS TMP  '

                                       
+   @new_order2   +   '  ) AS TMP  '   +   @new_order1     

                        
END

                    
ELSE    -- 反向检索

                         BEGIN

                            
SET   @sql   =   ' SELECT TOP  '   +   STR ( @PageSize +   '   '   +   @FieldList   +   '  FROM (  '   

                                       
+   ' SELECT TOP  '   +   STR ( @PageSize +   '   '   +   @FieldList   +   '  FROM (  '

                                       
+   '  SELECT TOP  '   +   STR ( @TotalCount - @PageSize * @PageIndex + @PageSize +   '   '   +   @FieldList

                                       
+   '  FROM  '   +   @TableName   +   @new_where1   +   @new_order2   +   '  ) AS TMP  '

                                       
+   @new_order1   +   '  ) AS TMP  '   +   @new_order1

                        
END

                
END

        
END

    
PRINT ( @sql )

    
EXEC ( @sql )

GO

 

联合主键的:

CREATE   PROC  P_public_ViewPage

    
/**/ /*

        no_mIss 通用分页存储过程 2007.3.1  QQ:34813284

        适用于联合主键/单主键/存在能确定唯一行列/存在能确定唯一行的多列 (用英文,隔开)

        调用

            第一页查询时返回总记录和总页数及第一页记录:

            EXECUTE P_public_ViewPage_per 'TableName','col1,col2,col3,col4','pk1,pk2,pk3',

                'col5>0 and col7<9','pk1 asc,pk2 asc,pk3 asc',10,1,

                @TotalCount OUTPUT,@TotalPageCount OUTPUT

            其它页调用,比如第89页(假设第一页查询时返回总记录为2000000):

            EXECUTE P_public_ViewPage_per 'TableName',2000000,89,@TotalPageCount OUTPUT

    
*/


    
@TableName   VARCHAR ( 200 ),     -- 显示列名

     @PrimaryKey   VARCHAR ( 100 ),     -- 单一主键或唯一值键或联合主键列表(用英文,隔开)或能确定唯一行的多列列表(用英文,隔开)

     @Where   VARCHAR ( 1000 ),         -- 查询条件 不含'where'字符

     @Order   VARCHAR ( 1000 ),         -- 排序 不含'order by'字符,用英文,隔开  

     @RecorderCount   INT ,       -- 返回记录总数

     @TotalPageCount   INT  OUTPUT    -- 返回总页数

AS


    
SET  NOCOUNT  ON

    

    
SET   @FieldList   =   REPLACE ( @FieldList , '' )

    
IF   @FieldList   =   ' * '  

        
BEGIN   SET   @FieldList   =   ' A.* ' END

    
ELSE

        
BEGIN

            
SET   @FieldList   =   ' A. '   +   REPLACE ( @FieldList ,A. ' )

        
END

    

    
WHILE   CHARINDEX ( ' , @Order ) > 0

    
BEGIN

        
SET   @Order   =   REPLACE ( @Order , ' )

    
END


    
IF   ISNULL ( @TableName , '' =   ''   OR   ISNULL ( @PrimaryKey , '' =   ''         

        
OR   @RecorderCount   <   0   OR   @PageSize   <   0   OR   @PageIndex   <   0

    
BEGIN         

        
RETURN

    
END

 

    
DECLARE   @new_where1   VARCHAR ( 1000 )

    
DECLARE   @new_where2   VARCHAR ( 1000 )

    
DECLARE   @new_where3   VARCHAR ( 1000 )

    
DECLARE   @new_where4   VARCHAR ( 1000 )

    
DECLARE   @new_order1   VARCHAR ( 1000 )

    
DECLARE   @new_order2   VARCHAR ( 1000 )

    
DECLARE   @Fields   VARCHAR ( 1000 )

    
DECLARE   @sql   VARCHAR ( 8000 )

    
DECLARE   @sqlCount   NVARCHAR ( 4000 )


    
SET   @Fields   =   @PrimaryKey   +   ' , '

    
SET   @new_where2   =   ''

    
SET   @new_where4   =   ''



    
IF   ISNULL ( @where , '' =   ''

        
BEGIN

            
SET   @new_where1   =   '   '

            
SET   @new_where3   =   '  WHERE  '

        
END

    
ELSE

        
BEGIN             

            
SET   @new_where1   =   '  WHERE  '   +   @where   +   '   '

            
SET   @new_where3   =   '  WHERE 1=1  '  

                    
+   REPLACE ( '  AND  '   +   @where , '  AND  ' , '  AND A. ' ) +   '  AND  '

        
END

    

    
WHILE   CHARINDEX ( ' , @Fields ) > 0

    
BEGIN

        
SET   @new_where2   =   @new_where2  

            
+   ' A. '   +   LTRIM ( LEFT ( @Fields , @Fields ) - 1 ))

            
+   '  = B. '   +   LTRIM ( LEFT ( @Fields , @Fields ) - 1 ))  +   '  AND  '

        
SET   @new_where4   =   @new_where4  

            
+   ' B. '   +   LTRIM ( LEFT ( @Fields , @Fields ) - 1 ))  +   '  IS NULL AND  '

        
SET   @Fields   =   SUBSTRING ( @Fields , @Fields ) + 1 , LEN ( @Fields ))

    
END

    
SET   @new_where2   =   LEFT ( @new_where2 , LEN ( @new_where2 ) - 4 )

    
SET   @new_where4   =   LEFT ( @new_where4 , LEN ( @new_where4 ) - 4 )


    
IF   ISNULL ( @order , '' =   ''  

        
BEGIN

            
SET   @new_order1   =   ''

            
SET   @new_order2   =   ''

        
END

    
ELSE

        
BEGIN

            
SET   @new_order1   =   '  ORDER BY  '   +   @Order

            
SET   @new_order2   =   '  ORDER BY  '  

                    
+   RIGHT ( REPLACE ( ' , '   +   @Order , A. '  ),

                            
LEN ( REPLACE ( ' , A. '  )) - 1 )

        
END


    
SET   @sqlCount   =   ' SELECT @TotalCount=COUNT(*),@TotalPageCount=CEILING((COUNT(*)+0.0)/ '

                    
+   CAST ( @PageSize   AS   VARCHAR ) + ' ) FROM  '   +   @TableName  

                    
+   '  A  '   +    @new_where1

    

    
IF   @RecorderCount   =   0

        
BEGIN

             
EXEC  SP_EXECUTEsql  @sqlCount , @TotalPageCount  OUTPUT

        
END

    
ELSE

        
BEGIN

             
SELECT   @TotalCount   =   @RecorderCount             

        
END


    
IF   @PageIndex   >   CEILING (( @TotalCount + 0.0 ) / @PageSize )

        
BEGIN

            
SET   @PageIndex   =   CEILING (( @TotalCount + 0.0 ) / @PageSize )

        
END

    
IF   @PageIndex   =   1

        
BEGIN

            
SET   @sql   =   ' SELECT TOP  '   +   STR ( @PageSize +   '   '   +   @FieldList   +   '  FROM  '  

                       
+   @TableName   +   '  A ' +   @new_where1   +   @new_order1

        
END

    
ELSE

        
BEGIN

            
SET   @sql   =   ' SELECT TOP  '   +   STR ( @PageSize +   '   '   +   @FieldList   +   '  FROM  '  

                       
+   @TableName   +   '  A LEFT JOIN (SELECT TOP  '  

                       
+   STR ( @PageSize * ( @PageIndex - 1 )) 

                       
+   '   '   +   @PrimaryKey   +   '  FROM  '   +   @TableName   +   @new_where1

                       
+   @new_order1   +   '  )B ON  '   +   @new_where2   +   @new_where3  

                       
+   @new_where4   +   @new_order2

        
END


EXEC ( @sql )

GO

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐