|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
SQLServer是基于服务器端的中型的数据库,可以适合大容量数据的应用,在功能上管理上也要比Access要强得多。在处理海量数据的效率,后台开发的灵活性,可扩展性等方面强大。毛病
后面已先容了利用ASP所必要的基础妙技,本章要会商的别的一个成绩是当ASP呈现毛病时怎样办,ASP堕落时是甚么情形。当经心编排的ASP页面呈现成绩中断了实行时,用户一样平常失掉的仅是一些用途不年夜的倡议,诸如:点击“革新”按钮,大概“与站点的Web办理员接洽,告知他们你的页面不克不及一般事情了”等等。
本章除供应有效的信息外,还想供应一个匡助地区。我们将具体先容在剧本和页面中毛病怎样呈现,大概发生的毛病范例,和甚么形成了这些毛病。更主要的是,要会商怎样尽量制止毛病的产生,如不克不及制止又怎样妥帖处置。
因而,本章将要切磋页面调试手艺,也就是怎样消费未几的精神和工夫就可以找到毛病并办理成绩。
本章包含以下内容:
·可以呈现的毛病范例。
·怎样避免各类毛病的发生。
·假如不克不及避免毛病产生,怎样妥帖处置这些毛病。
·怎样发明和处置剧本毛病及其他范例的毛病。
·怎样利用定制的毛病页面失掉毛病信息。
·怎样纪录产生的毛病以监督我们的网站。
·创立一个定制毛病网页和一个毛病日记文件。
·供应相干的在线匡助。
本章不触及怎样处置利用ActiveXDataObjects(ADO)会见数据源时呈现的各类特别范例的毛病。像很多组件一样,ADO供应了本人的毛病处置体系,第8章将深切会商这一点。本章将从会商能呈现的各类毛病范例入手下手,使我们可以熟悉这些毛病并接纳响应的措施。
听说,在非洲最暗中的雨林深处,有如许一群程序员,他们的程序代码历来没有呈现不对误。可是,很遗憾他们从没有享用过调试一段不克不及一般事情的使用程序的兴趣。调试程序代码是一个真正充斥康乐的事情,以是我们要面临这个成绩,在调试程序的过程当中查验我们的察看力和横向头脑才能。年夜多半“实在天下”的程序员可以体验这些兴趣是一件功德。
固然,有些人会说,调试程序与其说是判别,不如说是试试看。消费了很多工夫往调试一段有毛病的程序,在某种水平上能够说的确是依附命运。可是,假如第一步从符合的中央入手下手检察,大概会更快地办理成绩。
但这不是程序调试应接纳的举措。从实际上讲,当某段程序运转失利时,应当以逻辑或按次体例跟踪毛病。作为一个伶俐和有履历的程序员,这才是调试经常用的办法,只要专业职员才随便改动程序中变量的值,各处增加Response.Write语句举行调试。
但是,为了可以在逻辑上跟踪程序中的毛病,必需懂得有关毛病怎样呈现方面的基本常识,更主要的是晓得毛病呈现在那里,以便很快就可以找到响应的中央。本章会商的内容是有关程序中可以呈现的分歧品种的毛病,毛病的分歧体现,和怎样纪录和扫除这些毛病。一样主要的是,还将先容怎样制止这些毛病的产生。
本章将从先容大概呈现的分歧品种的毛病入手下手,假如以为你的代码不会呈现任何毛病,能够间接跳到下一章。
7.1毛病的品种
7.1.1语法或“编译”毛病
当我们第一次运转新编写的程序代码时,一般看到的第一种毛病范例是“syntaxerror”。这就是所说的,程序代码上的语法毛病。这就像在写作中利用了毛病的语法,使读者不克不及懂得个中的寄义。而注释器(诸如剧本引擎)和编译器对语法请求得加倍严厉和正确。
语法毛病一般也是最早呈现和必要扫除的。年夜多半情形下,注释器和编译器会指出行号和地点行中的字符地位,和在响应的地位上短少的内容。上面举一个复杂的例子,以下所示的如许一段程序:
<%
Response.Write"Therepaymentsforyourloanare$"&chrPayment_
&"per"&strInterval&,dueonthe"&strDay&"ofeach"
&strInterval&"."
%>
我们但愿失掉上面的了局:
Therepaymentsforyourloanare$124.50permonth,dueonthe12thofeachmonth.
实践上失掉的了局如-1所示:
豆豆注:
假如你的毛病提醒信息没法呈现“语法毛病”,请将你的WINNTHelpiisHelpcommon500-100.asp做以下改动(加了两行黑体字):
...
DimbakCodepage
bakCodepage=Session.Codepage
Session.Codepage=936
Response.WriteServer.HTMLEncode(objASPError.Category)
IfobjASPError.ASPCode>""ThenResponse.WriteServer.HTMLEncode(","&objASPError.ASPCode)
Response.WriteServer.HTMLEncode("(0x"&Hex(objASPError.Number)&")")&"<br>"
IfobjASPError.ASPDescription>""ThenResponse.WriteServer.HTMLEncode(objASPError.ASPDescription)&"<br>"
blnErrorWritten=False
Response.Write"<B>"
IfobjASPError.Description>""ThenResponse.WriteServer.HTMLEncode(objASPError.Description)&"<br>"
OnlyshowtheSourceifitisavailableandtherequestisfromthesamemachineasIIS
…
文件中第3行是Response.Write语句的第2行。呈报毛病信息时,VBScript注释器疏忽一行中的引诱空格和制表符。以是在数完26个字符以后,能够找到语法毛病的中央,这里分明短少了一个双引号。加上双引号后再运转这个页面,我们能够失掉如-2所示:
此次又是别的一个复杂毛病。实践上毛病呈现在第3行而不是第4行。我们遗漏了第三行开端的续行符_。程序代码应当是:
<%
Response.Write"Therepaymentsforyourloanare$"&chrPayment_
&"per"&strInterval&",dueonthe"&strDay&"ofeach"_
&strInterval&"."
%>
1.毛病呈现在甚么中央
必要注重的是剧本注释器仅指出所发明毛病的中央,但实践上那儿其实不必定是毛病真正呈现的中央。在上例中,后面三行的语法准确的;并发生响应的输入了局,而恰好是第4行引发成绩,由于这一行是以一种不法字符开首的,剧本注释器没无意识到这一行是上一行的一部分。
如许的毛病是广泛存在的,由于一般我们次要思索的是要输入的文本内容,而不是双引号、连字符(在VBScript中为“&”)、续行符等的准确按次。
关于关头字、外部函数名拼写毛病或函数的不法参数列表而引发的语法毛病,一般对照简单发明,由于毛病信息提醒大概就指出了毛病的实践地位。比方:上面这段代码是想把今天的日期写进页面。
Response.WriteDateAdd(Now(),"d",1)
实践失掉的了局如-3所示:
这是由于DateAdd函数的语法应当是:
DateAdd(interval_string,interval_number,start_date)
以是应当改写为以下的代码:
Response.WriteDateAdd("d",1,Now())
剧本注释器检测到了我们为第二个参数供应的是一个字符型数据,而DateAdd函数必要的是整型数据范例。
代码布局和剧本布局
语法毛病的另外一个缘故原由是:当制造网页时利用嵌套的或庞大的剧本布局,如IfThen…Else…EndIf大概DoWhile…Loop。这偶然会形成难以找到的语法毛病。
比方上面这段程序:
<%
IfLen(Request.Form("cmdSet"))Then
strCounterName=Request.Form("lstSet")
strNewValue=Request.Form("txtSet")
IfIsNumeric(strNewValue)Then
intNewValue=Cint(strNewValue)
objCounters.SetstrCounterName,intNewValue
Response.Write"Setcounter"&strCounterName&"to"&strNewValue
Else
Response.WritestrNewValue&"isnotavalidnumber"
IfLen(Request.Form("cmdRemove"))Then
strCounterName=Request.Form("lstRemove")
objCounters.RemovestrCounterName
Response.Write"Removedcounter"&strCounterName
EndIf
EndIf
%>
发生的毛病如-4所示:
为何提醒在网页程序中必要一个End语句呢?看一下程序就能够发明,丧失了一个EndIf,而不是End,在程序的最开端应当另有另外一个EndIf。
…
Response.Write"Removedcounter"&strCounterName
EndIf
EndIf
EndIf
%>
在这类情形下,依据代码的缩排格局能够很简单地找到响应的毛病。出格当毛病信息指堕落误的大抵地位时,很快就能够找到毛病地位。但是,这段代码很短,假如在分界符<%…%>中别的另有40行代码,那末毛病行号仍旧大概指向最初一行(line56);而且假如在新的代码中的其他剧本布局搅散了嵌套的布局,毛病大概会指向另外一个地位。
2.关于JScript
假如你不是一名JavaScript妙手,而且的确想实验一些语法毛病,那末就从VBScript切换到JScript。JScript比VBScript对程序编写的请求更严厉,而且对关头字和变量名巨细写敏感,看上面的程序段。
<%
vardatToday=newDate();
Response.Write(datToday.GetMonth());
%>
运转这段程序会发生“Objectdoesn’tsupportthispropertyormethod”(工具不撑持这类属性或办法)毛病,如-5所示:
缘故原由很复杂,前往月份数的JScript函数是getMonth,而不是GetMonth。上面这段程序就能够一般运转。
<%
vardatToday=newDate();
Response.Write(datToday.getMonth());
%>
固然,假如重试这段程序,大概得不到一样的毛病动静。我们第一次运转这段程序时,失掉如-6所示的毛病。
第2行有甚么毛病?假如利用JScript注释器,没有毛病呈现。毛病动静申明,这是一个VBScript语法毛病。用VBScript注释器剖析JScript程序,以是会失掉奇异的毛病动静。
记着正在利用言语
这以是呈现上述毛病是由于在页面的代码后面健忘加@LANGUAGE指令。缺省是VBScript(假如在注册表或在InternetServicesManager中没有改动它),以是VBScript引擎用于处置后面不带@LANGUAGE指令的程序。即便一向利用专为本人的服务器设置的缺省言语,一直利用@LANGUAGE指令是制止发生上述毛病的好办法。如许,假如把网页移到另外一个缺省言语分歧的服务器上,也会失掉预期的了局。
这里报告的内容不成能掩盖一切大概碰到的语法毛病,人们往住想晓得为何会呈现毛病,而毛病信息提醒其实不老是像人们但愿的那样正确。幻想的体例应当是ASP给我们供应一个简便的毛病显现页面,有对毛病的周全准确的形貌,乃至扣问我们是不是想主动处置毛病。现实上使用程序MicrosoftScriptDebugger正试图为我们供应相似的功效,本章前面要对其举行会商,也要归纳综合制止呈现语法毛病的一些要点。如今,我们持续研讨常常在网页中呈现的第二类毛病。
7.1.2语义或“运转期”毛病
语法毛病的发明和处置是使人懊恼的,但在编程中会碰到一些真正“使人镇静”的另外一范例的毛病――语义毛病(semanticerror)或称“运转期”毛病(runtimeerror)。这类毛病仅当运转一个剧本代码或其他程序时才会发明。换句话说完全无效的代码已经由过程注释器或编译器的注释或编译,在实行时发生了毛病。术语“运转期毛病”经由过程是指语义毛病的了局,也就是说这类毛病存在于代码的语义中,今世码运转时它们才酿成可见的。
这类区分来自于这类现实:程序编译器或注释器在处置程序代码之前必需创建一种外部代码的形貌,触及多种布局开首和开头的婚配,以便标明每种布局包括甚么内容,然后剖析每一个句子,以便晓得怎样实行这个句子。比方,假如在程序代码中有一个IfThen…Else…EndIf布局,注释器或编译器做的第一步事情就是剖析哪些语句在“Then”的部分,哪些在“Else”部分。这一步的目标是,在对布局中的If前提举行测试以后,能够决意该到哪一个分支往实行。
编译器(诸如在编程言语像VisualBasic和C++中见到的那种)息争释器(诸如用于像VBScript和JScript那样的剧本言语的注释器)之间真正区分在于:编译器不试图运转程序代码,而是在对源程序举行两次预处置后,构成二进制指令或标记代码,并构成一个.exe文件或.dll文件。注释器不含有代码的文件,而是在运转时慢慢实行。
1.使运转中断的毛病
假如程序中含有一个语义毛病,一般在运转时可失掉提醒。假如侥幸的话,当毛病产生时,程序会中断,如许能够简单地找堕落误地点。比方,上面这段程序界说了一个有六个元素的数组。
<%
DimarrValues(5)toholdsixelements,indexedfrom0to5
ArrValues(6)="Whoops,gotanerror"
%>
假如试图读或设置下标为6的元素值,能够失掉一个运转期毛病,如-7所示:
注重这里的毛病范例是“runtime”(相称于语义)毛病,而不是语法毛病。毛病信息显现了毛病地点行数和毛病的形貌,有助于我们对照简单地找到响应的毛病。但这是一个复杂的例子,在更庞大的程序代码中,这类毛病大概呈现在一些遍历一些值并把它们加到一个数组中程序中。以下所示:
<%
DimarrValues(5)toholdsixelements
ForintLoop=0TointListCountthenumberofitemsinsomelist
arrValues(intLoop)=Request.Form("SelectedItems")(intListCount)
Next
%>
这类情形下,极可能是失掉了过量的列表条目,大概是数组的索引不敷,依据代码的请求,能够判别是那种毛病,而且可以经由过程增添数组巨细来办理这个毛病。
<%
DimarrValues(10)toholdelevenelements
ForintLoop=0TointListCountthenumberofitemsintsomelist
arrValues(intLoop)=Request.Form("SelectedItems")(intListCount)
Next
%>
大概响应地设置轮回的参数来办理处置这个毛病。
<%
DimarrValues(5)toholdsixelements
IntArrayMax=intListCount
IfintArrayMax>5ThenintArrayMax=5
ForintLoop=0TointArrayMaxonlyaddthefirstsixitems
arrValues(intLoop)=Request.Form("SelectedItems")(intListCount)
Next
%>
很多其他运转期毛病可以使网页运转中断,诸如一些组件或工具的实例化失利,缘故原由是有ProgID毛病,大概是由于组件没有准确安装。在这些情形下,了局老是给出“ActiveXCannotCreateObject”毛病提醒信息,前面随着挪用Server.CreateObject办法的行号。
2.发生毛病了局的毛病
下面提到,假如碰到一个使程序代码中断的运转期毛病,我们多是侥幸的。可是另外一种情形是程序能很好地实行,仿佛甚么也没有产生,最初发生一个毛病的了局。这是最难发明息争决的毛病,由于认识不到那里堕落了。比方,假定有一个网页,这个网页把用户的诞辰作为日期型的值,而且独自显现日期元素(能够把它们作为三个条目加到一个数据库中)。
<%
getthevaluefromtheRequestanddisplayit
datBirthdate=Request.Form("Birthdate")
Response.Write"Thevalueyouenteredis:"&datBirthdate&"<P>"
gettheindividualdateelements
intDay=Day(datBirthdate)
intMonth=Month(datBirthdate)
intYear=Year(datBirthdate)
anddisplaythem
Response.Write"Day:"&Cstr(intDay)&"<BR>"
Response.Write"Month:"&Cstr(intMonth)&"<BR>"
Response.Write"Year:"&Cstr(intYear)&"<BR>"
%>
-8是了局,是用美国日期作风月/日/年显现的,仿佛统统都没有成绩。
但是假如输出一个不法日期,大概让输出文本框空着,便失掉一个运转期毛病,如-9所示:
(1)假如不是一名JScript专家
在寻觅毛病时,这不是一个年夜成绩,由于我们可以敏捷发明为何会呈现毛病。现实上彀页中断运转有助于我们跟踪毛病。但是不测的毛病大概会产生。比方,用JScript重写程序代码,因为不是一名JScript专家,内里呈现一些微小毛病。
<%
//getthevaluefromtheRequestanddisplayit
vardatBirthdate=newDate(Request.Form("Birthdate"));
Response.Write("Thevalueyouenteredis:"+datBirthdate+"<P>");
//gettheindividualdateelements
intDay=datBirthdate.getDay();
intMonth=datBirthdate.getMonth();
intYear=datBirthdate.getYear();
//anddisplaythem
Response.Write("Day:"+intDay.toString()+"<BR>");
Response.Write("Month:"+intMonth.toString()+"<BR>");
Response.Write("Year:"+intYear.toString()+"<BR>");
%>
-10便是运转了局,只管程序没有中断运转并给出运转期毛病,仍是即刻看出个中有些成绩,月份不成能是0。
成绩呈现的缘故原由在于JScript的getMonth函数前往的了局为0~11局限内的数,因而必要再加1,才干失掉准确的了局。
intMonth=datBirthdate.getMonth()+1;
(2)衍生毛病
即便不把初始值赋给网页往和了局对照,下面这类毛病也多是相称分明的。但是,假如面临的是一个数据库体系,而且没有看到显现出不准确的了局,大概不晓得为何程序不克不及准确地更新数据库。更糟的是,假如复杂地把数值做为整型数据存进数据库,大概直到有人试图对这个数据查询时才干发明这个毛病。
如今,发明约莫有十二分之一的成员出身在0月份大概会令人受惊,并会引发一些成绩。记着,不单单是那些1月份出身的职员存在数据库中的信息不准确,并且每一个成员都是如许。假如有很多使用程序都能增添和修正这个数据库中的纪录,跟踪这个毛病多是艰辛的事情,出格是,不克不及往查找毛病呈现在哪一个程序行,而是起首要找堕落误呈现在哪一个使用程序中。
(3)把握日期的用法
在下面的程序中呈现的日期型数据的毛病不长短常分明,不管利用都输出甚么样的日期,程序代码只能给出0~6当中的值,缘故原由在于编码中的设定,出格是从VBScript转换到JScript时。在JScript中,getDay函数前往的周中的某一天,而不是月中的某一天,这等价于VBScript中的Weekday函数,getDay函数的前往值是0(代表日曜日)到6(代表礼拜六)。
注重VBScript的Weekday函数前往1(代表日曜日)到7(代表礼拜六)。
因而,在JScript中由getDate函数取得某月的日期的准确代码是:
…
//gettheindividualdateelements
intDay=datBirthdate.getDate();
intMonth=datBirthdate.getMonth()+1;
intYear=datBirthdate.getYear();
…
运转这段程序即可失掉想要的了局,如-11所示:
写软件都是想的时间比写的时间要长的.如果反过来了就得看看是什么原因了.另外大家可以回去问问公司里的小MM.(一般企业里,跟你们交付软件接触得最多的是她们) |
|