Sql Server 分页存储过程
分页存储过程一:
--/*-----存储过程 分页处理 孙伟 2005-03-28创建 -------*/
--/*----- 对数据进行了2分处理使查询前半部分数据与查询后半部分数据性能相同 -------*/
--/*-----存储过程 分页处理 孙伟 2005-04-21修改 添加Distinct查询功能-------*/
--/*-----存储过程 分页处理 孙伟 2005-05-18修改 多字段排序规则问题-------*/
--/*-----存储过程 分页处理 孙伟 2005-06-15修改 多字段排序修改-------*/
--/*-----存储过程 分页处理 孙伟 2005-12-13修改 修改数据分页方式为top max模式性能有极大提高-------*/
--/*-----缺点:相对之前的not in版本主键只能是整型字段,如主键为GUID类型请使用not in 模式的版本-------*/
CREATE PROCEDURE dbo.proc_ListPageInt
(
@tblName nvarchar(200), ----要显示的表或多个表的连接
@fldName nvarchar(500) = "*", ----要显示的字段列表
@pageSize int = 10, ----每页显示的记录个数
@page int = 1, ----要显示那一页的记录
@pageCount int = 1 output, ----查询结果分页后的总页数
@Counts int = 1 output, ----查询到的记录数
@fldSort nvarchar(200) = null, ----排序字段列表或条件
@Sort bit = 0, ----排序方法,0为升序,1为降序(如果是多字段排列Sort指代最后一个排序字段的排列顺序(最后一个排序字段不加排序标记)--程序传参如:" SortA Asc,SortB Desc,SortC ")
@strCondition nvarchar(1000) = null, ----查询条件,不需where
@ID nvarchar(150), ----主表的主键
@Dist bit = 0 ----是否添加查询字段的 DISTINCT 默认0不添加/1添加
)
AS
SET NOCOUNT ON
Declare @sqlTmp nvarchar(1000) ----存放动态生成的SQL语句
Declare @strTmp nvarchar(1000) ----存放取得查询结果总数的查询语句
Declare @strID nvarchar(1000) ----存放取得查询开头或结尾ID的查询语句
Declare @strSortType nvarchar(10) ----数据排序规则A
Declare @strFSortType nvarchar(10) ----数据排序规则B
Declare @SqlSelect nvarchar(50) ----对含有DISTINCT的查询进行SQL构造
Declare @SqlCounts nvarchar(50) ----对含有DISTINCT的总数查询进行SQL构造
if @Dist = 0
begin
set @SqlSelect = "select "
set @SqlCounts = "Count(*)"
end
else
begin
set @SqlSelect = "select distinct "
set @SqlCounts = "Count(DISTINCT "+@ID+")"
end
if @Sort=0
begin
set @strFSortType=" ASC "
set @strSortType=" DESC "
end
else
begin
set @strFSortType=" DESC "
set @strSortType=" ASC "
end
--------生成查询语句--------
--此处@strTmp为取得查询结果数量的语句
if @strCondition is null or @strCondition="" --没有设置显示条件
begin
set @sqlTmp = @fldName + " From " + @tblName
set @strTmp = @SqlSelect+" @Counts="+@SqlCounts+" FROM "+@tblName
set @strID = " From " + @tblName
end
else
begin
set @sqlTmp = + @fldName + "From " + @tblName + " where (1>0) " + @strCondition
set @strTmp = @SqlSelect+" @Counts="+@SqlCounts+" FROM "+@tblName + " where (1>0) " + @strCondition
set @strID = " From " + @tblName + " where (1>0) " + @strCondition
end
----取得查询结果总数量-----
exec sp_executesql @strTmp,N"@Counts int out ",@Counts out
declare @tmpCounts int
if @Counts = 0
set @tmpCounts = 1
else
set @tmpCounts = @Counts
--取得分页总数
set @pageCount=(@tmpCounts+@pageSize-1)/@pageSize
/**//**当前页大于总页数 取最后一页**/
if @page>@pageCount
set @page=@pageCount
--/*-----数据分页2分处理-------*/
declare @pageIndex int --总数/页大小
declare @lastcount int --总数%页大小
set @pageIndex = @tmpCounts/@pageSize
set @lastcount = @tmpCounts%@pageSize
if @lastcount > 0
set @pageIndex = @pageIndex + 1
else
set @lastcount = @pagesize
--//***显示分页
if @strCondition is null or @strCondition="" --没有设置显示条件
begin
if @pageIndex<2 or @page<=@pageIndex / 2 + @pageIndex % 2 --前半部分数据处理
begin
if @page=1
set @strTmp=@SqlSelect+" top "+ CAST(@pageSize as VARCHAR(4))+" "+ @fldName+" from "+@tblName
+" order by "+ @fldSort +" "+ @strFSortType
else
begin
set @strTmp=@SqlSelect+" top "+ CAST(@pageSize as VARCHAR(4))+" "+ @fldName+" from "+@tblName
+" where "+@ID+" <(select min("+ @ID +") from ("+ @SqlSelect+" top "+ CAST(@pageSize*(@page-1) as Varchar(20)) +" "+ @ID +" from "+@tblName
+" order by "+ @fldSort +" "+ @strFSortType+") AS TBMinID)"
+" order by "+ @fldSort +" "+ @strFSortType
end
end
else
begin
set @page = @pageIndex-@page+1 --后半部分数据处理
if @page <= 1 --最后一页数据显示
set @strTmp=@SqlSelect+" * from ("+@SqlSelect+" top "+ CAST(@lastcount as VARCHAR(4))+" "+ @fldName+" from "+@tblName
+" order by "+ @fldSort +" "+ @strSortType+") AS TempTB"+" order by "+ @fldSort +" "+ @strFSortType
else
set @strTmp=@SqlSelect+" * from ("+@SqlSelect+" top "+ CAST(@pageSize as VARCHAR(4))+" "+ @fldName+" from "+@tblName
+" where "+@ID+" >(select max("+ @ID +") from("+ @SqlSelect+" top "+ CAST(@pageSize*(@page-2)+@lastcount as Varchar(20)) +" "+ @ID +" from "+@tblName
+" order by "+ @fldSort +" "+ @strSortType+") AS TBMaxID)"
+" order by "+ @fldSort +" "+ @strSortType+") AS TempTB"+" order by "+ @fldSort +" "+ @strFSortType
end
end
else --有查询条件
begin
if @pageIndex<2 or @page<=@pageIndex / 2 + @pageIndex % 2 --前半部分数据处理
begin
if @page=1
set @strTmp=@SqlSelect+" top "+ CAST(@pageSize as VARCHAR(4))+" "+ @fldName+" from "+@tblName
+" where 1=1 " + @strCondition + " order by "+ @fldSort +" "+ @strFSortType
else
begin
set @strTmp=@SqlSelect+" top "+ CAST(@pageSize as VARCHAR(4))+" "+ @fldName+" from "+@tblName
+" where "+@ID+" <(select min("+ @ID +") from ("+ @SqlSelect+" top "+ CAST(@pageSize*(@page-1) as Varchar(20)) +" "+ @ID +" from "+@tblName
+" where (1=1) " + @strCondition +" order by "+ @fldSort +" "+ @strFSortType+") AS TBMinID)"
+" "+ @strCondition +" order by "+ @fldSort +" "+ @strFSortType
end
end
else
begin
set @page = @pageIndex-@page+1 --后半部分数据处理
if @page <= 1 --最后一页数据显示
set @strTmp=@SqlSelect+" * from ("+@SqlSelect+" top "+ CAST(@lastcount as VARCHAR(4))+" "+ @fldName+" from "+@tblName
+" where (1=1) "+ @strCondition +" order by "+ @fldSort +" "+ @strSortType+") AS TempTB"+" order by "+ @fldSort +" "+ @strFSortType
else
set @strTmp=@SqlSelect+" * from ("+@SqlSelect+" top "+ CAST(@pageSize as VARCHAR(4))+" "+ @fldName+" from "+@tblName
+" where "+@ID+" >(select max("+ @ID +") from("+ @SqlSelect+" top "+ CAST(@pageSize*(@page-2)+@lastcount as Varchar(20)) +" "+ @ID +" from "+@tblName
+" where (1=1) "+ @strCondition +" order by "+ @fldSort +" "+ @strSortType+") AS TBMaxID)"
+" "+ @strCondition+" order by "+ @fldSort +" "+ @strSortType+") AS TempTB"+" order by "+ @fldSort +" "+ @strFSortType
end
end
------返回查询结果-----
exec sp_executesql @strTmp
--print @strTmp
SET NOCOUNT OFF
GO 怎么在数据库中测试呢?
declare @pageCount int declare @Counts int exec [dbo].[proc_ListPageInt] "sysobjects", "* ", 20,1,@pageCount output,@Counts output,"id", 0,"","id",0 print @pageCount --这个可有可无 print @Counts --这个可有可无
执行效果如下:
分页存储过程二:
USE [JianKunKingTestDatabase001]
GO
/****** Object: StoredProcedure [dbo].[A_P_HelpPageShow] Script Date: 01/21/2015 19:19:42 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[A_P_HelpPageShow]
(
@tblName nvarchar(max), -- 表名
@strGetFields varchar(1000) = "*", -- 需要返回的列
@fldName varchar(255)="", -- 排序的字段名
@PageSize int = 10, -- 页尺寸
@PageIndex int = 1, -- 页码
@OrderType bit = 0, -- 设置排序类型, 非 0 值则降序
@strWhere varchar(1500) = "", -- 查询条件 (注意: 不要加 where)
@Counts int = 0 output --查询到的记录数
)
AS
declare @strSQL nvarchar(4000) -- 主语句
declare @strTmp nvarchar(110) -- 临时变量
declare @strOrder nvarchar(400) -- 排序类型
declare @totalRecord int --查询到的记录数
declare @SqlCounts nvarchar(max) ----对总数查询进行SQL构造
--计算总记录数
begin
if @strWhere !=""
set @SqlCounts = "select @totalRecord=count(*) from " + @tblName + " where "+@strWhere
else
set @SqlCounts = "select @totalRecord=count(*) from " + @tblName + ""
end
--print @strWhere
--print @SqlCounts
exec sp_executesql @SqlCounts,N"@totalRecord int OUTPUT",@totalRecord OUTPUT--计算总记录数
set @Counts=@totalRecord
begin
if @OrderType != 0
begin
set @strTmp = "<(select min"
set @strOrder = " order by " + @fldName +" desc"
--如果@OrderType不是0,就执行降序,这句很重要!
end
else
begin
set @strTmp = ">(select max"
set @strOrder = " order by " + @fldName +" asc"
end
--print @strOrder
if @PageIndex = 1
begin
if @strWhere != ""
set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ " from " + @tblName + " where " + @strWhere + " " + @strOrder
else
set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ " from "+ @tblName + " "+ @strOrder
--如果是第一页就执行以上代码,这样会加快执行速度
end
else
begin
--以下代码赋予了@strSQL以真正执行的SQL代码
set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ " from "
+ @tblName + " where " + @fldName + " " + @strTmp + "("+ @fldName + ") from (select top " + str((@PageIndex-1)*@PageSize) + " "+ @fldName + " from " + @tblName + " " + @strOrder + ") as tblTmp)"+ @strOrder
--print @strSQL
if @strWhere != ""
set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ " from "
+ @tblName + " where " + @fldName + " " + @strTmp + "("
+ @fldName + ") from (select top " + str((@PageIndex-1)*@PageSize) + " "
+ @fldName + " from " + @tblName + " where " + @strWhere + " "
+ @strOrder + ") as tblTmp) and " + @strWhere + " " + @strOrder
end
end
--print @strSQL
exec sp_executesql @strSQL
GO 怎么在数据库中测试呢?
select count(*) from sysobjects ; declare @CountsAA int exec [dbo].[A_P_HelpPageShow] "sysobjects", "* ", "id ",20, 1,1, " ",@CountsAA output print @CountsAA --这个可有可无
执行结果如下:
存储过程二(优化版)
USE [JianKunKingTestDatabase001]
GO
/****** Object: StoredProcedure [dbo].[A_P_HelpPageShow] Script Date: 01/30/2015 20:21:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[A_P_HelpPageShow]
(
@TableName nvarchar(max), -- 表名
@strGetFields varchar(1000) = "*", -- 需要返回的列
@OrderField varchar(255)="", -- 排序的字段名
@PageSize int = 10, -- 页尺寸
@PageIndex int = 1, -- 页码
@strWhere varchar(1500) = "", -- 查询条件 (注意: 不要加 where)
@Counts int = 0 output --查询到的记录数
)
AS
declare @strSQL nvarchar(4000) -- 主语句
declare @totalRecord int --查询到的记录数
declare @SqlCounts nvarchar(max) ----对总数查询进行SQL构造
--计算总记录数
begin
if @strWhere !=""
set @SqlCounts = "select @totalRecord=count(*) from " + @TableName + " where "+@strWhere
else
set @SqlCounts = "select @totalRecord=count(*) from " + @TableName + ""
end
exec sp_executesql @SqlCounts,N"@totalRecord int OUTPUT",@totalRecord OUTPUT--计算总记录数
set @Counts=@totalRecord
BEGIN
IF (@strWhere="" or @strWhere IS NULL)
SET @strSQL = "Select * FROM (select " + @strGetFields + ",ROW_NUMBER() Over(order by " + @OrderField + ") as rowId from " + @TableName
ELSE
SET @strSQL = "Select * FROM (select " + @strGetFields + ",ROW_NUMBER() Over(order by " + @OrderField + ") as rowId from " + @TableName + " where " + @strWhere
END
--处理页数超出范围情况
IF @PageIndex<=0
SET @PageIndex = 1
--处理开始点和结束点
DECLARE @StartRecord INT
DECLARE @EndRecord int
SET @StartRecord = (@pageIndex-1)*@PageSize + 1
SET @EndRecord = @StartRecord + @PageSize - 1
--继续合成sql语句
SET @strSQL = @strSQL + ") as tempTable where rowId >=" + CONVERT(VARCHAR(50),@StartRecord) + " and rowid<= " + CONVERT(VARCHAR(50),@EndRecord)
exec sp_executesql @strSQL
GO
拓展:http://blog.csdn.net/jiankunking/article/details/43339301
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
- 上一篇: Sql Server 查询表中各列名称、表中列数
- 下一篇:没有了
