您的位置:首页 > 其它

常用的分页存储过程

2011-05-10 13:47 495 查看
SQL分页存储过程:

CREATEPROCEDURE[dbo].[ProcCustomPage]
(
@tbnamenvarchar(100),--要分页显示的表名
@FieldKeynvarchar(1000),--用于定位记录的主键(惟一键)字段,可以是逗号分隔的多个字段
@PageCurrentint=1,--要显示的页码
@PageSizeint=10,--每页的大小(记录数)
@FieldShownvarchar(1000)='',--以逗号分隔的要显示的字段列表,如果不指定,则显示所有字段
@FieldOrdernvarchar(1000)='',--以逗号分隔的排序字段列表,可以指定在字段后面指定DESC/ASC
@WhereStringnvarchar(1000)='',--查询条件
@RecordCountintOUTPUT--总记录数
)
AS
SETNOCOUNTON

--分页字段检查
IFISNULL(@FieldKey,N'')=''
BEGIN
RAISERROR(N'分页处理需要主键(或者惟一键)',1,16)
RETURN
END

--其他参数检查及规范
IFISNULL(@PageCurrent,0)<1SET@PageCurrent=1
IFISNULL(@PageSize,0)<1SET@PageSize=10
IFISNULL(@FieldShow,N'')=N''SET@FieldShow=N'*'
IFISNULL(@FieldOrder,N'')=N''
SET@FieldOrder=N''
ELSE
SET@FieldOrder=N'ORDERBY'+LTRIM(@FieldOrder)
IFISNULL(@WhereString,N'')=N''
SET@WhereString=N''
ELSE
SET@WhereString=N'WHERE('+@WhereString+N')'

--如果@RecordCount为NULL值,则计算总页数(这样设计可以只在第一次计算总页数,以后调用时,--把总页数传回给存储过程,避免再次计算总页数,对于不想计算总页数的处理而言,可以给@RecordCount赋值)
IF@RecordCountISNULL
BEGIN
DECLARE@sqlnvarchar(4000)
SET@sql=N'SELECT@RecordCount=COUNT(*)'
+N'FROM'+@tbname
+N''+@WhereString
EXECsp_executesql@sql,N'@RecordCountintOUTPUT',@RecordCountOUTPUT
END

--计算分页显示的TOPN值
DECLARE@TopNvarchar(20),@TopN1varchar(20)
SELECT@TopN=@PageSize,
@TopN1=(@PageCurrent-1)*@PageSize

--第一页直接显示
IF@PageCurrent=1
EXEC(N'SELECTTOP'+@TopN
+N''+@FieldShow
+N'FROM'+@tbname
+N''+@WhereString
+N''+@FieldOrder)
ELSE
BEGIN
--处理别名
IF@FieldShow=N'*'
SET@FieldShow=N'a.*'

--生成主键(惟一键)处理条件
DECLARE@Where1nvarchar(4000),@Where2nvarchar(4000),
@snvarchar(1000),@Fieldsysname
SELECT@Where1=N'',@Where2=N'',@s=@FieldKey
WHILECHARINDEX(N',',@s)>0
SELECT@Field=LEFT(@s,CHARINDEX(N',',@s)-1),
@s=STUFF(@s,1,CHARINDEX(N',',@s),N''),
@Where1=@Where1+N'ANDa.'+@Field+N'=b.'+@Field,
@Where2=@Where2+N'ANDb.'+@Field+N'ISNULL',
@WhereString=REPLACE(@WhereString,@Field,N'a.'+@Field),
@FieldOrder=REPLACE(@FieldOrder,@Field,N'a.'+@Field),
@FieldShow=REPLACE(@FieldShow,@Field,N'a.'+@Field)
SELECT@WhereString=REPLACE(@WhereString,@s,N'a.'+@s),
@FieldOrder=REPLACE(@FieldOrder,@s,N'a.'+@s),
@FieldShow=REPLACE(@FieldShow,@s,N'a.'+@s),
@Where1=STUFF(@Where1+N'ANDa.'+@s+N'=b.'+@s,1,5,N''),
@Where2=CASE
WHEN@WhereString=''THENN'WHERE('
ELSE@WhereString+N'AND('
END+N'b.'+@s+N'ISNULL'+@Where2+N')'

--执行查询
EXEC(N'SELECTTOP'+@TopN
+N''+@FieldShow
+N'FROM'+@tbname
+N'aLEFTJOIN(SELECTTOP'+@TopN1
+N''+@FieldKey
+N'FROM'+@tbname
+N'a'+@WhereString
+N''+@FieldOrder
+N')bON'+@Where1
+N''+@Where2
+N''+@FieldOrder)
END
GO


对此分页存储过程的C#封装代码:

viewsourceprint?

///<summary>
///分页获取数据列表适用于SQL2000
///</summary>
///<paramname="connectionString">连接字符串</param>
///<paramname="fieldlist">查找的字段</param>
///<paramname="tablename">表名</param>
///<paramname="where">查询条件</param>
///<paramname="orderfield">排序字段</param>
///<paramname="key">主键</param>
///<paramname="pageindex">页索引</param>
///<paramname="pagesize">每页记录数</param>
///<paramname="ordertype">排序方式0=ASC1=DESC</param>
///<paramname="recordcount">总记录数</param>
///<returns></returns>
public
static
DataTableGetPagerDataForSQL2k(
string
connectionString,
string
fieldlist,
string
tablename,
string
where,
string
orderfield,
string
key,
int
pageindex,
int
pagesize)
{
string
cmd=
"ProcCustomPage"
;
SqlParameter[]para=
new
SqlParameter[8];
para[0]=
new
SqlParameter(
"@tbname"
,tablename);
para[1]=
new
SqlParameter(
"@FieldKey"
,key);
para[2]=
new
SqlParameter(
"@WhereString"
,where);
para[3]=
new
SqlParameter(
"@PageSize"
,pagesize);
para[4]=
new
SqlParameter(
"@PageCurrent"
,pageindex);
para[5]=
new
SqlParameter(
"@FieldOrder"
,orderfield);
para[6]=
new
SqlParameter(
"@FieldShow"
,fieldlist);
para[7]=
new
SqlParameter(
"@RecordCount"
,SqlDbType.Int);
return
SqlHelper.ExecuteDataset(connectionString,CommandType.StoredProcedure,cmd,para).Tables[0];
}
使用注意事项:

表中的字段,id为主键,如:id,userid,companyid....这样在分页时会有问题哦。应将id改为productid类似于这样的xxxid这样在分页就OK,为什么要这样呢?因为如将主键设为id,分页存储过程会将userid替换为usera.id在执行时就会出错了。如果字段名称中不包括主键的字符就可以。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: