1 通过select top进行分页查询 /*通用分页程序(排序为组合字段排序)查询原理:需要查询第N页时,首先取到前N页的所有数据,然后排出前N-1页的数据,就是第N页的数据@sortFields 排序的字段名,只能一个字段,需要具有唯一性;可以采用数据记录的主键
*/create PROCEDURE [dbo].[GetOnePageData](
@tblName nvarchar(400), -- 表或视图名称
@selectFields nvarchar(4000) = ''*'', -- 需要返回的字段名
@strWhere nvarchar(4000) = null, -- 查询条件 (注意: 不要加 where)
@sortFields nvarchar(400) = null, -- 排序的字段名,只能一个字段,需要具有唯一性;可以采用数据记录的主键
@pageIndex int = 1, -- 页码
@pageSize int = 20, -- 页尺寸
@descOrderType bit = 1, -- 设置排序类型, 非 0 值则降序
@compositeSortFields nvarchar(4000),--组合排序字段
@doCount bit = 0, --是否返回记录总数
@isPage bit = 1 -- 是否进行分页查询。若不分页,则返回所有的查询结果;若分页,则返回该页数据
)
AS
declare @strSQL nvarchar(4000) -- 主语句
declare @strTmp nvarchar(400) -- 临时变量
declare @strOrder nvarchar(400) -- 排序类型
declare @strCompOrder nvarchar(2000) -- 组合排序类型
if @pageIndex < 1--处理传进来的页编号
begin
Set @pageIndex=1
end
if @descOrderType = 1 --如果@descOrderType是1,就执行降序,这句很重要!
begin
set @strTmp = ''<(select min''
if @sortFields is null
set @strOrder = '' ''
else
set @strOrder = '' order by ['' + @sortFields +''] desc''
end
else
begin
set @strTmp = ''>(select max''
if @sortFields is null
set @strOrder = '' ''
else
set @strOrder = '' order by ['' + @sortFields +''] asc''
end
if @compositeSortFields is not null
begin
set @strTmp = '' not in (select ''
set @strCompOrder = '' order by '' + @compositeSortFields +''''
end
else
set @strCompOrder = @strOrder
---返回记录总数
if @doCount = 1
begin
if @strWhere is not null
set @strSQL = ''select count(*) as Total from '' + @tblName + '' where ''+@strWhere
else
set @strSQL = ''select count(*) as Total from '' + @tblName + ''''
exec (@strSQL)
end
if @isPage = 1 ---要进行分页查询
begin
if @PageIndex = 1--如果是第一页就执行此代码,这样会加快执行速度
begin
if @strWhere is not null
set @strSQL = ''select top '' + str(@PageSize) +'' ''+@selectFields+ '' from '' + @tblName + '' where '' + @strWhere + '' '' + @strCompOrder
else
set @strSQL = ''select top '' + str(@PageSize) +'' ''+@selectFields+ '' from ''+ @tblName + '' ''+ @strCompOrder
end
else
begin
--以下代码赋予了@strSQL以真正执行的SQL代码
set @strSQL = ''select top '' + str(@PageSize) +'' ''+@selectFields+ '' from ''
+ @tblName + '' where ['' + @sortFields + '']'' + @strTmp + ''([''+ @sortFields + '']) from (select top '' + str((@PageIndex-1)*@PageSize) + '' [''+ @sortFields + ''] from '' + @tblName + '''' + @strCompOrder + '') as tblTmp)''+ @strCompOrder
if @strWhere is not null
set @strSQL = ''select top '' + str(@PageSize) +'' ''+@selectFields+ '' from ''
+ @tblName + '' where ['' + @sortFields + '']'' + @strTmp + ''([''
+ @sortFields + '']) from (select top '' + str((@PageIndex-1)*@PageSize) + '' [''
+ @sortFields + ''] from '' + @tblName + '' where '' + @strWhere + '' ''
+ @strCompOrder + '') as tblTmp) and '' + @strWhere + '' '' + @strCompOrder
end
exec (@strSQL)
end
else ---返回所有结果,不进行分页查询;也不需要执行总数统计
begin
if @strWhere is not null
set @strSQL = ''select '' + '' ''+@selectFields+ '' from '' + @tblName + '' where '' + @strWhere + '' '' + @strCompOrder
else
set @strSQL = ''select '' + '' ''+@selectFields+ '' from ''+ @tblName + '' ''+ @strCompOrder
exec (@strSQL)
end
RETURN2通过系统存储过程进行分页查询 /*
一共返回三个表第一个表为空 查询字符串的条件中有 like ,in 可能出现问题,具体出现原因不明
,第二个表包含总页数,总行数,当前页
第三个表包含查询记录*/
create procedure [dbo].[GetOnePageData]
@sqlstr nvarchar(4000), --查询字符串 ,就是一般的查询语句,不需要top关键字
@currentpage int, --第N页
@pagesize int --每页行数
as
set nocount on
declare @P1 int, --P1是游标的id
@rowcount int--
exec sp_cursoropen @P1 output,@sqlstr,@scrollopt=1,@ccopt=1,@rowcount=@rowcount output--定义与游标和游标选项相关联的 SQL 语句,然后填充游标。
--选择总页数,总行数,当前页
select ceiling(1.0*@rowcount/@pagesize) as TotalPages,@rowcount as TotalRows,@currentpage as CurPage
set @currentpage=(@currentpage-1)*@pagesize+1
--查询记录
exec sp_cursorfetch @P1,16,@currentpage,@pagesize --从游标中提取一行或一个行块。
--返回值
exec sp_cursorclose @P1--关闭并释放游标
set nocount off
go3 通过新函数ROW_NUMBER()进行分页查询/*
只适用与sql2005,据调查此方法限制最少,性能最佳
@strOrder nvarchar(400)--需要加 order by ,至少一个字段,是分页的字段
返回两个表,第一个表包含总行数,第二个表是查询到的记录
--分页查询的原理:
--1.先将预分页内容按照排序条件加上自增列导入到临时表中(或表变量)
--2.针对临时表操作,找到相应的N页对应的自增列编码范围
--3.根据第N页对应的自增列编码范围,查找第N页内容
--需要注意的是:
--第一是添加自增列,确定行号
--第二缩减中间处理过程的操作数据量*/
create PROCEDURE GetDataListWithPage
(
@tblName nvarchar(400), -- 表或视图名称 可以是多个表或视图名称
@selectFields nvarchar(400) = ''*'', -- 需要返回的字段名 可以是多个字段名
@strWhere nvarchar(400) = null, -- 查询条件 (注意: 不要加 where)
@pageIndex int = 1, -- 页码
@pageSize int = 20, -- 页尺寸
@strOrder nvarchar(400)--需要加 order by 可以是多个字段名,至少一个字段
)
as
begin
declare @strSQL nvarchar(4000) -- 主语句
declare @strTotal nvarchar(400) -- 计算总行数语句
if @pageIndex < 1
begin
Set @pageIndex=1
end
set @strSQL='' select ROW_NUMBER() OVER( '' + @strOrder+'' ) as RowNumID, '' +@selectFields+'' into #temp ''+'' from '' +@tblName
set @strTotal = '' select count(*) as Total from '' + @tblName + ''''
if (@strWhere is null or @strWhere='''')
begin
set @strSQL=@strSQL+'' select ''+@selectFields +'' from #temp where RowNumID>''+str((@PageIndex-1)*@PageSize)
+'' and RowNumID<= '' +str(@PageIndex*@PageSize)
end
else
begin
set @strSQL=@strSQL+'' where '' +@strWhere+
'' select ''+@selectFields +'' from #temp where RowNumID>''+str((@PageIndex-1)*@PageSize)
+'' and RowNumID<= '' +str(@PageIndex*@PageSize)
set @strTotal = @strTotal + '' where ''+@strWhere
end
EXEC dbo.sp_executesql @strTotal--总记录数
EXEC dbo.sp_executesql @strSQL--第N页数据
end
go
综述,在数据库拼字符串性能不是特别好,如果需要更好的性能,可以把第一或者第三种分页方法根据实际情况,进行改写,改为处理特定表的分页存储过程,不具有通用性,但性能会好很多。这或许就是通用和性能之间的矛盾吧。
*/create PROCEDURE [dbo].[GetOnePageData](
@tblName nvarchar(400), -- 表或视图名称
@selectFields nvarchar(4000) = ''*'', -- 需要返回的字段名
@strWhere nvarchar(4000) = null, -- 查询条件 (注意: 不要加 where)
@sortFields nvarchar(400) = null, -- 排序的字段名,只能一个字段,需要具有唯一性;可以采用数据记录的主键
@pageIndex int = 1, -- 页码
@pageSize int = 20, -- 页尺寸
@descOrderType bit = 1, -- 设置排序类型, 非 0 值则降序
@compositeSortFields nvarchar(4000),--组合排序字段
@doCount bit = 0, --是否返回记录总数
@isPage bit = 1 -- 是否进行分页查询。若不分页,则返回所有的查询结果;若分页,则返回该页数据
)
AS
declare @strSQL nvarchar(4000) -- 主语句
declare @strTmp nvarchar(400) -- 临时变量
declare @strOrder nvarchar(400) -- 排序类型
declare @strCompOrder nvarchar(2000) -- 组合排序类型
if @pageIndex < 1--处理传进来的页编号
begin
Set @pageIndex=1
end
if @descOrderType = 1 --如果@descOrderType是1,就执行降序,这句很重要!
begin
set @strTmp = ''<(select min''
if @sortFields is null
set @strOrder = '' ''
else
set @strOrder = '' order by ['' + @sortFields +''] desc''
end
else
begin
set @strTmp = ''>(select max''
if @sortFields is null
set @strOrder = '' ''
else
set @strOrder = '' order by ['' + @sortFields +''] asc''
end
if @compositeSortFields is not null
begin
set @strTmp = '' not in (select ''
set @strCompOrder = '' order by '' + @compositeSortFields +''''
end
else
set @strCompOrder = @strOrder
---返回记录总数
if @doCount = 1
begin
if @strWhere is not null
set @strSQL = ''select count(*) as Total from '' + @tblName + '' where ''+@strWhere
else
set @strSQL = ''select count(*) as Total from '' + @tblName + ''''
exec (@strSQL)
end
if @isPage = 1 ---要进行分页查询
begin
if @PageIndex = 1--如果是第一页就执行此代码,这样会加快执行速度
begin
if @strWhere is not null
set @strSQL = ''select top '' + str(@PageSize) +'' ''+@selectFields+ '' from '' + @tblName + '' where '' + @strWhere + '' '' + @strCompOrder
else
set @strSQL = ''select top '' + str(@PageSize) +'' ''+@selectFields+ '' from ''+ @tblName + '' ''+ @strCompOrder
end
else
begin
--以下代码赋予了@strSQL以真正执行的SQL代码
set @strSQL = ''select top '' + str(@PageSize) +'' ''+@selectFields+ '' from ''
+ @tblName + '' where ['' + @sortFields + '']'' + @strTmp + ''([''+ @sortFields + '']) from (select top '' + str((@PageIndex-1)*@PageSize) + '' [''+ @sortFields + ''] from '' + @tblName + '''' + @strCompOrder + '') as tblTmp)''+ @strCompOrder
if @strWhere is not null
set @strSQL = ''select top '' + str(@PageSize) +'' ''+@selectFields+ '' from ''
+ @tblName + '' where ['' + @sortFields + '']'' + @strTmp + ''([''
+ @sortFields + '']) from (select top '' + str((@PageIndex-1)*@PageSize) + '' [''
+ @sortFields + ''] from '' + @tblName + '' where '' + @strWhere + '' ''
+ @strCompOrder + '') as tblTmp) and '' + @strWhere + '' '' + @strCompOrder
end
exec (@strSQL)
end
else ---返回所有结果,不进行分页查询;也不需要执行总数统计
begin
if @strWhere is not null
set @strSQL = ''select '' + '' ''+@selectFields+ '' from '' + @tblName + '' where '' + @strWhere + '' '' + @strCompOrder
else
set @strSQL = ''select '' + '' ''+@selectFields+ '' from ''+ @tblName + '' ''+ @strCompOrder
exec (@strSQL)
end
RETURN2通过系统存储过程进行分页查询 /*
一共返回三个表第一个表为空 查询字符串的条件中有 like ,in 可能出现问题,具体出现原因不明
,第二个表包含总页数,总行数,当前页
第三个表包含查询记录*/
create procedure [dbo].[GetOnePageData]
@sqlstr nvarchar(4000), --查询字符串 ,就是一般的查询语句,不需要top关键字
@currentpage int, --第N页
@pagesize int --每页行数
as
set nocount on
declare @P1 int, --P1是游标的id
@rowcount int--
exec sp_cursoropen @P1 output,@sqlstr,@scrollopt=1,@ccopt=1,@rowcount=@rowcount output--定义与游标和游标选项相关联的 SQL 语句,然后填充游标。
--选择总页数,总行数,当前页
select ceiling(1.0*@rowcount/@pagesize) as TotalPages,@rowcount as TotalRows,@currentpage as CurPage
set @currentpage=(@currentpage-1)*@pagesize+1
--查询记录
exec sp_cursorfetch @P1,16,@currentpage,@pagesize --从游标中提取一行或一个行块。
--返回值
exec sp_cursorclose @P1--关闭并释放游标
set nocount off
go3 通过新函数ROW_NUMBER()进行分页查询/*
只适用与sql2005,据调查此方法限制最少,性能最佳
@strOrder nvarchar(400)--需要加 order by ,至少一个字段,是分页的字段
返回两个表,第一个表包含总行数,第二个表是查询到的记录
--分页查询的原理:
--1.先将预分页内容按照排序条件加上自增列导入到临时表中(或表变量)
--2.针对临时表操作,找到相应的N页对应的自增列编码范围
--3.根据第N页对应的自增列编码范围,查找第N页内容
--需要注意的是:
--第一是添加自增列,确定行号
--第二缩减中间处理过程的操作数据量*/
create PROCEDURE GetDataListWithPage
(
@tblName nvarchar(400), -- 表或视图名称 可以是多个表或视图名称
@selectFields nvarchar(400) = ''*'', -- 需要返回的字段名 可以是多个字段名
@strWhere nvarchar(400) = null, -- 查询条件 (注意: 不要加 where)
@pageIndex int = 1, -- 页码
@pageSize int = 20, -- 页尺寸
@strOrder nvarchar(400)--需要加 order by 可以是多个字段名,至少一个字段
)
as
begin
declare @strSQL nvarchar(4000) -- 主语句
declare @strTotal nvarchar(400) -- 计算总行数语句
if @pageIndex < 1
begin
Set @pageIndex=1
end
set @strSQL='' select ROW_NUMBER() OVER( '' + @strOrder+'' ) as RowNumID, '' +@selectFields+'' into #temp ''+'' from '' +@tblName
set @strTotal = '' select count(*) as Total from '' + @tblName + ''''
if (@strWhere is null or @strWhere='''')
begin
set @strSQL=@strSQL+'' select ''+@selectFields +'' from #temp where RowNumID>''+str((@PageIndex-1)*@PageSize)
+'' and RowNumID<= '' +str(@PageIndex*@PageSize)
end
else
begin
set @strSQL=@strSQL+'' where '' +@strWhere+
'' select ''+@selectFields +'' from #temp where RowNumID>''+str((@PageIndex-1)*@PageSize)
+'' and RowNumID<= '' +str(@PageIndex*@PageSize)
set @strTotal = @strTotal + '' where ''+@strWhere
end
EXEC dbo.sp_executesql @strTotal--总记录数
EXEC dbo.sp_executesql @strSQL--第N页数据
end
go
综述,在数据库拼字符串性能不是特别好,如果需要更好的性能,可以把第一或者第三种分页方法根据实际情况,进行改写,改为处理特定表的分页存储过程,不具有通用性,但性能会好很多。这或许就是通用和性能之间的矛盾吧。
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货