在儲存過程中分頁

2021-04-01 18:14:21 字數 3923 閱讀 3459

/*--用儲存過程實現的分頁程式

--鄒建 2003.09(引用請保留此資訊)--*/

/*--呼叫示例

exec p_show '地區資料'

exec p_show '地區資料',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]

gocreate proc p_show

@querystr nvarchar(4000), --表名、檢視名、查詢語句

@pagesize int=10,   --每頁的大小(行數)

@pagecurrent int=1,   --要顯示的頁

@fdshow nvarchar (4000)='', --要顯示的字段列表,如果查詢結果有標識字段,需要指定此值,且不包含標識字段

@fdorder nvarchar (1000)='' --排序字段列表

asdeclare @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

endend

endelse

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

在儲存過程中排序分頁

在專案中,會遇到查詢出的結果排序分頁的問題,可以有多種解決方法,乙個是利用開發工具提供的方法,例如.net visual studio中的gridview,就提供了排序,分頁功能。但如果情況複雜,我們可以把排序分頁放到儲存過程來完成。以乙個簡單例子來說明問題 table reportfile fie...

Sql2005中分頁儲存過程

set ansi nulls on goset ansi nulls on set quoted identifier on goalter procedure pagetest tblname varchar 255 表名 fldname varchar 255 主鍵欄位名 pagesize in...

sql儲存過程中分隔字串

最近遇到了如下問題,要向使用者角色資訊表中插入資料。每個使用者有多個角色,因此每次新增使用者要新增一到多條記錄。這個過程要放到儲存過程中實現,但是儲存過程不能傳入集合。解決思路是,將角色id集合轉成用逗號分隔的字串,在儲存過程中分隔。那麼儲存過程中如何分隔字串呢?因為sql中沒有split函式,所以...