SQL基础知识.docx
第三局部操作数据:SQ1.本局部内容SQ1.基础中级SQ1.高级SQ1.第10章SQ1.基础本章内容SQ1.介绍使用SE1.ECT语句从表中取数据创立新表字段属性向表中添加数据删除和修改表为了建立交互站点,你需要使用蚊据库未存储来自访问者的信息。例如,你要建立一个职业介绍效劳的站点,你就需要存储诸如个人向历,所感兴提的工作等等这样的信息。创立动态同叶也需要使用数据库.如果你怂显示符合来访者要求的呆好的工作,你就帑要从数据库中取出这份工作的信息.你将会发现,在许多情况下得要使用数据库。在这一章里,你将学会怎样使用“结构化查询语言”(SQ1.)来操作数据库,SQ1.法盲是般据库的标准语言。ActiveSverPages中,无论何时你要访问一个数据库.你就要使用SQ1.语言。因此.学提好SQ1.对ASP编程是生常重要的.注意:你可以把“SQ1.读作-seque1.",也可以按单个字母的读音读作S-Q-1.4两种发音标是正确的,每种发音各有大量的支椅者.在本书里,认为“SQ1.”读作"seque1.".通过这一章的学习,你将理解怎样用SQ1.实现数据库查询.你将学会怎样笠用这种丧询从蚊据表中取出信息.最后,你将学会怎样设计和建立囱己的数据库。注意:通过下面几章就SQ1.的介绍.你将对SQ1.有足够的了解,从而可以有效地使用ACtiVeSeVerPages。但是.SQ1.是一种复杂的语言.本书不可能包括它的全部细节。要登首掌握SQ1.语言,你常要学习在MiCroSof1.SQ1.Sover中使用SQ1.你可以到附近的书店去买一本ZiCroSof1.SQ1.Sever6.5.SQ1.介绍:本书假设你是在SQ1.操作MiCroSoftSQ1.Sever的数据库.你也可以用SQ1.操作许多其它类型的数据库.SQ1.是操作/据库的标准语言。(事实上,关于SQ1.语音有一个专门的ANSI标准)注意:不要在你的站点上试图用MicrosoftAccess代替MicrosoftSQ1.Sever.SQ1.Sever5T以同时效劳于许多用户,如果你希曳你的站点有较高的访问率,MSACCeSS是不能胜任的。在学习SQ1.的细节之前,你需要理解它的苒大构点。一个特点容易单握.另一个掌握起来有点困难.第一个特点是所有SQ1.数据库中的数崇都存偌在表中.一个表由行和列组成.例如.下面这个简单的表包括name和e-mai1.address:NameEmai1.AddressBi1.1.GatespresidentC1.intonpresiStephenUa1.ther这个表有两列(列也称为字段,域):NaBC和EmaiIAddress.有三行,每一行包含一组数据,一行中的数据俎合在一起讲为一条记录.无论何时你向表中添加新数禺,你就添加了一条新记录,一个数据表可以有几十个记录,也可以有几千甚至几十亿个记录。虽然你也许永远不济要存猪十亿个Emai1.地址,但知道你能这样做总是好的,也许有一天你会有这样的需要。你的数据库很有可能也含几十个表,所有存储在你数据库中的信息都被存储在这些表中.当你考虑怎样把信息存储在数据库中时,你应该考虑怎样把它们存储在表中。SQ1.的第二个绮点有些理于掌握.这种话亩被设计为不允许你按照某种特定的顺序未取出记录.因为这样做会降低SQ1.SeYer取记录的效率,使用SQ1.,你只能按查询条件来读取记录.当考虑如何从表中取出记录时,自然会想我按记录的位置读取它们。例如,也许你会尝试通过一个循环,逐个记录地扫描.来选出特定的记录。在使用SQ1.时,你必须训练自己,不要有这种思路。假设你想选出所有的名字是“Bi1.1.Ga1.es"的记录,如果使用传统的编程语言,你也许会构造一个循环,逐个查看表中的记录,看名字城是否是aBi1.1.Gates-.这种选择记录的方法是可行的,但是妓军不高。使用SQ1.你只要说,“选择所有名字域等于BiI1.GateS的记录°.SQ1.就会为你选出所有符合条件的记录。SQ1.会确定实现查询的最正确方法.健设你想取出表中的前十个记录.使用传统的编程语言,你可以做一个循环,取出前十个记录后转束循环.但使用标准的SQ1.查询,这是不可能实现的,从SQ1.的角度来说,在一个米中不存在前十个记录这种概念.开始时,当你知道你不能用SQ1.实现某些你感觉应该能实现的功能,你会受到挫折。你也许会以失撞墙甚至博写怒毒的信件给SQ1.的设计者们。但后来你会认识到,SQ1.的这个料点不仅不是个限制.反而是其长处因为SQ1.不根密位置来读取记或,它读取记录可以很快.僚上所逑,SQ1.有两个特点:所有数据存储在表中,从SQ1.的角度来说,表中的记录没有Ifi序。在下一节,你将学会卷祥府SQ1.从表中选择特殊的记录。使用SQ1.从表中取记录。SQ1.的主要功能之一是实观数据库查询。如果你熟希IntCrne1.引擎,那么你已经熟悉麦河了.你使用查询来取得满足特定条件的信息.例如,如果你想找到有ASP信息的全部站点,你可以连接到YahOo!并执行一个对ActiveSeverPages的慢索,在你输入这个查询后,你会收到一个列表,枭中包括所有其描述中包含接索表达式的站点。多数IUte1.引擎允许逻辑查询。在正辑Jt询中,你可以包括转殊的运算符如AND.OR和NoT,你使用这些运算符来选择特定的记录.例如,你可以用AM)来限制查询结果.如果你执行一个对ACtiVeSeVerPiIgeSANDSQ1.的傻家.你将得到其描述中同时包含AetiVeSeVerPageS和SQ1.的记录。当你需要泯制查询结果时,你可以使用AND,如果你裔要犷展查询的结果.你可以使用退辑操作符OR。例如,如果你执行一个搜索,技余所有的其描述中包含ACtiVeSeVerPageSORSQ1.的拈点,你收到的列表中将包括所有其描述中同时包含两个表达式或其中任何一不表达式的站点.如果你想从搜俅结果中排除特定的站点,你可以使用NOT.例如.丧询“ActiveSeverPages"ANDNOT"SQ1.”将返回一个列表,列表中的站点包含ACIiVCSeverPages.但不包含SQ1.。当必须排除特定的记录时.你可以使用MJTo用SQ1.执行的查询与用InteI-net攫华引擎执行的梭索非常相似。当你执行一个SQ1.查询时,通过使用包括近辑运算符的登询条件,你可以得到一个记录列表。此时登询结果是来自一个或多个表。SQ1.查询的句法聿常钩单。假设有一个名为Cmai1.tabIC的表.包含名字和地址两个字段.要程到BinGatCS的ejnai1.地址,你可以使用下面的查询:SE1.ECTemai1.freeemai1._tab1.eWHEREname='Bi1.1.Gates'当这个受询执行时,就从名为e三i1.tab1.e的表中读取BmGateS的eBai1.地址.这个简华的语句包括三局部: SE1.ECr语句的第一局都指名要选取的列。在比例中,只有emai1.列被选取。当执行时,只显示emai1.列的值. SE1.ECTT语句的篇二部份指明要从舞个(些)表中查询数据.在此例中,要查询的未名为emui1.tab1.e. 最后.SE1.ECT语句的IIHERE子句指明要选择满足什么条件的记录.在此例中,查询条件为只有na«e列的值为BiI1.Gates的记录才被选取.BinGateS很有可能拥有不止一个emai1.地址,如果我中包含BiHGateS的多个Cmai1.地址.用上述的SE1.ECT语句可以读取他所有的emai1.地址。SE1.EeT语句从表中取出所有name字段值为Bi1.IGates的记录的emai1.字段的值。前面说用,瓷询可以在查询条件中包含建辖运算符“假没你想读取Bi1.IGateS或C1.intOn总统的所有em,i1.地址,你可以使用下面的查询语句:SE1.ECTemai1.EROMCmai1.tab1.cWHEREname=,Bi1.1.Gates'ORrame=*presidentC1.inton"牝例中的登询条件比前一个复杂了一点。这个语句从表emai1._tab1.e中选出所有name列为Bi1.1.Gates或presidentC1.inton的记录.如果表中含有Bi1.1.GatespresidentC1.inton的多个地址,所有的地址都被读取.SE1.ECT语句的结构看起来很克现.如果你请一个用友从一个表中为你选择一俎记录,你也许以非常相似的力武提出你的要求。荏SQ1.SE1.ECT语句中,你“SE1.ECT特定的列FROM一个表WHERE某些列满足一个朴定的条件*。下一节将介绍怎样执行SQI.查询来选取记录.这将帮助你熟悉用SE1.ECT语句从表中取数据的各种不同方法.使用ISQ1.执行SE1.ECT查询当你安装SQ1.Sever9?,你同时安装了一个叫作ISQ1.w的应用程序.1SQ1.a允许你执行交互的SQ1.瓷询.在把查询包括到你的ASP风页中之前,用ISQ1.w对其进行测试是非常有用的。注意在这本书的第一部份,你学习了怎样安装和配置MiCroSoftSQ1.Sever.如果没有安装SQ1.SeVer或者SQ1.SeVer不能运行,请参阅第三章“安装和使用SQ1.SeVer*.选择任务上SQ1.Svcr程序俎中的ISQ1.W以启动该程序.程序启动时.&先会出现一个对话框.要求为入效劳器信息和登录信息(见图10.1).在SeVer推中,输入你的SQ1.效劳器的名字.如果效劳器正运行在本地计算机上,效劳器名字就是你计算机的名字。在聋录信息相中,输入一个督录帐号和再码或选择使用“可信连接”,ffi后单击Connect按钮。图10.1注港:如果你将SQ1.%ver配置为使用完整平安或混合平安,那么你可以使用可信连接。如果你使用标准平安,你则需要提供用户帐号和雷码.要了解更多信息,参见第三章.如果一切正常,在你单击连接按钮后会出况一个立询窗口,如图10.2所示.(如果右异蒿,请叁考第三章)图10.2在执行查询之前,你需要迷择政据阵。安笠SQ1.SeVer时你已为自己钊立了一个数据库,SQ1.SeVer迂有洋多系统数据库,如BaSter.mode1.,asdb,fctempdb,方便的是,SQ1.SeVer带有一个好殊的名为PUbS的例子数据库。库PUbS中包含供一个虚拟的出版商使用的各个表。文档中所有的例子程序都是针对这个库来谀计的。本书中的许多例子也使用这个数据序.在交询窗口顶部的DB下拉椎中选择数据库pubs,这样你就选择了数据库.你所有的爻询都将针对这个库中的各个表来执行。现在你可以执行你的第一个查询了。这真让人兴奋!你的第一个登询将针对一个名为autrors的表.表中包含所有为某个虚拟出版商工作的作者的相关数据。单击查询窗口并输入以下的语句:SE1.ECTphoneFROMauthorsWHEREau-nju11e=*Ringer"输入完成后.单击执行查询按钮(一个绿色三戏形.看起来像VCR拾放就)。单击此按钮后,任何出现在查询口中的语句均会帔执行.攵询富口会自助变成诘果显示窗口,你可以看到询的结果(见图10.3).你看到的查询结果也许与图10.3所示的不同,在SQ1.seVer的不同版本中,库PUbS中的数抠会有所不同,游SQ1.Sever6.5来说,将会找到两条记录。结果显示窗口中应显示如下内容:phone801826_0752801826_0752(2row(三)affected)S10.3你所执行的SE1.ECT语句从表authors中取出所有名字为Ringer的作者的电话号玛.你通过在WHERE子句中使用绮殊的选择条件来限制查询的结果,你也可以忽略选择条件,从表中取出所有作者的电话号码。要做到这一点,单击QUery标线,返国到登询窗口,输入以下的SE1.ECr语句:SE1.ECTPhoneI1ROMauthors这个查询执行后.会取出表authors中的所有电话号码(没有好定的顺序)。如果浅authors中包含一百个电话号码,会有一百个记录被取出,如果表中有十亿个电话号码,这十亿条记录演会被取出(这也许需要一些时问).表authrs的字段包括姓.名字,电话号码,池址,城市,州和邮政愉码,通过在SE1.ECT语句的第一部份指定它们.你可以从表中取出任何一个字段。你可以荏一个SE1.ECT谓旬中一次取出多个字段,比方:SE1.ECTaufname,au_!name,phoneFROMauthors这个SEuXT语句执行后.将取出这三个列的所有值.下面是这个衣询的结果的一个例如(为了节省设张.只显示查询结果的一局部,其余记录用古略号代苕):aufnameauInamephoneJohnsonWhite408196_7223MarjorieGreen415986_7020Chcry1.Carson415548_7723Michae1.0,1.earyJ082862428*(23row(三)affected)在SE1.ECT语句中,你需要列出多少个字段,你就可以列出多少.不要忘了把字段名用逗号隔开.你也可以用星号(*)从一个表中取出所有的字段.这里有一个使用星号的例子:SE1.ECT*I-ROMauthors这个SE1.ECT语句执行后.表中的所有字段的值都被取出.你会发现你将在SQi.查询中疑繁使用星号.技巧:你可以使用星号来或看一个表的所有列的名字.要做到这一点,只需要在执行完SE1.ECT语句后看一下查询结果的列标题。操作多个表到现在为止,你只尝试了用一句SQ1.查询从一个袅中取出数箔,你也可以用一个SE1.EcT语句同时从多个表中取出金据,只需在SE1.ECT语句的FROM从句中列出要从中取出数据的表名称即可:SE1.ECTau!name.tit1.eFROMauthors,tit1.es这个SE1.ECT语句执行时,同时从表authors和表tit1.es中取出数据,从表authors中取出所有的作者名字,从表tit1.es中取出所有的书名。在ISQ以程序中执行这个查询.看一下查询结果。你会发现一些奇怪的出乎意料的情况:作者的名字并没右和它们所著的书相匹配,而是出现了作者名字和书名的所彻可能的组合,这也许不是你所希曳见到的。出了什么过错?问题在于你没有指明这为个表之何的关系.你没有通过任何方式告诉SQ1.如何把表和表关联在一起。由于不知道如何关联两个表.效劳器只能铺单地返回取囱两个表中的记录的所有可能组合.更从两个表中选出有意义的记录俎合,你帝要通过嫂立两表中字段的关系来关联两个表.要做到这一点的途径之一是创立第三个表,专门用来搭迷另外两个表的字段之间的关系.表authors有一个名为au_id的字段,包念有每个作者的唯一标识。表tit1.es有一个名为tit1.e_id的字段.包含每个书名的唯一标识.如果你能在字段au_id和字段ti1.1.e,d之问是立一个关系,你就可以关骁这两个表.数泰称PUbS中有一个名为Iit1.eauthor的表,正是用来完成这个工作.表中的每个记录包括两个字段,用来把表tit1.es和表authors关联在一起。下面的SE1.ECr语句使用了这三个耒以得到正琬的结果:SE1.ECTau-namc.tit1.eFROMauthors.tit1.es.tIt1.cauthorWHEREauthors.auid=titIeauthor.auidANDtit1.es.tit1.e_id=titieauthor.tit1.e_id当这个SE1.ECT语句执行时.每个作者都将与正确的书名相匹配。表Iit1.cauthor指明了表authors和表tit1.es的关系,它通过包含分别来自两个表的各一个字段实现这一点.第三个表的唯一目的是在另外两个表的字段之间建立关系。它本身不包含任何附加教樨.注意在这个例子中字段名是如何书写的。为了区别表authors和表tit1.es中相同的字段名au_id,每个字段名前面都加上了表名前援和一个句号.名为author.au_id的字段属于表authors,名为tit1.eauthor.au_id的字段属于表IitIeaUthOr.两者不会混淆。通过使用第三个袤,你可以在苒个表的字段之间建立各种类型的关系。例如,一个作者也许写了许多不同的书,或者一本书也许由许多不同的作者共同完成.当两个表的字段之间有这种“多对多"的关系时,你需要使用第三4表未指明这种关系.但是,在许多情况下,两个表之间的关系并不复杂。比方你常要指明表tit1.es和表PUbIiSherS之同的关系.因为一个书名不可能与多个出版商相匹配,你不需要通过第三个表来指明这两个表之间的关系。要指明表tit1.es和表PUb1.iSherS之间的关系,你只要让这两个表有一个公共的字段就可以了.在数据库pubs中,表Iit1.eS和表PUbIiSherS都有一个名为PUb_id的字或。如果你想得到书名及其出版商的一个列表,你可以使用如下的语句:SE1.ECTtit1.e.xb-na三eFROMtit1.es.pub1.ishersWHEREtit1.es.pub_id=pub1.ishcrs.pub_id当然,如果一本书是由两个出版商联合出版的.那么你需要第三个未来代表这种关系。通常,当你于先知道苒个表的字段间存在“多对多”关系时,就使用第三个表来关联这两个表。反之,如果两个表的字段间只有“一对一”或“一对多"关系.你可以使用公共字段来关联它门。操作字段通常.当你从一个表中取出字段值时,该值与创立该表时所定义的字段名联系在一起。如果你从表authors中选择所右的作者名字,所有的值将会与字段名auIni1.me相联系.但是在某些情况下,你带要对字段名进行操作。在SE1.ECT语句中,你可以在缺省字段名后面仅跟一个新名字未取代它。例如,可以用一个更直观易读的名字AUIhor1.astNaBe来代瞥字段名au!name:SE1.ECTauInametAuthor1.astNaee,1.:ROMauthors当这个SE1.ECr语句执行时,来百字段auJnamc的值会与"Author1.astName"相联系查询结果可能足这样:A1.nhQr1.astNa三eWhiteGreenCarson0'1.earyStraight(23row(三)affected)注朦字段标题大再是auu1.na11cffjftAuthor1.astNaInC所双代。你也可以通过执行运算,来操作从一个表返回的字段值.例如,如果你恐把衰IitIeS中的所有书的价格如倍,你可以使用下质的SE1.ECT语句:SE1.ECTPriCC*2FROMtit1.es当这个查询执行时,每本书的价格从表中取出时都会加倍,但是,通过这种途径操作字段不会改变存储在表中的书价。对字段的运算只会影响SE1.EcT语句的输出.而不会影构表中的蚣据。为了同时显示书的原始价格和涨价后的新价格,你可以使用下面的查询:SE1.ECTprice"Origina1.price*,price2'Newprice*FRWItit1.es当数据从表tit1.es中取出时,原始价格显示在标题Origina1.price下面,加倍后的价格显示在标题NewPriCe下面,结果可能是这样:origina1.pricenewprice19.9939.9811.9523.902.995.9819.9939.98(18row(三)affected)你可以使用大多数标准的数学运算杆来操作字段值,如加(+).减(一).东()和除</),你也可以一次对多个字段进行运算,例如:SE1.ECTprice*ytdsa1.es"tota1.revenue,FROMtit1.es在这个例子中,通过把价格与销售量相乘,计算出了每种书的总辆售额。这个SEUiCT语句的结果将是这样的:tota1.revenue81.859.0546.318,2055.978,7881.859.0540.619.68(18row(三)affected)益后,你还可以使用连接运算符(它看起来像个加号)来连接两个字符型字段:SE1.ECTaufna三e-""+au-1.na三e"authorna三e,FR<!authors在这个例子中,你把字段au_fna«c和字段auBamC格砧在一起.中间用一个逗号展开,并把查询结果的标题指定为authorname.这个语句的执行结果将是这样的:authornamesJohnsonWhiteMarjorieGreenChery1.CarsonMichae1.O'1.caryDeanStraight(23row(三)affected)可以看到SQ1.为你援供了对查询结果的许多控制。你应该在ASP编程过程中充分利用这些优点。使用SQ1.来操作查询结果几乎总是氏使用有同样作用的脚本效率更高。排序查询结果本章的介绍中苜强调过.SQ1.表没有内在的顺序。例如,从一个表中取第二个记录是没有雳义的。从SQ1.的角度看来,没有一个记录在任何其他记录之前.然而,你可以操纵一个SQI.查询结果的漱序.在缺省情况下,当记录从枭中取出时,记荥不以特定的顺序出现,例如.当从表authors中取出字段au_Iname时.专询结果显示成这样:auInameIhiteGrecnCarsonO*1.earyStraight(23row(三)affected)着一列没有特定顺序的名字足很不方便的。如果把这些名字按字母顺序排列,读起来就会容易得多。通过使用ORDERBY子句你可以强制一个查询结果按升序排列,就像这样:SE1.ECTau_InameFROMauthorsORDERBYau_Inane当这个SE1.ECT语句执行时.作者名字的显示将按字母喉序排列。ORDERBY子句将作者名字按升序排列你也可以同时对多个列使用ORDERBY子句,例如,如果你想同时按升序显示字段iwIrunDe和字段inifname,你需要对两不字段都进行排序:SE1.ECTauname,au_fnameFROMauthorsORDERBYau.1.na11>c.au.fnaac这不查询苜先把结果按aunnm。字段进行排序,然后按字段Hkfna三e排序。记录将按如下的顺序取出:au-1.narneau.fnamcBennetAbrahfimRingerA1.beriRingcrAnrWSnithMeander(23row(三)affected)注意有两个作者有相同的名字Ringer。名为A1.bertRinger的作者出现名为AnneRinger的作者之前.是因为姓AIbCrt按字母原序应排在姓Rnne之前。如果你想把受询拮果按相反的顺序排列,你可以使用关键字DESC.关键字DESC把受询结果按得序排列,如下例所示:SE1.ECTauname,a1.fnameEROMauthorsInIEREauIname=*Ringer*ORDERBYuuInaae,aufnameDESC这个查询从表authors中取出所有名字为Ringer的作者记录。ORDERBY子句根据作者的名字和姓.将衣询结果按降序排列。结果是这样的:aufnameAtineA1.bertauInameRingerRinger(2row(三)affeetec)注雳在这个表中.姓AnnC出现在姓AIbCr1.之前。作者名字按降序显示。你也可以按数值型字段对一个查询结果进行排序.例如,如果你想按降序取出所有书的价格,你可以使用如下的SQ1.查询:SE1.ECTpriceFROMtit1.esORDERBYpriceDESC这个SE1.ECT语句从表中取出所有书的价格,显示结果时,价播低的书先显示,价格高的书后显示.不;另1花去时,不管对食阕U排摩,因力抵方缶兀成IJ项工作要费吗力Cj域意味南带可ORDERB1.子句的SE1.ECT语句执行栽来比一般的SE1.ECT语句花的时间长.取出互不相同的记录一不表有可能在同一列中布"重复的值.例如,数据库PUbS的表authors中有甫个作者的名字是Ringer。如果你从这不表中取出所有的名字,名字Ringer将会显示两次。在特定情况下,你可能只有兴建从一个表中取出互不相同的值。如果一个字段有IE复的值,你也许希望毒个值只被选取一次,你可以使用关键字DISnNCr来做到这一点:SE1.CETDISTINCTau_!nameFROMauthorsIHEREau_1.name="Ringer'当这个SE1.ECT语句执行时,只返回一个记录.通过在SE1.ECT语句中包含关键字DIST1.NCT,你可以韧除所有重复的值,例如,假设有一个关于新闾缎信息发布的束,你想取出所有甘在这个新区组中发布信息的人的名字,那么你可以使用关键字DIST1.NCT。每个用户的名字只取一次尽管有的用户发布了不止一储馆息。警告:如同ORDERBY子句一样,强制效劳器返回互不相同的值也会增如运行开错.福气不得不花费一些卅间来完成这项工作.因此,不是必须的时候不要使用关键字DISTINCT,创立新表前面说过,数据庠中的所有数据存储在表中。数据表包括行和列。列决定了表中数据的类型.行包含了实际的数指。例如,数据库PUbS中的表authors有九个字段。其中的一个字段名为为auIname1这个字段被用来存储作者的名字信息。每次向这个表中滋加新作者时.作者名字就被添加到这个字段,产生一条新记录.通过定义字段,你可以创立一个新表。每个字段有一个名字和一个特定的数据类型(数据类型在后面的“字段类Sr一节中科挑),例如字段auIname存储的是字符型数据.一个字段也可以存储其它类型的数据.使用SQ1.Sever,创立一个新未的力法是很多的。你可以可执行一个SQ1.语句或使用SQ1.事务管理信(SQ1.EnterpriseManager)来创立一个新表。在下一节里,你将学会如何用SO1.语句来钮立一个新表.用SQ1.创立新表注意:如果你还没有暧立囱己的数据库,现在就巡回到第三章创立这个库。你渔不能向三astcr,1.eInPdb或任何其他任何系统数指库中添加数据.从SQ1.SeVer程序组(在任务拦中)中启动ISO1.ATE.出现丧询窗口后,从窗口顶部的下拉列米中选择你在第三章所创立的数据库.下一步,在查询由口中俄人下面的SQ1.语句,单击执行查询按钮.执行这个语句:CREATETAB1.Eguestbook(visitorVARCI1.AR(40).counertsTEXT.entrydateDATETIME)如果一切正常,你会在第果窗口中看到如下的文字(如果出现异常,请参回第三章:Thiscommandditnotreturndata.anditdidnotreturnanyrows祝贺你,你巳经度立了你的第一个表!你所创立的表名为euestbook,你可以使用这个表未存储来字你站点访问者的信息,你是用REEATETAB1.E语句创立的这个表.这个语句有两周部:第一部份指定表的名子:第二部份是括在括号中的各字段的名笄和属性,相互之间用型号展开。表guestbook有三个字段:visitor.CQnmentS和entrydate,visitor字段存铭访问者的名字,CommentS字段存储访问者对你站点的意见,entrydate字段存储访问者访问你站点的日期和时间.注意每个字段名后面都果有一个专门的表达式。例如.字段名CommentS后面跟有表达式TEXT。这个表达式指定了字段的数据费型.数据类型决定了一个字段可以存猪什么样的数据。因为字段Coff1.menIS包含文本信息.其数据类型定义为文本型.字段有许多不同的数据类型,下一小节讲述SQ1.所支持的一些至要的战箔类型.字段类型不同的字段类型用来存放不同类型的数据。创立和使用表时,更你应谖理解五肿常用的字段类型:字杆型,文本型,蛾值型,正辑性和日期型。字符型数据字符型蛾据非常有用.当你需要存储短的字符串信息时.你总是要用到字符型数据.例如,你可以把从Hn1.1.ft>E的文本板中搜第到的信息放在字符型字段中。要建立一个字段用来存放可受长度的字符串信息,你可以使用表达式VARCHAR.考虐你前而创立的表Kuestbook:CREATETAB1.Eguestbook(visitorVRIAR(40).co11mentsTEXT.entrydateDATETIME)在这个例子中,字段visitor的数指类型为VAReHAR.注意跟在数据类型后面的括号中的数字.这个数字指定了这个字段所允许存放的字符串的最大长度,在这个例子中,字段YiSitor能存放的字杵由最长为四十个字符.如果名字大长.字符串会被截断,只保存四十个字符。VRRCHAR类型可以存堵的字符串最长为255个字符。要存储更长的字籽串数据,可以使用文本型数据(下一节中讲述).另一种字符型数据用来存储固定长度的字符数据。下面是一个使用这种数据类型的例子:CREATETAB1.ESUCSIbOok(visitorCHRR(40),COn1.nen1.STEXT1CntrydatcDATETIME)在这个例子中,字段ViSitor被用来存储四十个字符的固定长度字符串。表达式CHAR指定了这个字段应该是固定长度的字符串。VARC1.iAR型和CIIAR型数据的这个差异是细徵的,但是非常重要.假设你向一个长度为四十个字符的YARCHAR型字段中输入数招Bi1.1.Cates,当你以后从这个字段中取出此数据时,你取出的战据其长度为十个字符字符串BiI1.GateS的长度。现在俣设你杷字符串输入一个长度为四十个字符的CHAR型字段中,那么当你取出数据时.所取出的数据长度将是旧十个字符.字籽串的后面会祓附加多余的空格.当你建立自己的站点肚,你会发现使用YARCHAR型字段要比CHAR型字段方便的多,使用YARCHAR型字段时,你不需要为剪掉你数据中多余的空格而操心。VARCHAR型字段的另一个突出的好处是它可以比CHRR型字段占用更少的内存和硬盘空间.当你的数据库截大时,这种内存和磁盘空间的节省会变得辛常重要.文本型数据字符型数据限制了字符串的长度不能越过255个字符.而使用文本型数据,你可以存放超过二十亿个字符的字符审。当你需要存储大事的字符时,应该使用文本型教抠.这里有一个使用文本型数据的例子:CREATETAB1.Eguestbook(visitorVARCI1.AR(40).co三mentsTEX1.entrydiiteDATETIME)在这个例子中.字段COimentS裱用来存放访问者对你站点的意见。注意文本型数据没有长度,而上一节中所讲的字符型数据是有长度的.一个文本型字段中的数指通常要么为空,要么很大.当你从HTM1.fMm的多行文本编辑根(TEXTAREA)中收集数据时,你应该把收集的信息存储于文本型字段中.但是.无论何时,只要你能防止使用文本型字段,你就应该不适用它。文本型字段既大且慢,装用文本型字段会使效劳器速度变慢。文本理字段还会吃掉大量的皴盘空间。警告:一旦你向文本型字段中输入了任何数据(甚至是空位),就会有2K的空间被自动分配蛤该数据。除非划除该记录.否则你无法收到这局部存储空间。数值型数据SQ1.SeVer支持许多种不同的敬位型数据.你可以存储婺数、小数、和钱数.通常,当你常要在表中的存放数字时,你要笠用整曼(INT)致格。INT型数据的表效范围是从-2,147,483,647到2,147,483.647的整政。下而是一个如何使用INT型败据的例子:CREATETAB1.Evisit1.og(visitorVARCIWR(40).nu三visitsINT)这个表可以历来记录你站点被访问的次数。只要没有人访问你的站点雇过2,147,483,647次,nubvisits字段就可以存转访问次数.为了节省内存空间,你可以使用sm1.1.int型数据.sma1.1.int型数指可以存偌从32768到32768的整数.这种故掘类型的使用方法与INT型完全相同.最后,如果你实在需要节省空间,你可以使用T1.NYINT型数据。同样,这种类型的使用方法也与INT型相同.不同的是这种类型的字段只能存储从Q到255的整数。TINY三型字段不能用来存储负数。通常,为了节省空间,应该尽可能的使用最小的按型数据.一个T1.NY1.NT型数据只占用一个字节;一个】NT型数据占用四小字节。这看起来似乎娄异不大,但是在比较大的表中,字节数的布长是很快的.另一方面,一旦你已经创立了一个字段,要修改它是很困赊的。因此.为平安显见,你应该慎测以下,一个字段所带要存储的政值最大有可能是多大.然后选择适当的故据类型。为了能对字段所存放的数据有更多的控制,你可以隹用NUMER1.C型数据来同时表示一个数的整数局都和小数局部。NUMER1.e型数先使你能表示非常大的数比INT型数据耍大得多。一个NIMER1.C型字段可以存储从-10”到10”范园内的数。NUMER1.C里数据还使你能表示有小数局部的数,例如,你可以在NuMER1.C里字段中存储小数3.14。又一个NUMER1.C型字段时,你需要同时指定婺数局部的大小和小数局部的大小.这里有一个使用这种数箔类型的例子:CREATETAB1.Enuneric.data(biRnmnbcrWMERIC(28.0),fractionNUMERIC(5.4)当这个潘旬执行时,将创立一个名为numeric_data的包含两个字段的表。字段bignumber可以存储宜到28位的整数。字段fraction可以存能有五位整数局部和四位小数局部的小做。一个MMERIC型致据的整数局部最大只能有28位,小数局部的位数必须小于或等于婪数局部的位数,小数局都可以是零。你可以使用INT型或NwER1.C型数据来存储线金。但是.专门有另外两种般据类型用于牝目的。如果你希望你的网点能挣很多饯.你可以使用money型数据.如果你的野心不大,你可以使用Sma1.uioney型数据。money型数密可以存偌从-922,337,203,685,477.5808到922,337,203,685,477.5807的钱数.如果你需要存储比这还大的金萄,你可以使用NwERIC型数橱.SMA1.1.MoNEY里数据只能存储从-2M.748.3648到214,748.3647的钱效。同样,如果可以的话,你应该用S购1.1.MoNE、.型来代替MONEY型数据.以节名空间。下面的例子显示了如何使用这两种表示线的数据类型:CREATETAB1.Eproducts(productVRIR(40),priceMONEY.DiSCoUnJDriCeSMA1.1.M