以前写分页读取数据时,
1、计算出Max(ID),Min(ID),取值:Max(ID)>ID>Min(ID),构造语句复杂,且容易出现1条数据量的误差;
2、排序我也不敢轻易尝试,担心会将动态sql搞的太复杂。
这次整理以前的存储过程,发现有一个编写存储过程的模版相当给力,思路清新:
1、使用ROW_NUMBER() OVER ( order by [字段1], [字段2],...) AS RowID
2、使用 Top @PageSize ; RowID > @PageSize * (@p_PageIndex -1), 简单精确获取制定数据数据
For Example :
以最简单的Student表为例作为案例:
一、准备工作:建立临时表和填充数据
if exists (select 1 from sys.objects where name ='Student' and type ='U')
drop Table Student
Create Table Student
(
[ID] int IDENTITY(1,1) NOT NULL
,[FullName] nvarchar(30)
,[FirstName] nvarchar(30)
,[LastName] nvarchar(30)
)
insert into Student
select '张一' ,'张','一'
union select '张二' ,'张','二'
union select '张三' ,'张','三'
union select '张四' ,'张','四'
union select '王一' ,'王','一'
union select '王二' ,'王','二'
union select '王三' ,'王','三'
union select '王四' ,'王','四'
union select '胡一' ,'胡','一'
union select '胡二' ,'胡','二'
union select '胡三' ,'胡','三'
union select '胡四' ,'胡','四'
union select '李一' ,'李','一'
union select '李二' ,'李','二'
union select '李三' ,'李','三'
union select '李四' ,'李','四'
二、构造查询全部的SQL语句
--外传穿参数
declare @PageSize int = 1
declare @PageIndex int = 3
declare @OrderStr nvarchar(100) = ' order by [FullName],[FirstName]' --也可根据传进来的参数构造
declare @WhereStr nvarchar(100) = ' Where [FirstName] = ''李''' --也可根据传进来的参数构造
declare @TotalCount int --OUTPUT
--内部临时参数变量
declare @ClumnsStr nvarchar(100)
declare @SQLStr nvarchar(4000)
declare @CountStr nvarchar(4000)
SET @ClumnsStr='
,[FullName]
,[FirstName]
,[LastName]'
set @SQLStr='select ROW_NUMBER() OVER (' + @OrderStr +
') AS RowID'+@ClumnsStr+'
from Student
'+@WhereStr
print '构造查询全部的SQL语句:' print @SQLStr
SET @CountStr = 'select @TotalCount=COUNT(*) from (' + @SQLStr + ') as g' --获得总行数
print ' 获得总行数SQL语句:' PRINT @CountStr
EXEC SP_EXECUTESQL @CountStr,
N' @TotalCount INT OUTPUT',
@TotalCount OUTPUT
print '总行数:' print @TotalCount
SET @SQLStr = 'select top ' + STR(@PageSize) + ' * from(' + @SQLStr +
') as g where RowID >' + STR(@PageSize * (@PageIndex -1))
print '最终组合构造分页查询:' PRINT(@SQLStr)
EXEC(@SQLStr)
四、运行结果