当前位置:编程学习 > C#/ASP.NET >>

求一条好用的分页mssql存储过程 谢谢!!

求一条好用的性能好的分页mssql存储过程,最好能支持表连接 非常感谢大侠们帮助!!急~~~~ --------------------编程问答-------------------- 结贴率。。
不能太楼主 --------------------编程问答-------------------- 顶楼主的结贴率:(转帖)

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go





--阿会楠sosuo8.com根据网络上的代码进行了修改,版权归原作者所有2009-4-5
--修改输出总记录数


CREATE PROCEDURE [dbo].[pagination]
@tblName varchar(255), -- 表名 
@strGetFields varchar(1000), -- 需要返回的列 
@fldName varchar(255), -- 排序的字段名 
@PageSize int, -- 页尺寸 
@PageIndex int, -- 页码 
@OrderType bit, -- 设置排序类型, 非 0 值则降序 
@strWhere varchar(1500), -- 查询条件 (注意: 不要加 where) 
@rowCount int output --查询到的记录数
AS 

declare @strSQL varchar(5000) -- 主语句 
declare @strTmp varchar(110) -- 临时变量 
declare @strOrder varchar(400) -- 排序类型 
declare @strCountTmp nvarchar(100) --记录数
declare @timediff datetime --耗时

begin
select @timediff = Getdate()
if @strWhere !='' 
set @strCountTmp = 'select @rowCount = count(*) from [' + @tblName + '] where '+@strWhere 
else 
set @strCountTmp = 'select @rowCount = rowCount_tmp from tmp where (table_tmp = ''' + @tblName +''')'

exec sp_executesql @strCountTmp,N'@rowCount int out',@rowCount out --输出总记录数

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 
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 
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 
exec (@strSQL)
select datediff(ms,@timediff,GetDate()) as runtime

--------------------编程问答-------------------- 楼上的大哥 您那个不能执行啊 建成功了 但是执行失败了 --------------------编程问答--------------------

CREATE procedure [dbo].[PageInation]
 @tblName varchar(225),--表名
 @strGetFields varchar(1000)='*',--需要返回的列
 @fldName varchar(50),--排序的字段名
 @pageSize int=3,--页尺寸
 @pageIndex int=1,--页码
 @totalCount int=0 output,--表的总记录行
 @orderType bit=0,--设置排序类型,非值为降序
 @strWhere varchar(1500)=''--查询条件(注意:不要加where)
 as
 declare @strSql varchar(5000)--主语句
 declare @strTmp varchar(110)--临时变量
 declare @strOrder varchar(400)--排序类型
 declare @sql nvarchar(500)
 declare @param nvarchar(100)

 if @strWhere=''
 begin

 set @sql=N'select @totalCount=count(*) from '+@tblName--注意:from后面必须有空格
 set @param=N'@totalCount int output'
 execute sp_executesql @sql,@param,@totalCount=@totalCount output
 end

 else
 begin

 set @sql=N'select @totalCount=count(*) from '+@tblName+'where'+@strWhere --注意:from 后面必须有空格
 set @param=N'@totalCount int output'
 execute sp_executesql @sql,@param,@totalCount=@totalCount output
 end

 if @orderType!=0--假如排序类型为降序
 begin

 set @strTmp='<(select min'
 set @strOrder='order by ['+@fldName+'] desc'
 end

 else--否则排序类型为升序
 begin
 set @strTmp='>(select max'
 set @strOrder='order by '+@fldName+' asc'
 end


 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代码
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+' '+@strOrder+') as tblTmp)' + @strOrder
else
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

exec (@strSql)

--------------------编程问答--------------------

/*===============================================

declare @PageCount int,@TotalRecord int

exec SYS_PageData 'SELECT  * FROM tb'  , 1 ,10,@PageCount out,@TotalRecord out
select @PageCount,@TotalRecord
===============================================*/



CREATE   PROCEDURE   SYS_PageData
(
@SqlCommandText   nvarchar(4000),
@CurrentPage   int,   -- 頁次
@PageSize   int,   -- 行數
@PageCount int out ,
@TotalRecord int out
)
AS   
set   nocount   on   
DECLARE
@P1 int,   --P1是游標的id   
@rowcount int   

SET @SqlCommandText=replace(replace(replace(replace(replace(replace(replace(replace(@SqlCommandText,'exec ',''),'insert ',''),'delete ',''),'update ',''),'drop ',''),'alter ',''),'chr(',''),'mid(','')

exec   sp_cursoropen   @P1  output ,@SqlCommandText,@scrollopt=1,@ccopt=1,@rowcount=@TotalRecord   output   

-- 頁數 行數

set   @CurrentPage=(@CurrentPage-1)*@PageSize+1   
set @PageCount  =   ceiling(1.0*@TotalRecord/@PageSize) 
exec   sp_cursorfetch   @P1,16,@CurrentPage,@PageSize   

exec   sp_cursorclose   @P1   

set   nocount   off
GO


--------------------编程问答--------------------
引用 3 楼 zuochuan89 的回复:
楼上的大哥 您那个不能执行啊 建成功了 但是执行失败了

set @strCountTmp = 'select @rowCount = rowCount_tmp from tmp where (table_tmp = ''' + @tblName +''')'
 你的困惑在这里

tmp表用来存放无搜索条件时的总记录数。这里我要说下,为什么需要一个表用来专门存放总记录数,总记录数你可以在后台每隔一段时间就去更新一次,把最新的总记录数写进去。否则的话,520W的记录你每次都要用count(id)那么耗费的时间也不少。
 CREATE TABLE [dbo].[tmp](   
    [id] [int] IDENTITY(1,1) NOT NULL,   
     [rowCount_tmp] [int] NULL,   
     [table_tmp] [varchar](255) COLLATE Chinese_PRC_CI_AS NULL,   
  CONSTRAINT [PK_tmp] PRIMARY KEY CLUSTERED    
 (   
     [id] ASC  
 )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]   
 ) ON [PRIMARY]


采用aspnetpager这个控件,这个控件我们只需要传入3个值
http://sosuo8.com/article/show.asp?id=2669
--------------------编程问答--------------------

CREATE PROCEDURE [sp_Paging]
(
 @SQL nvarchar(1024) = '',   --查询语句
 @PageSize int = 20,    --分页大小
 @PageIndex int = 0,    --分页索引
 @Sort nvarchar(100) = '',    --排序字段
 @TotalCount int = 0 output --总数    
)
AS

set nocount on
/*声明查询字符串*/
declare @strSQL nvarchar(4000)

set @strSQL = ' select @TotalCount=count(*) from ('+@SQL+') as t ' 

/*取得查询结果总数*/
exec sp_executesql
@strSQL, 
N'@TotalCount int=0 OUTPUT', 
@TotalCount=@TotalCount OUTPUT 

declare @ItemCount int 
declare @_PageIndex int

set @_PageIndex = @PageIndex + 1;
/*确定搜索边界*/
set @ItemCount = @TotalCount - @PageSize * @_PageIndex

if(@ItemCount < 0) 
    set @ItemCount = @ItemCount + @PageSize 
else 
    set @ItemCount = @PageSize 

if(@ItemCount < 0) return 1 

if(@Sort != '')
begin
    /*声明排序变量*/
    declare @IndexSort1 nvarchar(50), @IndexSort2 nvarchar(50), @Sort1 nvarchar(50), @Sort2 nvarchar(50)
    
    SET @Sort1 = @Sort
    SET @Sort2 = Replace(Replace(Replace(@Sort, 'DESC', '@SORT'), 'ASC', 'DESC'), '@SORT', 'ASC')

    set @strSQL = 'SELECT * FROM 
    (SELECT TOP ' + STR(@ItemCount) + ' * FROM 
    (SELECT TOP ' + STR(@PageSize * @_PageIndex) + ' * FROM 
    ('+@SQL+') AS t0 
    ORDER BY '+@Sort1 +') AS t1 
    ORDER BY '+@Sort2 +') AS t2 
    ORDER BY ' +@Sort 
end
else
begin
    set @strSQL = 'SELECT * FROM 
    (SELECT TOP ' + STR(@ItemCount) + ' * FROM 
    (SELECT TOP ' + STR(@PageSize * @_PageIndex) + ' * FROM 
    ('+@SQL+') As t0) 
    aS t1) 
    AS t2'
end

exec sp_executesql 
@strSQL
GO

--------------------编程问答-------------------- 这结贴率也太高了。 --------------------编程问答-------------------- 你们写的存储过程 我试了 如果我要按 price这列排序 单这列价格肯定会有重复的 这样分页出来的会有很多数据没有 不准 --------------------编程问答-------------------- 简单的说 就是如果排序的列 数据存在重复的 那分完也后有可能少数据
--------------------编程问答--------------------
引用 10 楼 zuochuan89 的回复:
简单的说 就是如果排序的列 数据存在重复的 那分完也后有可能少数据

大哥,你也看看存储过程,那个排序列是数据表中可以做主键的列,这样才能取出一定位置一定数量的数据行。 --------------------编程问答-------------------- http://www.webdiyer.com
补充:.NET技术 ,  ASP.NET
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,