求:关于分页显示的存储过程代码. 急!!!

sunon 2003-08-15 03:57:46
经常看到有这么一个分页的代码:

declare @SQLStr varchar(8000)
set @SQLStr='SELECT Top '+cast(@每页大小 as varchar)+' * FROM 表 WHERE 主键列 NOT IN (SELECT TOP '+cast(@每页大小*@第几页 as varchar)+' 主键列 from 表 )'
exec(@SQLStr)

但是,我的分页存储过程有好几个条件.哪应怎么写呀!

以下为我的存储过程输入参数:

CREATE PROCEDURE [SearchNewCar]
(
@Keyword [nvarchar](50)=null,
@keyMakeCode [nvarchar](3)=null,
@keyModelCode [nvarchar](6)=null,
@ProvinceCode [nvarchar](2)=null,
@CityCode [nvarchar](4)=null,
@MinPrice [money],
@MaxPrice [money],
@KeySpeedClass [nvarchar](10)=null,
--以上为数据库中的字段去'@'
@Sort [char](4)=null, //这是一个按 @Price 字段升/降排序,值为: "Desc" or "ASC"
@page [int],
@pagesize [int],
)
AS
...全文
48 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
ghostzxp 2004-03-16
  • 打赏
  • 举报
回复
zjcxc 元老 2004-03-10
  • 打赏
  • 举报
回复

更多的参考我的贴子:

查询第X页,每页Y条记录
http://expert.csdn.net/Expert/topic/2365/2365596.xml?temp=.8605615
zjcxc 元老 2004-03-10
  • 打赏
  • 举报
回复
/*--实现分页的通用存储过程

显示指定表、视图、查询结果的第X页
对于表中主键或标识列的情况,直接从原表取数查询,其它情况使用临时表的方法
如果视图或查询结果中有主键,不推荐此方法
如果使用查询语句,而且查询语句使用了order by,则查询语句必须包含top 语句

--邹建 2003.09--*/

/*--调用示例
exec p_show '地区资料'

exec p_show 'select top 100 percent * from 地区资料 order by 地区名称',5,3,'地区编号,地区名称,助记码'
--*/

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_show]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[p_show]
GO

CREATE Proc p_show
@QueryStr nvarchar(4000), --表名、视图名、查询语句
@PageSize int=10, --每页的大小(行数)
@PageCurrent int=1, --要显示的页
@FdShow nvarchar (4000)='', --要显示的字段列表,如果查询结果有标识字段,需要指定此值,且不包含标识字段
@FdOrder nvarchar (1000)='' --排序字段列表
as
declare @FdName nvarchar(250) --表中的主键或表、临时表中的标识列名
,@Id1 varchar(20),@Id2 varchar(20) --开始和结束的记录号
,@Obj_ID int --对象ID
--表中有复合主键的处理
declare @strfd nvarchar(2000) --复合主键列表
,@strjoin nvarchar(4000) --连接字段
,@strwhere nvarchar(2000) --查询条件


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=1
begin
select @Id1=cast(@PageSize as varchar(20))
exec('select top '+@Id1+@FdShow+' from '+@QueryStr+@FdOrder)
return
end

--如果是表,则检查表中是否有标识更或主键
if @Obj_ID is not null and objectproperty(@Obj_ID,'IsTable')=1
begin
select @Id1=cast(@PageSize as varchar(20))
,@Id2=cast((@PageCurrent-1)*@PageSize as varchar(20))

select @FdName=name from syscolumns where id=@Obj_ID and status=0x80
if @@rowcount=0 --如果表中无标识列,则检查表中是否有主键
begin
if not exists(select 1 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>1 --检查表中的主键是否为复合主键
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,2,2000)
,@strjoin=substring(@strjoin,5,4000)
,@strwhere=substring(@strwhere,5,4000)
goto lbusepk
end
end
end
else
goto lbusetemp

/*--使用标识列或主键为单一字段的处理方法--*/
lbuseidentity:
exec('select top '+@Id1+@FdShow+' from '+@QueryStr
+' where '+@FdName+' not in(select top '
+@Id2+' '+@FdName+' from '+@QueryStr+@FdOrder
+')'+@FdOrder
)
return

/*--表中有复合主键的处理方法--*/
lbusepk:
exec('select '+@FdShow+' from(select top '+@Id1+' a.* from
(select top 100 percent * from '+@QueryStr+@FdOrder+') a
left join (select top '+@Id2+' '+@strfd+'
from '+@QueryStr+@FdOrder+') b on '+@strjoin+'
where '+@strwhere+') a'
)
return

/*--用临时表处理的方法--*/
lbusetemp:
select @FdName='[ID_'+cast(newid() as varchar(40))+']'
,@Id1=cast(@PageSize*(@PageCurrent-1) as varchar(20))
,@Id2=cast(@PageSize*@PageCurrent-1 as varchar(20))

exec('select '+@FdName+'=identity(int,0,1),'+@FdShow+'
into #tb from'+@QueryStr+@FdOrder+'
select '+@FdShow+' from #tb where '+@FdName+' between '
+@Id1+' and '+@Id2
)

GO
lufly2000 2004-03-10
  • 打赏
  • 举报
回复
只是这个:

select top 10 * from isto where ty like 'W40%' and nnoid not in
(select top 10 nnoid from isto where ty like 'W40%')

上面那句是比较结果.
lufly2000 2004-03-10
  • 打赏
  • 举报
回复
总觉得上面的回复都不是楼主要的.

select * from isto where ty like 'W40%'
select top 10 * from isto where ty like 'W40%' and nnoid not in
(select top 10 nnoid from isto where ty like 'W40%')

okgoodsun 2003-09-16
  • 打赏
  • 举报
回复
pengdali(大力 V2.0)介绍的存储过程的方法有productID得比较,那如果我的表中没有这个字段那,你不是让我对每个表都做一个存储过程吧,很麻烦的,我的意思是说,有没有能做得很通用的方法,像用mysql中limit的语法一样的?
okgoodsun 2003-09-16
  • 打赏
  • 举报
回复
再有,这么多方法,理论上都行,但那个效率更高纳,我觉得这在数据库运用中挺重要的,那个高手做过比较?
okgoodsun 2003-09-16
  • 打赏
  • 举报
回复
我觉得做一个分页的程序应该通用,像这个
select IDENTITY(int, 1,1) AS ID_Num,* into #temp from 表
select * from #temp where ID_Num between 10 and 20
我觉得不足够好,一旦碰到表中有标示字段就不行了
tds007 2003-08-27
  • 打赏
  • 举报
回复
上面已经回答的很详细了干嘛还不结帖呢?
txlicenhe 2003-08-25
  • 打赏
  • 举报
回复
up
lynx1111 2003-08-25
  • 打赏
  • 举报
回复
up
linhaibo 2003-08-24
  • 打赏
  • 举报
回复
我把 text 型 的字段放在最后,居然就可以了,,怪
linhaibo 2003-08-24
  • 打赏
  • 举报
回复
在分页的时候,如果查询的字段有 text 型的,好象显示不出来啊
CrazyFor 2003-08-21
  • 打赏
  • 举报
回复
查询N-M条记录。
select IDENTITY(int,1,1) as iid,* into #temptable from yourtable
select top M-N * from #temptable where iid>=N

OR:

select top M-N * from yourTable where id not in(select top N-1 id from table)
ID为表具有唯一值的任何字段
zjcxc 元老 2003-08-21
  • 打赏
  • 举报
回复
/*
用存储过程实现的分页程序
*/
CREATE procedure Department_pagination
@SelectStr nvarchar(1000),
@ColumnStr nvarchar (1000),
@OrderStr nvarchar (1000),
@CurrentPage int,
@PageCount int
as
declare @TimeName nvarchar(25)
declare @TableStr nvarchar(1000)

select @TimeName = convert(nvarchar(23), getdate(), 121)
set @TimeName = REPLACE(@TimeName, '.', '')
set @TimeName = REPLACE(@TimeName, ':', '')
set @TimeName = REPLACE(@TimeName, '-', '')
set @TimeName = REPLACE(@TimeName, ' ', '')

select @TableStr='create table ##Tab' + @TimeName + '(wb int identity,'
exec(@TableStr+@ColumnStr+')')
exec('insert into ##Tab' + @TimeName + ' ' + @SelectStr + ' order by ' + @OrderStr)
exec('select * from ##Tab' + @TimeName + ' where wb between ((' + @CurrentPage + '-1)*' + @PageCount + '+1) and ' + @CurrentPage + '*' + @PageCount + ' order by wb')
exec('drop table ##Tab' + @TimeName)
GO



参数1:select语句。2:字段列表。3:排序字段。4:当前页。5每页数目
Guizhi 2003-08-21
  • 打赏
  • 举报
回复
刚好要用到,谢.

mark
smsky530 2003-08-21
  • 打赏
  • 举报
回复
CREATE PROCEDURE TAB_BM_LIST

@Ppage int =0, ----当前页数
@Psize int = 0 , -----每页记录数
@BMDEPTA int , -----目标部门
@BMDEPTB int , -----相关部门
@BMCHECK int , -----是否审核
@BMSDATE datetime , -----开始日期
@BMEDATE datetime , -----结束日期
@BMTYPE int

AS

set nocount on

-----------搜索条件

declare @StrWhere1 varchar(5000)
declare @StrWhere2 varchar(5000)
declare @StrWhere3 varchar(5000)
declare @StrWhere4 varchar(5000)
declare @StrWhAll varchar(5000)


select @StrWhere1=' where BMTYPE='+rtrim(@BMTYPE)+' and BMWDATE between '''+rtrim(@BMSDATE)+''' and '''+rtrim(@BMEDATE)+''''
--select @StrWhere1=' where BMNO like ''%'+rtrim(@Key)+'%'' ' ---------货号
select @StrWhere2=case @BMDEPTA when 0 then '' else ' and BMDEPTA='+rtrim(@BMDEPTA) end --
select @StrWhere3=case @BMDEPTB when 0 then '' else ' and BMDEPTB='+rtrim(@BMDEPTB) end --
select @StrWhere4=case @BMCHECK when 0 then '' else ' and BMCHECK='+rtrim(@BMCHECK) end --
select @StrWhAll=@StrWhere1+@StrWhere2+@StrWhere3+@StrWhere4
-----------搜索条件结束


----------------得到符合条件的记录总数
declare @WhAllcount varchar(5000)
declare @StrAllCount varchar(5000)
declare @AllCount int

select @WhAllcount='declare curr cursor for select count(*) from TAB_BM '+rtrim(@StrWhAll)+ ' '
exec( @WhAllcount)
open curr
fetch next from curr into @AllCount
close curr
deallocate curr
----------------得到符合条件的记录总数结束
declare @timenow datetime
select @timenow=getdate()+10000

----select @timenow

select @StrAllCount='select 单据编号=-1,目标部门='+rtrim(@AllCount)+' , 相关部门=-1,单据类型=-1,填单人=-1,填单日期='''+rtrim(@timenow)+''',审核人=-1,审核日期=-1,单据备用=''-1'',出入标志=-1,审核标志=-1,凭证号=''-1'',结存标志=-1,关联单据号=-1,备用整数=-1,备用小数=-1'

--select @StrAllCount

------------------------------------------------
if @AllCount>0
BEGIN
----------查询表
declare @CurExec varchar(5000)
declare @StdRec int,@EndRec int
declare @aa int
declare @bb int
declare @tmpno int

select @CurExec='declare cro_fastread cursor scroll for select BMID from TAB_BM '+rtrim(@StrWhAll)+' order by BMID desc' --这里定义游标操作,但是不用临时纪录集,而且游标也不需要全部遍历所有纪录集。
exec(@CurExec)
open cro_fastread --打开游标

select @aa=(@Ppage-1)*@Psize+1 ---------得出该页的第一个纪录Id
select @bb =(@Ppage-1)*@Psize+@Psize -----------------得出该页的最后一个纪录的Id

fetch absolute @aa from cro_fastread into @StdRec --------------- 将他的Id传给一个变量该页开始的Id
fetch absolute @bb from cro_fastread into @EndRec
fetch last from cro_fastread into @tmpno --直接将游标绝对定位到最后一条纪录,得出他的id号来
select @EndRec=isnull(@EndRec,@tmpno) --这里要注意,如果某一页不足固定页数的纪录时。如只有一页纪录,而且纪录少于我们定义的数目。或者是最后一页时。。。
close cro_fastread
deallocate cro_fastread

-----------------CTYPE,CNO,CNAME,DTYPE,DNO,DNAME,PRODEPT,DLDEPT
declare @StrSec1 varchar(5000)
declare @StrSec2 varchar(5000)
declare @StrSec3 varchar(5000)
declare @StrAll varchar(5000)

select @StrSec1='select BMID,BMDEPTA,BMDEPTB,BMTYPE,BMWMAN,BMWDATE,BMCMAN,BMCDATE,BMNOTE,BMSIGN,BMCHECK,BMNO,BMEND,BMRELA,BMBAKINT,BMBAKSNG from TAB_BM '
select @StrSec2=' and BMID between '+rtrim(@EndRec)+' and '+rtrim(@StdRec)+' '
select @StrSec3=' order by 填单日期 desc'
select @StrAll=@StrSec1+@StrWhAll+@StrSec2+@StrSec3
--------查询TAB_PRO结束

----------联合查询

exec(@StrAllCount+' union '+@StrAll)
END

else

BEGIN
exec(@StrAllCount)
END
GO


不知道你能不能用得到
自己看吧!
childish 2003-08-20
  • 打赏
  • 举报
回复
mark
lynx1111 2003-08-15
  • 打赏
  • 举报
回复
UP
lynx1111 2003-08-15
  • 打赏
  • 举报
回复
严重MARK!
加载更多回复(3)

34,874

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧