今天终于糊里糊涂的搞好了一个用ASP存储过程分页例子了,只是还有个问题要请教.请进来......
问题1:
这个存储过程只有一个返回总页数的输出参数,我还想要一个返回总记录数的输出参数该如何修改??
问题2:
虽然说这个存储过程可以把表名作为参数灵活套用,可实际中,更多的是对好几个表同时关联查询,那个这存储过程就好象不适用了。能否改为把整个SQL语句(包括条件过滤,排序等等)当作一个存储过程的参数?如果可以的话,该怎么样写。那样写明显可扩展性更大,可为什么不那样写呢?是不是有什么弊端?
问题3:
用存储过程分页是不是和表的主键有关?我不明白,为什么有些人说如果要显示包括主键的字段就不适用了。
谢谢啦~~(一个问题15分,答中者即给分,只是帮忙顶没有答题的或答非所问的暂不给分^_^)
原存储过程代码如下:
CREATE PROCEDURE sp_newpage
@tb varchar(50), --表名
@col varchar(50), --按该列来进行分页
@coltype int, --@col列的类型,0-数字类型,1-字符类型,2-日期时间类型
@orderby bit, --排序,0-顺序,1-倒序
@collist varchar(800),--要查询出的字段列表,*表示全部字段
@pagesize int, --每页记录数
@page int, --指定页
@condition varchar(800),--查询条件
@pages int OUTPUT --总页数
AS
/*
功能描述:对指定表中满足条件的记录按指定列进行分页查询,分页可以顺序、倒序
查询可以指定页大小、指定查询任意页、指定输出字段列表,返回总页数
作 者:pbsql
版 本:1.10
最后修改:2004-11-29
*/
DECLARE @sql nvarchar(4000),@where1 varchar(800),@where2 varchar(800)
IF @condition is null or rtrim(@condition)=''
BEGIN--没有查询条件
SET @where1=' WHERE '
SET @where2=' '
END
ELSE
BEGIN--有查询条件
SET @where1=' WHERE ('+@condition+') AND '--本来有条件再加上此条件
SET @where2=' WHERE ('+@condition+') '--原本没有条件而加上此条件
END
SET @sql='SELECT @pages=CEILING((COUNT(*)+0.0)/'+CAST(@pagesize AS varchar)+
') FROM '+@tb+@where2
EXEC sp_executesql @sql,N'@pages int OUTPUT',@pages OUTPUT--计算总页数
IF @orderby=0
SET @sql='SELECT TOP '+CAST(@pagesize AS varchar)+' '+@collist+
' FROM '+@tb+@where1+@col+'>(SELECT MAX('+@col+') '+
' FROM (SELECT TOP '+CAST(@pagesize*(@page-1) AS varchar)+' '+
@col+' FROM '+@tb+@where2+'ORDER BY '+@col+') t) ORDER BY '+@col
ELSE
SET @sql='SELECT TOP '+CAST(@pagesize AS varchar)+' '+@collist+
' FROM '+@tb+@where1+@col+'<(SELECT MIN('+@col+') '+
' FROM (SELECT TOP '+CAST(@pagesize*(@page-1) AS varchar)+' '+
@col+' FROM '+@tb+@where2+'ORDER BY '+@col+' DESC) t) ORDER BY '+
@col+' DESC'
IF @page=1--第一页
SET @sql='SELECT TOP '+CAST(@pagesize AS varchar)+' '+@collist+' FROM '+@tb+
@where2+'ORDER BY '+@col+CASE @orderby WHEN 0 THEN '' ELSE ' DESC' END
EXEC(@sql)
GO
问题点数:45、回复次数:18Top
1 楼wjhcjg(任任行)回复于 2006-06-19 17:07:48 得分 0
没人答??自己顶一下!Top
2 楼baby97(小雕(Asp→.Net中...)回复于 2006-06-19 17:11:08 得分 0
问题1:@RecordCount Int OutputTop
3 楼baby97(小雕(Asp→.Net中...)回复于 2006-06-19 17:16:12 得分 15
问题2:(本人理解性评论)
当多个表时就涉及到各表之间的关联条件。
这样,你传入存储过程的参数就不单单是表名这么简单了,还得把各表之间的关联也传进去。
个人感觉这样没有提高程序的简单明了性,反而增加了麻烦程度。
以上为个人理解性评论,如有不对请多包含。Top
4 楼baby97(小雕(Asp→.Net中...)回复于 2006-06-19 17:17:24 得分 0
问题3:我不太清楚主键和分页存储过程有什么关系。不做任何评论。Top
5 楼wjhcjg(任任行)回复于 2006-06-19 17:29:24 得分 0
问题1:@RecordCount Int Output
你是怎么加的呢,我也是加了一个输出参数,可是在执行时老说我没有申明:@RecordCount,但我明明写了 @RecordCount Int Output
所以我郁闷,请具体写一下可以吗?
Top
6 楼wjhcjg(任任行)回复于 2006-06-19 17:32:57 得分 0
问题2:
只是确定有些查询是涉及到多个表关联的,而且数剧量较大,如能用上存储过程查询和分页当然是最好的.否则用传统的标准分页数据量大了就非常慢;就是因为要传关联等条件非常麻烦,所以我想能否把一个完整的SQL语句当作参数传给存储过程执行,这样在ASP页面中生成各种复合条件的SQL语句是很容易的,如能这样的话,就简明多了.Top
7 楼wjhcjg(任任行)回复于 2006-06-20 08:53:48 得分 0
UPTop
8 楼loulou_ff(髅髅)回复于 2006-06-20 09:26:20 得分 0
问题1
http://blog.csdn.net/loulou_ff/archive/2006/04/12/660612.aspx
Top
9 楼baby97(小雕(Asp→.Net中...)回复于 2006-06-20 10:00:17 得分 0
@RecordCount Int Output,
@pages int OUTPUT --总页数
这样不可以吗?Top
10 楼gq(游子)回复于 2006-06-20 10:06:20 得分 30
问题1:
这个存储过程只有一个返回总页数的输出参数,我还想要一个返回总记录数的输出参数该如何修改??
--->
自己添加。
如
EXEC sp_executesql @sql,N'@count int OUTPUT',@count OUTPUT--计算总记录
题2:
虽然说这个存储过程可以把表名作为参数灵活套用,可实际中,更多的是对好几个表同时关联查询,那个这存储过程就好象不适用了。
-->
使用视图
问题3:
用存储过程分页是不是和表的主键有关?我不明白,为什么有些人说如果要显示包括主键的字段就不适用了。
--》
http://blog.csdn.net/lihonggen0/archive/2004/09/14/103511.aspxTop
11 楼gq(游子)回复于 2006-06-20 10:09:18 得分 0
修正:
如
SET @sql='SELECT @count=COUNT('+@col+') FROM '+@tb+@where2
EXEC sp_executesql @sql,N'@count int OUTPUT',@count OUTPUT--计算总记录
Top
12 楼liuph3000()回复于 2006-06-20 10:21:23 得分 0
markTop
13 楼wjhcjg(任任行)回复于 2006-06-20 12:01:22 得分 0
OK,分页问题已解决,我把存储过程源代码和ASP调用源代码完整列出如下(可直接用),供参考学习,等其它问题我搞好后就结贴:
存储过程源代码:
CREATE PROCEDURE sp_newpage
@tb varchar(50), --表名
@col varchar(50), --按该列来进行分页
@coltype int, --@col列的类型,0-数字类型,1-字符类型,2-日期时间类型
@orderby bit, --排序,0-顺序,1-倒序
@collist varchar(800),--要查询出的字段列表,*表示全部字段
@pagesize int, --每页记录数
@page int, --指定页
@condition varchar(800),--查询条件
@RecordCount Int Output,
@pages int OUTPUT --总页数
AS
/*
功能描述:对指定表中满足条件的记录按指定列进行分页查询,分页可以顺序、倒序
查询可以指定页大小、指定查询任意页、指定输出字段列表,返回总页数
作 者:pbsql
版 本:1.10
最后修改:2004-11-29
*/
DECLARE @sql nvarchar(4000),@where1 varchar(800),@where2 varchar(800)
IF @condition is null or rtrim(@condition)=''
BEGIN--没有查询条件
SET @where1=' WHERE '
SET @where2=' '
END
ELSE
BEGIN--有查询条件
SET @where1=' WHERE ('+@condition+') AND '--本来有条件再加上此条件
SET @where2=' WHERE ('+@condition+') '--原本没有条件而加上此条件
END
SET @sql='SELECT @pages=CEILING((COUNT(*)+0.0)/'+CAST(@pagesize AS varchar)+
') FROM '+@tb+@where2
EXEC sp_executesql @sql,N'@pages int OUTPUT',@pages OUTPUT--计算总页数
SET @sql='SELECT @RecordCount=COUNT(*) FROM '+@tb+@where2
EXEC sp_executesql @sql,N'@RecordCount int OUTPUT',@RecordCount OUTPUT--计算总记录
IF @orderby=0
SET @sql='SELECT TOP '+CAST(@pagesize AS varchar)+' '+@collist+
' FROM '+@tb+@where1+@col+'>(SELECT MAX('+@col+') '+
' FROM (SELECT TOP '+CAST(@pagesize*(@page-1) AS varchar)+' '+
@col+' FROM '+@tb+@where2+'ORDER BY '+@col+') t) ORDER BY '+@col
ELSE
SET @sql='SELECT TOP '+CAST(@pagesize AS varchar)+' '+@collist+
' FROM '+@tb+@where1+@col+'<(SELECT MIN('+@col+') '+
' FROM (SELECT TOP '+CAST(@pagesize*(@page-1) AS varchar)+' '+
@col+' FROM '+@tb+@where2+'ORDER BY '+@col+' DESC) t) ORDER BY '+
@col+' DESC'
IF @page=1--第一页
SET @sql='SELECT TOP '+CAST(@pagesize AS varchar)+' '+@collist+' FROM '+@tb+
@where2+'ORDER BY '+@col+CASE @orderby WHEN 0 THEN '' ELSE ' DESC' END
EXEC(@sql)
GO
ASP调用源代码:
<!-- #include file="ADOVBS.INC" -->
<head>
<meta http-equiv="Content-Language" content="zh-cn">
</head>
<%
set conn=server.createobject("adodb.connection")
connstr="server=192.168.0.48;uid=sa;pwd=web678sql;database=buyicdb;PROVIDER=SQLOLEDB"
'conn.open connstr
%>
<%
dim records
page=request("page")
if not isnumeric(page) then
page=1
end if
if page<1 then
page=1
end if
set rs=server.createobject("adodb.recordset")
'rs.open "sp_newpage 'insider','name',1,0,'name,company,intro',25,"&page&",'',''",conn
'records=rs("records")
Set CmdSP = Server.CreateObject("ADODB.Command")
CmdSP.ActiveConnection = connstr'MyConStr是数据库连接字串
CmdSP.CommandText = "sp_newpage" '指定存储过程名
CmdSP.CommandType = 4 '表明这是一个存储过程
CmdSP.Prepared = true '要求将SQL命令先行编译
'返回值
CmdSp.Parameters.Append CmdSp.CreateParameter("RETURN_VALUE",adInteger,adParamReturnValue,4)
'入参(表名)
CmdSp.Parameters.Append CmdSp.CreateParameter("@tb",adVarChar,adParamInput,50)
'入参(按该列来进行分页)
CmdSp.Parameters.Append CmdSp.CreateParameter("@col",adVarChar,adParamInput,50)
'入参(col列的类型,0-数字类型,1-字符类型,2-日期时间类型)
CmdSp.Parameters.Append CmdSp.CreateParameter("@coltype",adInteger,adParamInput)
'入参(排序,0-顺序,1-倒序)
CmdSp.Parameters.Append CmdSp.CreateParameter("@orderby",adInteger,adParamInput)
'入参(要查询出的字段列表,*表示全部字段)
CmdSp.Parameters.Append CmdSp.CreateParameter("@collist",adVarChar,adParamInput,800)
'入参(每页记录数)
CmdSp.Parameters.Append CmdSp.CreateParameter("@pagesize",adInteger,adParamInput)
'入参(指定页)
CmdSp.Parameters.Append CmdSp.CreateParameter("@page",adInteger,adParamInput)
'入参(查询条件)
CmdSp.Parameters.Append CmdSp.CreateParameter("@condition",adVarChar,adParamInput,800)
'出参(总记录数)
CmdSp.Parameters.Append CmdSp.CreateParameter("@RecordCount",adInteger,adParamOutput)
'出参(总页数)
CmdSp.Parameters.Append CmdSp.CreateParameter("@pages",adInteger,adParamOutput)
CmdSp("@tb")="insider"
CmdSp("@col")="id"
CmdSp("@coltype")=0
CmdSp("@orderby")=0
CmdSp("@collist")="*"
CmdSp("@pagesize")=10
CmdSp("@page")=page
CmdSp("@condition")=""
Set rs =CmdSp.Execute
if rs.state = 0 then '未取到数据,rs关闭
recordcount = -1
else
rs.close '只有关闭才能取出返回值
recordpage=CmdSp.parameters("@pages")
recordcount=CmdSp.parameters("@recordcount")
response.write "总记页数="&CmdSp("@pages")
response.write " 总记录数="&CmdSp.parameters("@recordcount")
rs.open'要取出记录集,则要再打开
if cint(page)>cint(recordpage) then
page=recordpage
end if
%>
<TABLE width="100%" bordercolorlight="#C0C0C0" cellspacing="1" bordercolor="#C0C0C0" bordercolordark="#FFFFFF" border="1">
<TR>
<TD height="20" bgcolor="#C0C0C0">
<p align="center">用户名</TD>
<TD bgcolor="#C0C0C0">
<p align="center">公司</TD>
<TD bgcolor="#C0C0C0">
<p align="center">公司简介</TD>
</TR>
<%if not rs.eof then
do while not rs.eof
%>
<TR>
<TD height="20"><%if not isnull(rs("name")) and rs("name")<>"" then response.write rs("name") else response.write " "%></TD>
<TD><%if not isnull(rs("company")) and rs("company")<>"" then response.write rs("company") else response.write " "%></TD>
<TD><%if not isnull(rs("intro")) and rs("intro")<>"" then response.write rs("intro") else response.write " "%></TD>
</TR>
<%
rs.movenext
loop
%>
<%else%>
<%end if%>
<%rs.close:set rs=nothing%>
<TR>
<TD height="20" colspan="3">
<p align="center">总共有<%=recordcount%>条记录 [<a href="search.asp?page=1">首页</a>]
[<a href="search.asp?page=<%if (page-1)>0 then response.write (page-1) else response.write "1"%>">上一页</a>] [<a href="search.asp?page=<%if cint(page+1)>cint(recordpage) then response.write recordpage else response.write (page+1)%>">下一页</a>] [<a href="search.asp?page=<%=recordpage%>">末页</a>]</TD>
</TR>
</TABLE>
<%end if%>Top
14 楼tujhth()回复于 2006-06-20 13:55:50 得分 0
兄弟,你这个数据表是什么样的啊.就是表怎么建的啊.我也在弄这个问题,很多东西不懂,跟你学习一下了,能否把你的表的结构也贴出来.Top
15 楼wjhcjg(任任行)回复于 2006-06-20 14:37:33 得分 0
这里的ASP代码中的表结构只要含有下面字段即可直接用:
ID 自编量
name varchar 50
company varchar 50
intro varchar 50Top
16 楼tujhth()回复于 2006-06-20 14:49:06 得分 0
我直接建了一个td的表,然后建立了这几个字段,
把存储过程复制上去,再把ASP程序代码付出过去,运行什么都没有,我是刚学这东西,不好意思.Top
17 楼wjhcjg(任任行)回复于 2006-06-20 14:52:46 得分 0
没有添加数据当然什么都没有了,表名改为insiderTop
18 楼lizh0103(天天向上)回复于 2006-08-17 22:14:58 得分 0
请问一下我直接用你的代码 怎么就出现错误了呢???
错误类型:
ADODB.Command (0x800A0BB9)
参数类型不正确,或不在可以接受的范围之内,或与其他参数冲突。
/test3/test.asp, 第 21 行
'返回值
CmdSp.Parameters.Append CmdSp.CreateParameter("RETURN_VALUE",adInteger,adParamReturnValue,4)------------------------21行
'入参(表名)Top




