分页存储过程

网上流传的Web分页存储过程大体分为两种:
一、(利用ID大于多少和SELECT TOP分页)

SELECT TOP 页大小 * FROM TestTable
WHERE (ID > (SELECT MAX(id) FROM (SELECT TOP 页大小*页数 id FROM 表 ORDER BY id) AS T))ORDER BY ID

二、
(利用Not In和SELECT TOP分页)

SELECT TOP 页大小 * FROM TestTable
WHERE (ID NOT IN (SELECT TOP 页大小*页数 id FROM 表 ORDER BY id)) ORDER BY ID

众所周知这两个存储过程都有自己的优劣,方案一效率最高但是不够灵活,在实际应用中如果要使用其它指定的字段排序时就无能力了。方案二中使用了NOT IN来过滤数据,这会使率大打折扣。那么有没有界于两者之间的方呢?我们可以使用NOT EXISTS来代替NOT IN.

SELECT TOP 页大小 * FROM TestTable WHERE NOT EXISTS(SELECT * FROM (SELECT TOP 页大小*页数 ID FROM  TestTable) T  WHERE T.ID=TestTable.ID)

不要以为这样就大功告成,这才完成了一半.不知大家有没有碰到这种情况:当排序字段有多个相同值时,SELECT TOP N 得到的结果与SELECT TOP M (N<>M)得到的结果排序顺序是不一样的,这就会引响正常的分页显示所以对上面方法还需要做进一步调整,我们除了需要按指定的列进行排序外还要让他按唯一键排序.这样如果指定的列有多个相同值也可以确保它们在整张表的中的位置不变.

SELECT TOP 页大小 * FROM TestTable WHERE NOT EXISTS(SELECT * FROM (SELECT TOP 页大小*页数 ID FROM TestTable ORDER BY 排序列 ASC/DESC,唯一键列) T WHERE T.ID=TestTable.ID) ORDER BY 排序列 ASC/DESC,唯一键列

下面是存储过程:希望大家试用,给出意见

CREATE   PROC GetCurrentPageData
(
    
@tableName VARCHAR(100),        --表名
    @primaryKey VARCHAR(100),       --主键
    @filter VARCHAR(800)='',        --查询条件(不用写WHERE)
    @fields VARCHAR(800)='*',       --查询字段(用逗号分隔多个字段)
    @orderField VARCHAR(800)='',    --排序列名
    @order BIT=0,                   --排序("1"降序,"0"升序)
    @pageIndex INT=1,               --页面索引
    @pageSize INT=15,               --每页面记录数
    @pageCount INT OUTPUT,          --页面总数
    @recordCount INT OUTPUT         --记录总数
)
AS
DECLARE @SQL NVARCHAR(4000),@subFilter VARCHAR(200),@parentFilter VARCHAR(200)

--组合查询条件字符串
IF @filter IS NOT NULL AND LTRIM(@filter)!=''
    
BEGIN
        
SET @subFilter=' WHERE '+@filter+' '
        
SET @parentFilter=' AND '+@filter+' '
    
END
ELSE
    
BEGIN
        
SET @subFilter=''
        
SET @parentFilter=''
    
END

--组合排序字符串
DECLARE @orderStr VARCHAR(200)
IF @orderField IS NULL OR RTRIM(LTRIM(@orderField))='' OR @orderField=@primaryKey
    
BEGIN
        
IF @order=1
            
SET @orderStr=' ORDER BY '+@primaryKey+' DESC '
        
ELSE
            
SET @orderStr=' ORDER BY '+@primaryKey+' ASC '
    
END
ELSE
    
BEGIN
        
IF @order=1
            
SET @orderStr=' ORDER BY '+@orderField+' DESC,'+@primaryKey
        
ELSE
            
SET @orderStr=' ORDER BY '+@orderField+' ASC,'+@primaryKey
    
END
    
SET @SQL='SELECT TOP '+CAST(@pageSize AS VARCHAR)+' '+@fields+' FROM '+@tableName+' WHERE NOT EXISTS(SELECT * FROM(SELECT TOP '+CAST(((@pageIndex-1)*@pageSizeAS VARCHAR)+' '+@primaryKey+' FROM '+@tableName+@subFilter+@orderStr+') T WHERE T.'+@primaryKey+'='+@tableName+'.'+@primaryKey+')'+@parentFilter+@orderStr
    
EXEC (@SQL)
--查询总页数
SET @SQL='SELECT @pageCount=CEILING((COUNT(*)+0.0)/'+CAST(@pageSize AS VARCHAR)+') FROM '+@tableName+@subFilter
EXEC sp_executesql @SQL,N'@pageCount INT OUTPUT',@pageCount OUTPUT
--查询总计录条数
SET @SQL='SELECT @recordCount=COUNT(*) FROM '+@tableName+@subFilter
EXEC sp_executesql @SQL,N'@recordCount INT OUTPUT',@recordCount OUTPUT
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值