数据库

位置:IT落伍者 >> 数据库 >> 浏览文章

分页SQLServer存储过程


发布日期:2018年08月18日
 
分页SQLServer存储过程

/*用存储过程实现的分页程序

显示指定表视图查询结果的第X页

对于表中主键或标识列的情况直接从原表取数查询其它情况使用临时表的方法

如果视图或查询结果中有主键不推荐此方法*/

/*调用示例

exec p_show 地区资料

exec p_show 地区资料地区编号地区名称助记码地区编号

*/

/*

因为要顾及通用性所以对带排序的查询语句有一定要求如果先排序再出结果就是:

exec p_show select top percent * from 地区资料 order by 地区名称地区编号地区名称助记码地区名称

查询语句加上:top percent //top时

*/

if exists (select * from dbosysobjects where id = object_id(N[dbo][p_show]) and OBJECTPROPERTY(id NIsProcedure) = )

drop procedure [dbo][p_show]

GO

CREATE Proc p_show

@QueryStr nvarchar() 表名视图名查询语句

@PageSize int= 每页的大小(行数)

@PageCurrent int= 要显示的页

@FdShow nvarchar ()= 要显示的字段列表如果查询结果有标识字段需要指定此值且不包含标识字段

@FdOrder nvarchar ()= 排序字段列表

as

declare @FdName nvarchar() 表中的主键或表临时表中的标识列名

@Id varchar()@Id varchar() 开始和结束的记录号

@Obj_ID int 对象ID

表中有复合主键的处理

declare @strfd nvarchar() 复合主键列表

@strjoin nvarchar() 连接字段

@strwhere nvarchar() 查询条件

select @Obj_ID=object_id(@QueryStr)

@FdShow=case isnull(@FdShow) when then * else

+@FdShow

end

@FdOrder=case isnull(@FdOrder) when then else order by

+@FdOrder

end

@QueryStr=case when @Obj_ID is not null then

+@QueryStr

else (

+@QueryStr+

) a end

如果显示第一页可以直接用top来完成

if @PageCurrent=

begin

select @Id=cast(@PageSize as varchar())

exec(select top

+@Id+@FdShow+

from

+@QueryStr+@FdOrder

)

return

end

如果是表则检查表中是否有标识更或主键

if @Obj_ID is not null and objectproperty(@Obj_IDIsTable)=

begin

select @Id=cast(@PageSize as varchar())

@Id=cast((@PageCurrent)*@PageSize as varchar())

select @FdName=name from syscolumns where

id=@Obj_ID

and status=x

if @@rowcount= 如果表中无标识列则检查表中是否有主键

begin

if not exists(select from sysobjects where

parent_obj=@Obj_ID

and xtype=PK)

goto lbusetemp 如果表中无主键则用临时表处理

select @FdName=name from syscolumns where

id=@Obj_ID

and colid in(

select colid from sysindexkeys where @Obj_ID=id and indid in(

select indid from sysindexes where @Obj_ID=id and name in(

select name from sysobjects where xtype=PK and

parent_obj=@Obj_ID

)))

if @@rowcount> 检查表中的主键是否为复合主键

begin

select @strfd=@strjoin=@strwhere=

select @strfd=@strfd+[+name+]

@strjoin=@strjoin+ and a[+name+]=b[+name+]

@strwhere=@strwhere+ and b[+name+] is null

from syscolumns where

id=@Obj_ID

and colid in(

select colid from sysindexkeys where @Obj_ID=id and indid in(

select indid from sysindexes where @Obj_ID=id and name in(

select name from sysobjects where xtype=PK and

parent_obj=@Obj_ID

)))

select @strfd=substring(@strfd)

@strjoin=substring(@strjoin)

@strwhere=substring(@strwhere)

goto lbusepk

end

end

end

else

goto lbusetemp

/*使用标识列或主键为单一字段的处理方法*/

lbuseidentity:

exec(select top

+@Id+@FdShow+

from

+@QueryStr

+ where

+@FdName+

not in(select top

+@Id+

+@FdName+

from

+@QueryStr+@FdOrder

+)+@FdOrder

)

return

/*表中有复合主键的处理方法*/

lbusepk:

exec(select

+@FdShow+

from(select top

+@Id+

a* from

(select top percent * from

+@QueryStr+@FdOrder+

) a

left join (select top

+@Id+

+@strfd+

from

+@QueryStr+@FdOrder+

) b on

+@strjoin+

where

+@strwhere+

) a

)

return

/*用临时表处理的方法*/

lbusetemp:

select @FdName=[ID_+cast(newid() as varchar())+]

@Id=cast(@PageSize*(@PageCurrent) as varchar())

@Id=cast(@PageSize*@PageCurrent as varchar())

exec(select

+@FdName+=identity(int)+@FdShow+

into #tb

from+@QueryStr+@FdOrder+

select

+@FdShow+

from #tb where

+@FdName+

between

+@Id+

and

+@Id

)

GO

               

上一篇:SQLServer2005与DB28.2之对比

下一篇:如何使SQL Server的日志文件不会增大