收藏一个分页存储过程
两种SQL通用分页存储过程:
它们具有以下特点1,支持字段集合选择,2支持任意字段排序,
上面的图,我们以最终结果集倒序为例,第一种方案,我们先取集集合OB,这可以用一个使用SELECT TOP 并使用升级排列的语句完成
然后对OB结果集进行倒序排序,再用"SELECT TOP 每页记录数"倒序 的方式取得目标集合AB,下面是存储过程
create PROCEDURE dbo.GetPagingData
(
@tablename varchar(100),--表名或视图表
@fieldlist varchar(4000)=\'*\',--欲选择字段列表
@orderfield varchar(100),--排序字段
@keyfield varchar(100),--主键
@pageindex int,--页号,从0开始
@pagesize int=20,--页尺寸
@strwhere varchar(4000),--条件
@ordertype bit=1--排序,1,降序,0,升序
)
AS
/**//*
名称:GetPagingRecord
作用:按任意字段进行排序分页
作者:菩提树(MARK MA)
时间:2004-12-14
声明:此代码你可以无偿使用及转载,但在转载时,请勿移称本文字声明
*/
SET NOCOUNT ON
declare @sqlstr varchar(6000)
--处理SQL中危险字符,并且将条件处理成易嵌入的形式
set @sqlstr=\'declare @Rcount int;\'
set @sqlstr=@sqlstr+\'set @rcount=(select count(\'+@keyfield+\') from \'+@tablename+\' where \'+@strWhere+\');\'
set @strwhere=replace(@strwhere,\'\'\'\',\'\'\'\'\'\')
set @strwhere=replace(@strwhere,\'--\',\'\')
set @strwhere=replace(@strwhere,\';\',\'\')
set @sqlstr=@sqlstr+\'declare @Rnum int;\'
set @sqlstr=@sqlstr+\'set @rnum=@rcount-\'+cast(@pagesize as varchar)+\'*\'+cast(@pageindex as varchar)+\';\'
set @sqlstr=@sqlstr+\'declare @sqlstr varchar(6000);\'
if @ordertype=1
begin
set @sqlstr=@sqlstr+\'set @sqlstr=\'\'select top \'+cast(@Pagesize as varchar)+\' \'+@fieldlist+\' from (select top 100
percent * from (select top \'\'+cast(@rnum as varchar)+\'\' * from \'+@tablename+\' where \'+@strwhere+\'
order by \'+@orderfield+\' asc) as b order by paymoney desc) as a order by \'+@orderfield+\' desc \'\';\'
end
else
begin
set @sqlstr=@sqlstr+\'set @sqlstr=\'\'select top \'+cast(@Pagesize as varchar)+\' \'+@fieldlist+\' from (select top 100
percent * from (select top \'\'+cast(@rnum as varchar)+\'\' * from \'+@tablename+\' where \'+@strwhere+\'
order by \'+@orderfield+\' desc) as b order by paymoney asc) as a order by \'+@orderfield+\' asc \'\';\'
end
set @sqlstr=@sqlstr+\'if @Rcount>0 begin execute(@sqlstr) end\'
--print @sqlstr
execute(@sqlstr)
在上面的代码中,还处理了没有符合条件结果的情况
第二种方案的思想是这样的,先用倒序的SELECT TOP (页序号+1)*页尺寸的方法取得AE结果集,再从AE结果集中用NOT IN 的方法排除掉用SELECT TOP 页序号*页尺寸的方法取得的结果集,最后,对目标结果集执行倒序,下面是实现的代码
create PROCEDURE dbo.GetPagingRecord
(
@tablename varchar(100),--表名或视图表
@fieldlist varchar(4000)=\'*\',--欲选择字段列表
@orderfield varchar(100),--排序字段
@keyfield varchar(100),--主键
@pageindex int,--页号,从0开始
@pagesize int=20,--页尺寸
@strwhere varchar(4000),--条件
@ordertype bit=1--排序,1,降序,0,升序
)
AS
/**//*
名称:GetPagingRecord
作用:按任意字段进行排序分页
作者:菩提树(MARK MA)
时间:2004-12-14
声明:此代码你可以无偿使用及转载,但在转载时,请勿移称本文字声明
*/
SET NOCOUNT ON
declare @sqlstr varchar(6000)
--处理SQL中危险字符,并且将条件处理成易嵌入的形式
set @strwhere=replace(@strwhere,\'\'\'\',\'\'\'\'\'\')
set @strwhere=replace(@strwhere,\'--\',\'\')
set @strwhere=replace(@strwhere,\';\',\'\')
set @sqlstr=\'declare @CurPageNum int;\'
set @sqlstr=@sqlstr+\'declare @nextpagenum int;\'
set @sqlstr=@sqlstr+\'set @curpagenum=\'+cast(@PageIndex as varchar)+\'*\'+cast(@Pagesize as varchar)+\';\'
set @sqlstr=@sqlstr+\'set @nextpagenum=\'+cast(@PageIndex+1 as varchar)+\'*\'+cast(@Pagesize as varchar)+\';\'
set @sqlstr=@sqlstr+\'declare @sqlstr varchar(6000);\'
if @ordertype=1
begin
set @sqlstr=@sqlstr+\'set @sqlstr=\'\'select \'+@fieldlist+\' from ( select top \'\'+cast(@nextpagenum as varchar)+\'\' * from
\'+@tablename+\' where \'+@strwhere+\' order by \'+@orderfield+\' desc ) as a where \'+@keyfield+\' not in (
select top \'\'+cast(@curpagenum as varchar)+\'\' \'+@keyfield+\' from \'+@tablename+\' where \'+@strwhere+\'
order by \'+@orderfield+\' desc) order by \'+@orderfield+\' desc\'\';\'
end
else
begin
set @sqlstr=@sqlstr+\'set @sqlstr=\'\'select \'+@fieldlist+\' from ( select top \'\'+cast(@nextpagenum as varchar)+\'\' * from
\'+@tablename+\' where \'+@strwhere+\' order by \'+@orderfield+\' asc ) as a where \'+@keyfield+\' not in (
select top \'\'+cast(@curpagenum as varchar)+\'\' \'+@keyfield+\' from \'+@tablename+\' where \'+@strwhere+\'
order by \'+@orderfield+\' asc) order by \'+@orderfield+\' asc\'\';\'
end
set @sqlstr=@sqlstr+\'execute( @sqlstr)\'
--print @sqlstr
execute(@sqlstr)
需要注意的是,如果要避免SQL注入式攻击,请注意处理像分号,双减号,单引号这些在SQL中有特殊含义的字符
它们具有以下特点1,支持字段集合选择,2支持任意字段排序,
上面的图,我们以最终结果集倒序为例,第一种方案,我们先取集集合OB,这可以用一个使用SELECT TOP 并使用升级排列的语句完成
然后对OB结果集进行倒序排序,再用"SELECT TOP 每页记录数"倒序 的方式取得目标集合AB,下面是存储过程
create PROCEDURE dbo.GetPagingData
(
@tablename varchar(100),--表名或视图表
@fieldlist varchar(4000)=\'*\',--欲选择字段列表
@orderfield varchar(100),--排序字段
@keyfield varchar(100),--主键
@pageindex int,--页号,从0开始
@pagesize int=20,--页尺寸
@strwhere varchar(4000),--条件
@ordertype bit=1--排序,1,降序,0,升序
)
AS
/**//*
名称:GetPagingRecord
作用:按任意字段进行排序分页
作者:菩提树(MARK MA)
时间:2004-12-14
声明:此代码你可以无偿使用及转载,但在转载时,请勿移称本文字声明
*/
SET NOCOUNT ON
declare @sqlstr varchar(6000)
--处理SQL中危险字符,并且将条件处理成易嵌入的形式
set @sqlstr=\'declare @Rcount int;\'
set @sqlstr=@sqlstr+\'set @rcount=(select count(\'+@keyfield+\') from \'+@tablename+\' where \'+@strWhere+\');\'
set @strwhere=replace(@strwhere,\'\'\'\',\'\'\'\'\'\')
set @strwhere=replace(@strwhere,\'--\',\'\')
set @strwhere=replace(@strwhere,\';\',\'\')
set @sqlstr=@sqlstr+\'declare @Rnum int;\'
set @sqlstr=@sqlstr+\'set @rnum=@rcount-\'+cast(@pagesize as varchar)+\'*\'+cast(@pageindex as varchar)+\';\'
set @sqlstr=@sqlstr+\'declare @sqlstr varchar(6000);\'
if @ordertype=1
begin
set @sqlstr=@sqlstr+\'set @sqlstr=\'\'select top \'+cast(@Pagesize as varchar)+\' \'+@fieldlist+\' from (select top 100
percent * from (select top \'\'+cast(@rnum as varchar)+\'\' * from \'+@tablename+\' where \'+@strwhere+\'
order by \'+@orderfield+\' asc) as b order by paymoney desc) as a order by \'+@orderfield+\' desc \'\';\'
end
else
begin
set @sqlstr=@sqlstr+\'set @sqlstr=\'\'select top \'+cast(@Pagesize as varchar)+\' \'+@fieldlist+\' from (select top 100
percent * from (select top \'\'+cast(@rnum as varchar)+\'\' * from \'+@tablename+\' where \'+@strwhere+\'
order by \'+@orderfield+\' desc) as b order by paymoney asc) as a order by \'+@orderfield+\' asc \'\';\'
end
set @sqlstr=@sqlstr+\'if @Rcount>0 begin execute(@sqlstr) end\'
--print @sqlstr
execute(@sqlstr)
在上面的代码中,还处理了没有符合条件结果的情况
第二种方案的思想是这样的,先用倒序的SELECT TOP (页序号+1)*页尺寸的方法取得AE结果集,再从AE结果集中用NOT IN 的方法排除掉用SELECT TOP 页序号*页尺寸的方法取得的结果集,最后,对目标结果集执行倒序,下面是实现的代码
create PROCEDURE dbo.GetPagingRecord
(
@tablename varchar(100),--表名或视图表
@fieldlist varchar(4000)=\'*\',--欲选择字段列表
@orderfield varchar(100),--排序字段
@keyfield varchar(100),--主键
@pageindex int,--页号,从0开始
@pagesize int=20,--页尺寸
@strwhere varchar(4000),--条件
@ordertype bit=1--排序,1,降序,0,升序
)
AS
/**//*
名称:GetPagingRecord
作用:按任意字段进行排序分页
作者:菩提树(MARK MA)
时间:2004-12-14
声明:此代码你可以无偿使用及转载,但在转载时,请勿移称本文字声明
*/
SET NOCOUNT ON
declare @sqlstr varchar(6000)
--处理SQL中危险字符,并且将条件处理成易嵌入的形式
set @strwhere=replace(@strwhere,\'\'\'\',\'\'\'\'\'\')
set @strwhere=replace(@strwhere,\'--\',\'\')
set @strwhere=replace(@strwhere,\';\',\'\')
set @sqlstr=\'declare @CurPageNum int;\'
set @sqlstr=@sqlstr+\'declare @nextpagenum int;\'
set @sqlstr=@sqlstr+\'set @curpagenum=\'+cast(@PageIndex as varchar)+\'*\'+cast(@Pagesize as varchar)+\';\'
set @sqlstr=@sqlstr+\'set @nextpagenum=\'+cast(@PageIndex+1 as varchar)+\'*\'+cast(@Pagesize as varchar)+\';\'
set @sqlstr=@sqlstr+\'declare @sqlstr varchar(6000);\'
if @ordertype=1
begin
set @sqlstr=@sqlstr+\'set @sqlstr=\'\'select \'+@fieldlist+\' from ( select top \'\'+cast(@nextpagenum as varchar)+\'\' * from
\'+@tablename+\' where \'+@strwhere+\' order by \'+@orderfield+\' desc ) as a where \'+@keyfield+\' not in (
select top \'\'+cast(@curpagenum as varchar)+\'\' \'+@keyfield+\' from \'+@tablename+\' where \'+@strwhere+\'
order by \'+@orderfield+\' desc) order by \'+@orderfield+\' desc\'\';\'
end
else
begin
set @sqlstr=@sqlstr+\'set @sqlstr=\'\'select \'+@fieldlist+\' from ( select top \'\'+cast(@nextpagenum as varchar)+\'\' * from
\'+@tablename+\' where \'+@strwhere+\' order by \'+@orderfield+\' asc ) as a where \'+@keyfield+\' not in (
select top \'\'+cast(@curpagenum as varchar)+\'\' \'+@keyfield+\' from \'+@tablename+\' where \'+@strwhere+\'
order by \'+@orderfield+\' asc) order by \'+@orderfield+\' asc\'\';\'
end
set @sqlstr=@sqlstr+\'execute( @sqlstr)\'
--print @sqlstr
execute(@sqlstr)
需要注意的是,如果要避免SQL注入式攻击,请注意处理像分号,双减号,单引号这些在SQL中有特殊含义的字符
至于上面两个存储过程哪个性能更好,那就取决于是对一个倒序的结果集再进入一次反序排列好呢,还是用NOT IN从一个大的结果集移除一个小的结果集好
希望对大家有帮助
如果需要转载,请标明出处,勿删减内容
Powered By 菩提树