asp知识从入门到精通,看完你就是网络编程高手.docx
ADO存取数据库时的分页显示如果你使用过目前众多网站上的电子公告板程序的话,那你应该会知道电子公告板程序为了提高页面的读取速度,一般不会将所有的帖子全部在一页中罗列出来,而是将其分成多页显示,每页显示一定数目的帖子数,譬如20条。想不想了解若何实现分页显示请看本文!?动态网站设计十八般武艺一ASP篇?一文从第一期至今已和朋友们一起度过了大半个年头,相信通过在这一段时间中的学习、实践到再学习、再实践,大家已经能够熟练运用ASP的内建对象、ActiveX组件去编写一些基本的ASP应用程序。从我收到的朋友们的来信中可以明显的感觉到,大家的ASP功力正不断地提升。最近很多朋友来信希望我写一些ASP在现实运用中的实例。因此,从本期开场我决定将?动态网站设计十八般武艺一ASP篇?的定位从介绍和学习ASP根基知识转向到ASP实际运行的探讨和深化。应朋友们的要求,在本期中我将给大家着重谈一谈“AD0存取数据库时若何分页显示的问题。什么是ADO存取数据库时的分页显示如果你使用过目前众多网站上的电子公告板程序的话,那你应该会知道电子公告板程序为了提高页面的读取速度,-一般不会将所有的帖子全部在一页中罗列出来,而是将其分成多页显示,每页显示一定数目的帖子数,譬如20条。这就是数据库查询的分页显示,如果你还不明白,去看看yahoo等搜索引擎的查询结果就会明白了。那么终究若何才能做到将数据库的查询结果分页显示呢其实方法有很多,但主要有两种:一、将数据库中所有符合查询条件的记录一次性的都读入recordset中,存放在内存中,然后通过ADORecordset对象所提供的几个专门支持分页处理的属性:PageSize(页大小)、PageCount(页数目)以及AbsolutePage(绝对页)来管理分页处理。二、根据客户的指示,每次分别从符合查询条件的记录中将规定数目的记录数读取出来并显示。两者的主要差异在于前者是次性将所有记录都读入内存然后再根据指示来依次做判断分析从而到达分页显示的效果,而后者是先根据指示做出判断并将规定数目的符合查询条件的记录读入内存,从而直接到达分页显示的功能。我们可以很明显的感觉到,当数据库中的记录数到达上万或更多时,第种方法的执行效率将明显低于第二种方法,因为当每一个客户查询页面时都要将所有符合条件的记娣旁诜衿能让嬷校缓省消蟹忠车却恚绻庇谐?100个的客户在线查询,那么ASP应用程序的执行效率将大受影响。但是,当服务器上数据库的记录数以及同时在线的人数并不是很多时,两者在执行效率上是相差无几的,此时一般就采用第一种方法,因为第一种方法的ASP程序编写相对第二种方法要简单明了得多。在这里作者就以我们常见的ASPBBS程序为例,来给大家分析一下若何在BBS程序里实现分页显示功能,由于我们一般使用的BBS程序的数据库记录数和同时访问的人数都不会太多,所以以下程序实例是使用的先前所介绍的第一种分页显示方法。进展ADO存取数据库时的分页显示,其实就是对Recordset的记录进展操作。所以我们首先必须了解Reordset对象的属性和方法:BOF属性:目前指标指到RecordSet的第一笔。EOF属性:目前指标指到RecordSet的最后一笔。Move方法:移动指标到RecordSet中的某一条记录。AbsolutePage属性:设定当前记录的位置是位于哪-页AbsolutePosition属性:目前指标在RecordSet中的位置。PageCount属性:显示Recordset对象包括多少“页”的数据。RecordCount属性:显示Recordset对象记录的总数。下面让我们来详细认识一下这些重要的属性和方法一、BOF与EOF属性通常我们在ASP程序中编写代码来检验BOE与EOF属性,从而得知目前指标所指向的RecordSet的位置,使用BOF与EOF属性,可以得知一个Recordset对象是否包含有记录或者得知移动记录行是否已经超出该Recordset对象的范围。如:$#60;%ifnotrs.eofthen.%$#62;$#60;%ifnot(rs.bofandrs.eof)%$#62;假设当前记录的位置是在一个Recordset对象第一行记录之前时,BOF属性返回true,反之那么返回false。假设当前记录的位置是在一个Recordset对象最后一行记录之后时,EOF属性返回true,反之那么返回false。BOF与EOF都为False:表示指标位于RecordSet的当中。BOF为True:目前指标指到RecordSet的第一笔记录。EOF为True:目前指标指到RecordSet的最后一笔记录。BOF与EOF都为True:在RecordSet里没有任何记录。二、Move方法您可以用Move方法移动指标到RccordSet中的某一笔记录,语法如下:rs.MoveNumRecords,Start这里的"rs”为一个对象变量,表示一个想要移动当当前记录位置的Recordset对象;aNumRecordsw是一个正负数运算式,设定当前记录位置的移动数目;“start”是一个可选的工程,用来指定记录起始的标签。所有的Recordset对象都支持Move方法,如果NumRecords参数大于零,当前记录位置向末尾的方向移动;如果其小于零,那么当前记录位置向开头的方向移动;如果一个空的Recordset对象调用Move方法,将会产生一个错误。MoveFirst方法:将当前记录位置移至第一笔记录。MoveLast方法:将当前记录位置移至最后一笔记录。MoveNext方法:将当前记录位置移至下一笔记录。MovePrevious方法:将当前记录位置移至上一笔记录。Moven方法:移动指标到第n笔记录,n由0算起。三、AbsolutePage属性AbsolutePage属性设定当前记录的位置是位于哪一页的页数编号;使用PageSize属性将Recordset对象分割为逻辑上的页数,每一页的记录数为PageSize(除了最后一页可能会有少于PageSize的记录数)。这里必须注意并不是所有的数据提供者都支持此项属性,因此使用时要小心。与AbsolutePosition属性一样,AbsolutcPage属性是以1为起始的,假设当前记录为Recordset的第一行记录,AbsolutePage为1。可以设定AbsolutePage属性,以移动到一个指定页的第一行记录位置。四、AbsolutePosition属性假设您需要确定目前指标在RecordSet中的位置,您可以用AbsolutePosition属性。AbsolutePosition属性的数值为目前指标相对於第一笔的位置,由1算起,即第一笔的AbsolutePosition为Io注意,在存取RecordSet时,无法保证RecordSet每次都以同样的顺序出现。假设要启用AbSoIUtePoSition,必须先设定为使用用户端cursor(指针),asp码如下:rs2.CursorLocation=3五、PageCount属性使用PageCount属性,决定Recordset对象包括多少“页"的数据。这里的"页"是数据记录的集合,大小等于PageSize属性的设定,即使最后一页的记录数比PageSize的值少,最后一页也算是PageCount的一页。必须注意也并不是所有的数据提供者都支持此项属性。六、PageSize属性PageSize属性是决定ADO存取数据库时若何分页显示的关键,使用它就可以决定多少记录组成一个逻辑上的“一页”。设定并建设一个页的大小,从而允许使用AbsolutePage属性移到其它逻辑页的第一条记录。PageSize属性能随时被设定。七、RecordCount属性这也是一个非常常用和重要的属性,我们常用RecordCount属性来找出一个Recordset对象包括多少条记录。如:$#60;%totle=RS.RccordCount%$#62;在了解了Recordset对象的以上属性和方法后,我们来考虑一下,若何运用它们来到达我们分页显示的目的。首先,我们可以为PageSize属性设置一个值,从而指定从记录组中取出的构成一个页的行数;然后通过RecordCount属性来确定记录的总数;再用记录总数除以PageSizc就可得到所显示的页面总数;最后通过AbsolutePage属性就能完成对指定页的访问。好象很并不复杂呀,下面让我们来看看程序该若何实现呢我们建设这样一个简单的BBS应用程序,它的数据库中分别有以下五个字段:“ID”,每个帖子的自动编号;“subject”,每个帖子的主题;“name”,加帖用户的姓名;“email",用户的电子邮件地址;“postdate”,加帖的时间。数据库的DSN为“bbs。我们将显示帖子分页的所有步骤放在一个名为'ShowListO”的过程中,方便调用。程序如下:BBS显刁:帖子分页$#60;%SubShowListO%$#62;$#60;%PgSz=20设定开关,指定每一页所显示的帖子数口,默认为20帖一页SetConn=Server.CreateObject("ADODB.Connection")SetRS=Server.CreateObject("ADODB.RecordSet")sql="SELECT-FROMmessageorderbyIDDESC,查询所有帖子,并按帖子的ID倒序排列Conn.Open"bbs"RS.opensql,Conn,1,1IfRS.RecordCount=Othenresponse.write"$#60;P$#62;$#60;center$#62;对不起,数据库中没有相关信息!$#60;/center$#62;$#60;/P$#62;"elseRS-PageSize=Cint(PgSz)设定PageSize属性的值Total=INT(RS.recordcount/PgSz,-1)*-1计算可显示页面的总数PageNo=RequestCpageno")ifPageNo=""ThenPageNo=1elsePageNo=PageNo+1PageNo=PageNo-IendifScroIIAction=Request("ScrollAction")ifScroIIAction=',上一页"ThenPageNo=PageNo-IendififScrOlIACtiOn="下一页"ThenPageNo=PageNo+1endififPageNo$#60;1ThenPageNo=1endifn=1RS-AbsoIutePage=PageNoResponse.Write"$#60;CENTER$#62;”position=RS.PageSize*PageNopagebegin=position-RS.PageSize+1ifposition$#60;RS.RecordCountthenpagend=positionelsepagend=RS-RecordCountendifResponse.Write"$#60;P$#62;$#60;fontcolor=Navy$#62;$#60;B$#62;数据库查询结果:$#60;/B$#62;"Response.Write"(共有"&RS.RecordCount&"条符合条件的信息,显示"&pagebegin&"-"&pagend&")$#60;/font$#62;$#60;/p$#62;"Response.Write"$#60;TABLEWIDTH=600BORDER=ICELLPADDING=4CELLSPACING=OBGCOLOR=#FFFFFF$#62;”Response.Write"$#60;TRBGCOLOR=#5FB5E2$#62;$#60;FONTSIZE=2$#62;$#60;TD$#62;$#60;B$#62;主题$#60;/B$#62;$#60;"D$#62;$#60;TD$#62;$#60;B$#62;用户$#60;/B$#62;$#60;/TD$#62;$#60;TD$#62;$#60;B$#62;Email$#60;/B$#62;$#60;/TD$#62;$#60;TD$#62;$#60;B$#62;发布日期$#60;/B$#62;$#60;/TD$#62;$#60;/FONT$#62;$#60;TRBGCOLOR=#FFFFFF$#62;"Dowhilenot(RSisnothing)RowCount=RS-PageSizeDoWhileNotRS.EOFandrowcount$#62;0Ifn=1thenResponse.Write"$#60;TRBGCC)LoR=#FFFFFF$#62;"ELSEResponse.Write"$#60;TRBGCoLOR=#EEEEEE$#62;”EndIfn=1-n%$#62;$#60;TD$#62;$#60;spanstyle="font-size:9pt"$#62;$#60;Ahref=view.asp?key=$#60;%=RS("ID")%$#62;$#62;$#60;%=RS("subject")%$#62;$#60;/A$#62;$#60;/span$#62;$#60;/td$#62;$#60;TD$#62;$#60;spanStyle="font-size:9pt”$#62;$#60;%=RS("name")%$#62;$#60;/A$#62;$#60;/span$#62;$#60;/td$#62;$#60;TD$#62;$#60;spanstyle="font-size:9pt"$#62;$#60;ahref="mailto:$#60;%=RS("email")%$#62;"$#62;$#60;%=RS("email")%$#62;$#60;/a$#62;$#60;/span$#62;$#60;/TD$#62;$#60;TD$#62;$#60;spanstyle="font-size:9pt"$#62;$#60;%=RS("postdate")%$#62;$#60;/span$#62;$#60;/td$#62;$#60;/TR$#62;$#60;%RowCount=RowCount-1RS-MoveNext1.oopsetRS=RS-NextRecordSetLoopConn.Closesetrs=nothingsetConn=nothing%$#62;$#60;/TABLE$#62;$#60;FORMMETHOD=GETACTION="list.asp"$#62;$#60;INPUTTYPE="HIDDEN"NAME="pageno"VALUE="$#60;%=PageNo%$#62;"$#62;$#60;%ifPageNo$#62;1Thenresponse.write"$#60;INPUTTYPE=SUBMITNAME=ScroIIActionVALUE=上一页$#62;"endififRowCount=0andPageNo$#60;$#62;Totalthenresponse.write"$#60;INPUTTYPE=SUBMITNAME=ScroIIActionVALUE=下一页$#62;"endifresponse.write"$#60;/FORM$#62;"Endif%$#62;$#60;%EndSub%$#62;相信大家都应该能完全读懂上面的程序,因此作者就不在此详细解释了。值得注意的是在这段程序中运用了一个小技巧$#60;INPUTTYPE="HIDDEN“NAME="pageno*VALUE=$#60;%=PageNo%$#62;$#62;,这是用来在每次调用该ASP文件时传递数据的“暗道”,由于我们需要在每次调用程序时传递代表当前页码的参数,可能大家会想到使用SeSSiOn,但是从节省系统资源和通用性来讲,用这样一个隐藏的form来传递数据将会到达更好的效果。