下载第8章 ADO 基 础在本书前 7章中,已经讲述了 A S P的有关内容,以及 A S P如何为 We b站点带来动态的内容。
已经见到其脚本程序允许自定义 We b页面,使我们能够构建功能更为强大的 A S P页面。
现在,将研究 A S P和数据的集成。虽然对用于网页中的脚本数量并无任何限制,但如果没有某种形式的数据,很快就会进入一个死胡同。数据构成了 We b站点的实际内容,或者指出了如何设置 We b站点,因此总的说来数据是非常重要的。如果围绕数据存储建立 We b站点,
改变 We b站点时只需要改变相应的数据即可。
A c t i v e X数据对象 ( A D O )是允许用户与数据存储进行交互的组件。这意味着只要基于某些数据就可建立一个网页,或一种完全交互的电子商务系统。不论那种方式,都是 A D O使我们能与数据进行通信。我们将讨论从数据存储获取和传送数据的主要内容,以及得到数据后的数据处理方法。
首先研究什么是 A D O及其所包括的组件,然后讨论如何访问数据存储。在下一章,将进一步学习 A D O更先进的一些特性,如命令、存储过程和优化应用程序的一些操作技巧。下一步研究 We b服务器和浏览器之间的交互过程,以及数据处理过程。然后研究数据存取领域中极具潜力的 X M L。 X M L是什么?如何使用?因为 X M L代表着未来发展的一种趋势,我们将介绍微软关于通用数据存取的构想。在这个构想中,数据不只是从数据库中获得的。最后,看一下标准的微软数据库 (如 A c c e s s与 SQL Server)以及在其中如何使用 A D O。
本章从 A D O开始,主要内容有:
研究 A D O如何与数据进行交互。
了解 A D O的组件。
如何与数据存储连接和创建数据集。
如何处理和修改数据。
如何处理 A D O错误。
8.1 ADO的定义
A D O是一个相当简单的思想,一种让你仅用一种方式去访问数据的思想。 A D O不算一个新思想,仅是采用现有的数据库访问技术,并将其融合而形成的一种适应现在和未来需要的新东西。适应未来的需求是一件十分重要的事。许多其他的技术,比如 D A O和 O D B C,在一些应用程序的开发过程中是可以接受的,然而随着 I n t e r n e t的兴起也出现了其自身的一些问题。
在许多情况下,传统的数据存取方法看上去能解决一些关于两层客户 /服务器系统的问题,
但要求与数据之间要保持一种永久性的连接,并要提供强大的功能,比如快速响应的查询、
数据容易修改等。在 I n t e r n e t领域,现在必须考虑到 We b无状态性本质,和潜在的众多可以访问 We b站点的用户。要与数据建立永久的连接是不现实的,因此必须在设计应用程序时考虑这些因素。
那么,OLE DB和 A D O确切地讲到底是什么?让我们与一些已有的数据存取技术做比较后再来回答这个问题。如果读者曾经接触过数据库编程,或许比较熟悉 O D B C和 R D O。开放数据库连接 ( O D B C )是允许访问关系数据库 (比如 A c c e s s和 SQL Server)的应用程序编程接口
( A P I )。正因为是一个 A P I,许多程序员,特别是 Visual Basic领域的程序员,发现它使用起来很复杂。远程数据对象 ( R D O )是位于 O D B C上层的 A c t i v e X对象,可以提供 O D B C的所有功能,
并且使用起来比较简单。
可以将 OLE DB等同于 O D B C,A D O等同于 R D O。
OLE DB是应用程序与数据源交互的一种基本技术。
这相当复杂,确实也只有 C和 C + +程序员能够使用。正如 A D O的名字所暗示的,它是易于访问 OLE DB功能的 A c t i v e X对象。
你或许发现术语 A c t i v e X与 C O M对象经常混用。对于 A S P程序员来说它们并没有本质上的区别,因为两者都基于 C O M系统结构,只不过 A c t i v e X是组件的一个跨平台标准,而 C O M是 Wi n d o w s专有的。
虽然微软已经引入了一种新的存取数据的技术,但并没有立即取消旧的技术。 O D B C工作起来仍然很有效,并同 OLE DB和 A D O紧密地一起工作着。事实上,O D B C并不只是微软的产品,也受到国际组织的控制。并且由于广泛的使用,O D B C也不会突然消亡。隐藏在 OLE DB
背后的思想不是摒弃现有的技术,而是不断地改进它们。
8.1.1 OLE DB和 A D O的体系结构前面已经给出了 OLE DB与 A D O在一些主要方面的简要解释。图 8 - 1显示了这两项技术与应用程序和数据存储相互关系。
图 8-1 OLE DB,A D O与应用程序和数据存储的关系从图 8 - 1中可以看出整体思路。图的顶端是应用程序 ( We b或常规的应用程序,这是无关紧要的 ),下面是提供对数据的访问的 A D O和 /或 OLE DB。 A D O和 OLE DB两者兼有是因为 O L E
第 8章 ADO 基 础 计计 245下载应用程序脚本数据存储目录服务
D B是一项基本技术。然而,OLE DB并不适用于所有语言,所以 A D O位于 OLE DB的上层,
为那些不能直接访问 OLE DB的语言 (如 Visual Basic和脚本语言 )提供编程接口。 A D O提供了比
OLE DB更容易的编程接口,因此即使那些可以直接使用 OLE DB的编程语言,如 C + +或 J a v a,
也可使用 A D O以简化对数据的访问。
图 8 - 1显示的是微软的编程语言,而 A D O是一个 C O M组件,因此可用于任何与 C O M兼容的编程语言,比如 D e l p h i或支持 Active Scripting接口的脚本语言。所以,虽然 A D O与平台有关,但与开发的语言是无关的。当然,对于 A S P主要使用 V B S c r i p t和 J S c r i p t,在组件中使用
A D O时,有一些 Visual Basic代码。
现在知道了 OLE DB和 A D O允许访问数据,可是为什么需要它们?老方法出问题了吗?
这里有两个主要原因:
首先,OLE DB和 A D O是用来访问数据存储的。注意这里指“数据存储”而不是“数据库” 。尽管数据库仍旧是数据存储最为广泛的形式,但并不一定含有全部的数据。一些消息系统,如 Microsoft Exchange Server,也普遍地用于存储数据。目录服务 (Directory Service)正开始在初露端倪,它们包含着有关用户、机器等的数据; We b服务器中存有大量的信息。可以继续罗列下去,很明显需要一种能访问所有这些不同类型数据的方法。
其次,源于 I n t e r n e t应用程序的兴起与 We b的状态性本质。过去的访问数据的方法主要考虑与数据存储保持永久连接的情况下处理数据。而 OLE DB和 A D O正是为解决这个问题而设计的,提供断开连接的记录集,我们将会在后面看到有关这方面的内容。
8.1.2 消费者与提供者
A D O系统结构图展示了 A D O是如何在应用程序和真实数据存储之间发挥作用的。在微软的文献中,会看到两个易懂的术语:消费者 ( C o m s u m e r )和提供者 ( P r o v i d e r ),但搞清它们的确切定义至关重要。
提供者是提供数据的物体,消费者是使用 (消耗 )这些数据的物体。
在编程中,经常会发现应用程序是数据的消费者。但提供者呢?一般是数据存储,并且由于 OLE DB被设计成用于与不同的数据存储对话,因此对于每一个独特类型的数据存储都有一个 OLE DB提供者。
这种单独提供者的思想并不新,但使编程变得容易了。编写程序与 A D O或 OLE DB对话,
OLE DB再与提供者对话。这意味着只需学会一套访问数据的方法,无论数据如何存储,在某些情况下确实可以完全不改变任何代码而只更换提供者。这就是 A D O和 OLE DB真正优越的地方,为数据存储提供了一套常用的编程接口。
要连接到数据存储,必须使用 OLE DB提供者。提供给 ADO 2.5的初始设置为:
Jet OLE DB 4.0:用于微软 A c c e s s数据库。
DTS Packages:用于 SQL Server的数据转换服务 (Data Transformation Services)。
Internet Publishing:用于访问 We b服务器。
Indexing Services:用于索引目录 (Index Catalogs)。
Site Server Search:用于站点服务器查找目录。
ODBC Drivers:用于 O D B C数据源。
246计计 ASP 3 高级编程 下载
OLAP Services:用于微软 O L A P服务器。
Oracle:用于 O r a c l e数据库。
SQL Server:用于微软 SQL Server数据库。
Simple Provider:用于简单的文本文件。
MSDataShape:用于层次数据。
Microsoft Directory Services:用于 Windows 2000的目录服务。
DTS Flat File:用于 SQL Server的数据转换服务的平面文件管理。
这只是微软提供的初始列表,并取决于安装在服务器上的服务及软件。以 O r a c l e
数据提供者为例,要求在客户机上安装 O r a c l e的客户端软件。
可以从别的制造商那里获得 OLE DB提供者,用于其他数据存储。甚至还可以编写自己的提供者。在第 11章,将演示如何编写简单的 OLE DB提供者。
要想知道系统中安装了哪些提供者,可以使用 Data Link properties对话框。在本章后面,
将介绍如何使用它。
8.1.3 提供者和驱动程序值得注意的是,OLE DB对 O D B C的兼容性,允许 OLE DB访问现有的 O D B C数据源。其优点很明显,由于 O D B C相对 OLE DB来说使用得更为普遍,因此可以获得的 O D B C驱动程序相应地要比 OLE DB的要多。这样不一定要得到 OLE DB的驱动程序,就可以立即访问原有的数据系统。
避免混淆提供者与驱动程序是重要的,图 8 - 2明确了它们之间的区别。
图 8-2 提供者与驱动程序之间的区别提供者位于 OLE DB层,而驱动程序位于 O D B C层。如果想使用一个 O D B C数据源,需要使用针对 O D B C的 OLE DB提供者,它会接着使用相应的 O D B C驱动程序。如果不需要使用
O D B C数据源,那么可以使用相应的 OLE DB提供者,这些通常称为本地提供者 ( n a t i v e
p r o v i d e r )。
可以清楚地看出使用 O D B C提供者意味着需要一个额外的层。 因此,当访问相同的数据时,
第 8章 ADO 基 础 计计 247下载层层针对 O D B C的 OLE DB提供者可能会比本地的 OLE DB提供者的速度慢一些。
8.2 ADO 2.5对象模型虽然在 ADO 2.5对象模型中出现了两个新对象,但与以前的版本基本上是类似的。图 8 - 3
显示了这些对象以及每个对象之间的关系。
图 8-3 对象之间的相互关系如果以前曾使用过 A D O,你会发现在这个新版本中出现了两个新对象,S t r e a m和 R e c o r d
对象。在第 11,1 2章将详细地介绍它们。
P r o p e r t i e s集合已经被有意地排除在图 8 - 3外,这样你对几个主要对象之间的交互关系就一目了然了。在本章的后面,有显示 P r o p e r t i e s集合的简化对象模型。
让我们更详细地考察这几个对象。
8.2.1 Connection对象
C o n n e c t i o n对象是使我们能与数据存储相连的对象。只有 C o n n e c t i o n对象才能指定希望使用的 OLE DB提供者、连接到数据存储的安全细节以及其他任何连接到数据存储特有的细节。
应该注意的是,不必显式创建一个 C o n n e c t i o n对象以连接到数据存储。尽管确实需要指定连接细节,但没有 C o n n e c t i o n对象,一样可以创建 C o m m a n d,R e c o r d s e t和 R e c o r d对象。如果不创建自己的 C o n n e c t i o n对象,A D O将会隐含地为你创建一个 C o n n e c t i o n对象。如果要对提供者运行多条命令,应该显式地创建一个 C o n n e c t i o n对象,这比每运行一条命令就创建一个连接更有效。
除了为数据存储提供连接以外,C o n n e c t i o n对象允许针对数据存储执行命令操作。这些命令可以是结构化的或存储的命令 (例如,S Q L命令或一个存储过程 ),并且可以有选择地从数据存储中返回一些数据。
248计计 ASP 3 高级编程 下载
8.2.2 Command对象
C o m m a n d 对象是对数据存储执行命令的对象。看到这里读者可能会产生疑问,
C o n n e c t i o n对象不也能这样做吗?是的,但是 C o n n e c t i o n对象在处理命令的功能上受到一定的限制,而 C o m m a n d对象是特别为处理命令的各方面问题而创建的。实际上,当从 C o n n e c t i o n
对象中运行一条命令时,已经隐含地创建了一个 C o m m a n d对象。
有时其他对象允许向命令传入参数,但在 C o n n e c t i o n对象中不能指定参数的任何细节。使用 C o m m a n d对象允许指定参数 (以及输出参数和命令执行后的返回值 )的精确细节 (比如,数据类型和长度 )。
因此,除了执行命令和得到一系列返回记录,也可能得到一些由命令提供的附加信息。
对于那些不返回任何记录的命令,如插入新数据或更新数据的 S Q L查询,C o m m a n d对象也是有用的。
8.2.3 Recordset对象
R e c o r d s e t对象是 A D O中使用最为普遍的对象,因为它含有从数据存储中提取的数据集。
我们经常运行不返回数据的命令,比如那些增加或更新数据的命令,但在大多数情况下很有可能会取得一系列记录。
R e c o r d s e t对象是拥有这些记录的对象。可以更改 (增加、更新和删除 )记录集中的记录,上下移动记录,过滤记录并只显示部分内容等等。 R e c o r d s e t对象也包含 F i e l d s集合,F i e l d s集合中有记录集中每一个字段 (列 )的 F i l e d对象。
无论是在 A S P页面中处理数据,还是利用远程数据服务 ( R D S )远程使用数据,R e c o r d s e t对象是必须处理的对象。
8.2.4 Record对象
ADO 2.5以前的版本在处理结构化数据上是很有效的,比如从数据库中取出记录集,但无法处理每一行的列 (也就是列数和数据类型 )可能不同的数据。对于 S Q L数据这不是一个问题,
但对于文件和邮件系统,We b服务器和别的诸如此类的数据存储会如何呢?我们把这些数据看作是半结构化的数据,与记录集相比结构性较差,但与那些常用来代表文本或图像的二进制数据相比更具有结构性。
通常,半结构化数据的存储采用树状结构来组织,有节点、子节点和文件。例如,设想一个有文件夹、子文件夹和文件的 We b站点。图 8 - 4所示的屏幕图显示了一台机器的 We b站点,
特别是还有一个名为 p u b l i c的虚拟目录。
如果一定要在 A D O中进行建模,会觉得这非常适合记录集,可能是嵌套的记录集。然而注意高亮显示的目录,该目录含有不同类型的文件,里面有几个目录、一个 A S P文件、一个文本文件和一个 W O R D文档。你会很容易地将其映射到一个拥有名称、类型、上次存取时间等字段的记录集,遗憾的是并不是这样简单。对于访问权限而言,在文件和目录之间就有区别。对于目录,需要的是能访问目录下的文件;而对于文件,却可能是需要访问其内容。
由于其复杂性,引入了 R e c o r d对象。在上面的情况下,存在有一些相同属性的条目的一个集合,但是每个条目也有独特的属性,因此需要使用别的方法去处理这些数据。把一个集合映射到一个记录集,一个单独的文件映射成一条记录,相应的文件属性就映射成 F i e l d s集合。
第 8章 ADO 基 础 计计 249下载图 8-4 显示了一台机器的 We b站点的界面这意味着有了一个含有九行记录的记录集。访问记录集中单独的一行就会得到该文件的属性 (字段 ),但是提供给我们的仅仅是属性。为了访问文件或目录的内容,需要使用 R e c o r d对象,该对象包含文件或目录的独特属性。习惯于这个概念有一定的困难,但不必担心,在第
11,1 2章你会看到更多的有关 R e c o r d对象的例子。
Windows 2000初始版本发布以来,只有用于 I n t e r n e t发布的 OLE DB提供者使用
R e c o r d对象。一旦微软 Exchange 6.0发布,将成为以类似方法利用记录集和记录提供对 E x c h a n g e信息库访问的 OLE DB提供者。
8.2.5 Stream对象
S t r e a m对象用于访问节点的内容,比如一个 E - M a i l消息,或一个 We b页面。利用 S t r e a m对象可以访问文件或资源的真实内容。因此,结合 R e c o r d和 R e c o r d s e t对象,不仅可以访问 We b
服务器上的文件或 e m a i l消息,还可以访问相应的内容。这样,就可以创建一个只使用 A D O去访问邮件系统的邮件客户。这也许不会有太多的优点,但意味着可不必了解邮件系统的 A P I或对象模型,减少了学习上的弯路。
S t r e a m的另一个用途是 X M L,可以访问一系列作为 X M L流的数据 (结构化或半结构化 )。
S t r e a m对象用来处理二进制数据,所以,可以用来处理 B L O B类型的数据,比如数据库中的图像或大文本数据。
同样,在本书第 11,1 2章中你会看到更多的有关 S t r e a m对象的例子。
8.2.6 集合
A D O对象库中有一些集合,每个集合都有零个或更多个与其关联的对象的拷贝。可以使用相同的代码结构去遍历这些集合:
在 V B S c r i p t中的语法是:
250计计 ASP 3 高级编程 下载
Collection
例如,遍历一个 R e c o r d s e t对象的 F i e l d s集:
如果选择 J S c r i p t,那么可以使用 E n u m e r a t o r对象:
1,Fields集合
F i e l d s集合拥有与记录集或记录关联的 F i e l d对象。对基于结构化数据的记录集,比如 S Q L
数据,字段相应于数据中的列,并含有列的详细内容,比如名称、数据类型、长度等等。在以后几章看到大量的关于 F i e l d s集合的例子。
对于半结构化的数据,对象的属性相应于字段。在第 1 2章会看到更多的相关的介绍。
2,Parameters集合
P a r a m e t e r s集合仅被 Command 对象使用,确定在存储命令中的参数。 S Q L数据库中的存储过程频繁地使用参数,并允许数据传入和传出预先定义的 S Q L语句。如果拥有向 A D O返回信息的参数,则会十分有用,因为这样从存储过程中返回的就不只是一个记录集。例如,考虑一个更新多个表然后返回一个记录集的复杂存储过程,可以用一个输出参数显示更新了多少条记录。
另一个使用参数的理由是性能问题,特别是在仅仅需要从存储过程返回单个值的时候。
在这种情况下,没有创建记录集的必要,只需要保存一个值即可,因而不需要返回记录集,
而返回输出参数的值是更为有效的方法。
在第 9章会看到有关 P a r a m e t e r s集合的详细介绍。
3,Errors集合
E r r o r s集合包含因运行命令而引起的上一次 A D O或 OLE DB提供者错误的详细内容,只能被 C o n n e c t i o n对象访问。可能会觉得这是个限制,因为不必显式定义 C o n n e c t i o n对象,但可以通过 C o m m a n d,R e c o r d s e t和 R e c o r d对象的 A c t i v e C o n n e c t i o n属性访问隐含的 C o n n e c t i o n对象。
例如:
在本章后面,将详细讨论 E r r o r s集合。
4,Properties集合为了避免混乱,P r o p e r t i e s集合没有在前面的对象模型图上加以显示。它与对象模型的关系显示在图 8 - 5中。
P r o p e r t i e s集合存在的原因是因为 A D O是用来处理许多不同的数据存储,都有不同的特征。将属性 ( P r o p e r t y )组成一个集合,可以使之能够动态地根据不同的数据提供者而随时改变。例如,J e t的 OLE DB提供者允许访问 J e t特第 8章 ADO 基 础 计计 251下载图 8-5 Property 与对象之间的关系殊的安全属性:
其他的提供者没有这个属性,因此把它加到 C o n n e c t i o n对象中作为一个静态属性是不明智的。 A D O根据所使用的 OLE DB提供者,会用提供者缺省值填充属性集合。
虽然这里有关于 P r o p e r t i e s集合的使用说明,但在本书中不准备详细叙述
P r o p e r t i e s集合。要获得更多的关于该集合的介绍,请参阅,Professional ADO 2.5
P r o g r a m m i n g》或,ADO 2.5 Programming's Reference》,两者都由 Wr o x出版。
8.2.7 ADO常数当使用 A D O时,会发现有许多预先定义的用于众多选项的常数,比如定义光标类型和锁类型的常数。使用像 Visual Basic或 Visual C++这样的语言,一旦引用了 A D O类型库,自然会用到这些常数。在 A S P中情况不同,有两种选择。
引用常数的第一种方法是把它们包含进 A S P文件:
可以将包含文件拷入本地目录,或者从安装目录引用它,其缺省路径为 C,\ P r o g r a m
Files\Common Files\System\ado(以上文件包含用于 V B S c r i p t的 A D O常数 — 对于 J S c r i p t,应该使用 a d o j a v a s,I n c )。使用这个方法的一点不足是会使 A S P页面变得过大,因为包含了全部的常数,而其中许多是不需要使用的。
可以创建自己的只含有所需要的常数的包含文件,但越来越多地使用 A D O的功能时,很可能会发现需要不断地编辑、维护这个文件。
一个比较好的解决的方法是创建一个对类型库的引用,这种方法不需要将常数包含进
A S P文件而直接可以引用常数:
不要怀疑这个 D L L的名字 m s a d o 1 5,d l l,这是一个正确的名字,包含最新版本的
A D O。
可以在需要的地方把这个 M E TA D ATA语句包含进每一个 A S P文件,或者放入 g l o b a l,a s a文件,这样应用程序中的每个 We b页面都可以引用这些常数。
8.3 连接到数据存储如果需要访问一个数据存储,应该创建一个到数据存储的连接。前面已经提到过:可以显式地创建一个 C o n n e c t i o n对象,或者让 A D O隐含地创建一个连接。对于任何一种方式,都必须知道数据存储的详细内容。
虽然用于连接的实际细节不尽相同,但对于所有类型的数据存储,其连接的实际方法是相同的。这并不令人惊奇,因为不同的提供者需要不同类型的信息。在允许用户访问数据存
252计计 ASP 3 高级编程 下载储之前,一些提供者需要用户的证书,而别的提供者却接受默认的安全证书。
连接到数据源有好几种方法:
连接字符串。在字符串中放入连接的细节,或在打开数据存储时,直接将连接细节加入到命令中。这种方法的优点是连接细节将保留在 A S P页面中。不足之处,如果你有较多的页面,在改变了连接细节时,将陷于繁重的维护工作当中。解决的方法是创建一个包含连接细节的字符串变量,并放进一个 A S P包含文件,这样的话仅仅有一个连接字符串的实例,但能保持与其他的 A S P页面相符。另一个常用的技术就是将应用程序中的连接字符串存储到状态变量中,这样可以被应用程序中的所有页面使用。
数据链接文件。这是一个含有连接细节的文件 (扩展名为,u d l )。优点是对于任何数量的
A S P页面只需要一个数据链接文件。要创建一个数据链接文件,只需创建一个新的文本文件,并重新命名 (要确保 Wi n d o w s资源管理器显示文件扩展名 )。一旦重新命名了该文件,就可以打开它 (双击 )以显示 Data Link Properties对话框。以前版本的 A D O允许从
Wi n d o w s资源管理器的 N e w菜单建立数据链接文件。我们将在本章稍后看到有关数据链接文件的内容。
O D B C数据源,或 D S N。有点类似于数据链接文件,但只适用于 O D B C数据源。它们集中起来用于 A S P页面,数据源必须是系统数据源。 O D B C数据源从 O D B C数据源管理器
(ODBC Data Source Administrator)中创建,这个工具可在 Administrative To o l s文件夹中找到。
这三种方法无论那一种都可以使用,使用那一种只是一种偏爱而已。直接的连接字符串可能速度快一些,因为提供所有的连接细节。数据链接文件需要从文件中读出连接细节,
O D B C数据源需要从注册表中读取连接细节。当然,速度的差异是很小的,每种方法各有优缺点。
8.3.1 连接字符串连接字符串依赖于提供者,因为每个数据提供者可能需要不同的细节。
值得注意的重要一点是,O D B C的 OLE DB提供者是缺省的,所以,如果不使用
Provide = 部分,系统将自动地使用 O D B C。
下面为不同的提供者列举了连接字符串的例子,在本书的后面将会看到更多的例子。
1,微软 A c c e s s
如果使用 O D B C,而没有 D S N:
对于本地的 OLE DB提供者:
上面的例子说明了 A c c e s s数据库存放于 C,\ w r o x目录下。虽然读者可能会尝试将数据库作为 We b文件存放于相同的目录下,但不要这样做,否则任何人都可以下载整个数据库文件。
将数据库存放于 We b目录外永远是明智的,没有人可以从外面访问该文件。
2,微软 SQL Server
对于微软 SQL Server,使用针对 O D B C的提供者:
第 8章 ADO 基 础 计计 253下载例如:
对于本地 OLE DB提供者,语法类似:
例如:
3,微软索引服务索引服务只能通过本地的 OLE DB提供者使用。其语法:
例如,使用 We b目录:
4,ODBC驱动程序在使用针对 O D B C的 OLE DB提供者的例子中,D r i v e r显得较为冗长。例如:
当创建一个新数据源时,使用的驱动程序的准确名字应该是从驱动程序列表中得到的,
如图 8 - 6所示。
5,数据链接文件以前版本的 A D O允许在资源管理器中的目录上右击鼠标来创建一个数据链接文件。创建了新文件后,打开该文件从而得到 Data Link Properties对话框。在写本书的时候,微软已经从鼠标右键菜单中删除了该选项,因为他们觉得这会让用户感到混乱。
但微软声称会提供一个注册表文件以便再次引入这项功能。
不要忘了,也可以简单地通过创建一个空文本文件,并将其扩展名改为,u d l来创建一个数据链接文件。
一旦有了物理上的数据链接文件,就可以通过鼠标双击或者右击鼠标选择 O p e n打开文件。
接下来,读者会看到图 8 - 7所示的对话框。
图中的详细内容因选择的提供者的不同而不同。上面的例子显示了 SQL Server提供者,
连接到一个称为 WAT C H E R的 SQL Server上,以 d a v i d s的身份登录 (口令被屏蔽了 ),使用 p u b s
数据库。注意,如果选择 Allow saving password选项,输入的口令将会在 U D L文件中以明文保存下来。
如果要改变提供者,可以选择,P r o v i d e r”选项卡,如图 8 - 8所示。
通过这个选择,可以选出所需要的提供者,然后按下 N e x t按钮填入适当的连接细节。
也可以在文本编辑器中编辑文件,如图 8 - 9所示。
254计计 ASP 3 高级编程 下载图 8-6 驱动程序列表图 8-9 编辑提供者的界面可以看到在 U D L文件中确实存有一个连接字符串。
要使用数据链接文件,仅需要在打开连接时指定这个数据链接文件:
图 8-10 选择数据源的界面第 8章 ADO 基 础 计计 255下载图 8-7 Data Link Properties对话框 图 8-8 改变提供者的选项卡
6,ODBC数据源
O D B C数据源 (通常称为数据源名称,即 D S N )可以通过 A d m i n i s t r a t i v e菜单的 Data Source选项进行设置。在以前版本的 Wi n d o w s中把它作为控制面板中的一个小程序。为了在 A S P页面中访问 D S N,必须确定该 D S N已被设置为系统 D S N。这只需在 Data Source Administrator中选择
System DSN选项卡,然后选择 A d d按钮,如图 8 - 1 0所示。
然后,就可以选择希望使用的 O D B C驱动程序,并填入适当的 O D B C参数。
一旦建立了 D S N,可以使用连接字符串的,D S N =”属性。例如:
8.3.2 使用包含文件使用包含连接字符串的包含文件提供了一个中心区域来存储许多 A S P页面需要的连接细节。要这样做,仅仅需要创建一个新的 A S P文件,不妨称为 C o n n e c t i o n,a s p,并在其中加入下面的代码:
在 A S P页面中,现在可以在该页的顶端加入这一行:
这样不必再为每个 A S P页面都输入连接细节,同时方便于更改整个站点都使用的连接。
包含文件也是放置 M E TA D ATA标签的好地方。
8.3.3 使用连接状态将连接字符串存入应用程序变量是一个常用的技巧,同使用一个包含文件一样有效。例如,可以在 g l o b a l,a s a文件中加入下面的代码:
在 A S P页面中,可以使用下面的代码:
从个人的角度,我更喜欢使用包含文件的方法,因为我写了许多不同的连接到各种服务器和数据库的例子。使用应用程序方法将意味着每次都必须关闭浏览器重新启动应用程序。
读者可以使用自己喜欢的任一种方法,在速度上它们并没有差别。
对于在本书的这节内的例子,将使用一个含有连接字符串的 c o n n e c t i o n,a s p文件作为一个包含文件。
256计计 ASP 3 高级编程 下载
8.3.4 连接语法上面所叙述的是相关理论,当确实要与数据存储连接时,应该怎么办?如果使用显式定义的 C o n n e c t i o n对象,可以使用 O p e n方法,它的语法如下:
参数如表 8 - 1所示。
表 8-1 Open方法的参数及说明参 数 说 明
C o n n e c t i o n S t r i n g 包含连接细节的字符串。可以是 ODBC DSN的名称、数据链接文件的名称或真实的连接细节
U s e r I D 连接期间,用户使用的名字。覆盖连接字符串中提供的任何用户名
P a s s w o r d 用户的口令。覆盖连接字符串中提供的任何口令
O p t i o n s 可以是 a d A s y n c C o n n e c t,指定异步地建立连接。忽略这个参数,则建立一个同步连接异步连接不用于 A S P环境,因为脚本语言不能接收来自 A D O的事件。
8.3.5 连接的例子下面是几个示例,这里假定 s t r C o n n包含一个有效的连接字符串。
为了打开一个连接,使用 C o n n e c t i o n对象的 O p e n方法。例如:
也可以使用 C o n n e c t i o n S t r i n g属性:
这两种实现方法之间没有什么区别,如果使用前一种方法来实现连接,C o n n e t i o n S t r i n g属性同时也被赋值。
值得注意的是,一旦与数据存储建立了连接,A D O可能会改变 C o n n e c t i o n S t r i n g
属性值。不必担心,A D O只填写一些额外的属性值。
8.3.6 连接缓冲池连接缓冲池 (connection pool)总使许多人感到困惑,其实原理非常简单。当关闭一个连接,
就用户 (和 A D O )而言,这个连接已经关闭。但实际上 OLE DB并没有关闭这个连接,只是将其第 8章 ADO 基 础 计计 257下载放入了非活动的连接缓冲池中。任何时候用户 (或其他人 )打开一个连接,OLE DB首先检测连接缓冲池中是否有相同连接细节的连接存在。如果有,将直接从缓冲池中取得此连接。如果没有,则为用户创建一个新的连接。为了避免浪费资源,经过一段缺省的时间段后,就从缓冲池中清除该连接。
那么,它的优点在哪里?打开一个连接可能是所进行的操作中最慢的操作之一,连接缓冲池使用户能与数据存储再次连接而无须重新创建连接。这对于那些连续打开和关闭大量连接的 We b站点显得特别重要。
对于 O D B C连接,连接缓冲池由 ODBC Data Source Administrator控制。对于
OLE DB,不能改变连接缓冲池 (或叫会话缓冲池 )。
必须注意的是,连接缓冲池不是连接共享。一个连接只有在被客户关闭后才能再次使用。
正在使用的连接 (也就是没有被关闭的 )是不能重新打开的。
内务处理为了使连接缓冲池生效,必须确保内务处理 ( H o u s e k e e p i n g )处于有序状态。这包括及时关闭 C o n n e c t i o n对象,这样它们才能回到缓冲池重新使用。你可能认为不断地打开、关闭连接对系统的开销很大,但必须衡量一下可扩展性 — 你的应用程序可能有许多人在使用,OLE DB
又非常善于管理连接资源。
一般的原则是:尽可能晚地建立连接,同时又要尽可能早地关闭连接,这样保证连接打开的时间段最短。
8.4 记录集前面已经提到,记录集是 A D O中最常用的对象,这并不值得奇怪。毕竟,他们包含着数据。但是,对于记录集还有比想象的更多的内容,知道数据如何保存和处理很重要,因为这为选择使用哪种记录集提供了更多的参考。
记录集有不同的类型,在一些细小的地方存在着差异,很容易造成失误。首先需要认真谈论的是光标的概念。
8.4.1 光标光标 ( c u r s o r )是让许多人感到困惑的概念,但实际上非常的简单。
光标用来管理记录集和记录集的当前位置,后者是由当前记录指针来处理的。
这不是 R e c o r d s e t对象所做的吗?是的,但是记录集也是依靠它的光标。这仍然没有回答光标是什么这个问题,那么先来看一个记录集,如表 8 - 2所示。
表 8-2 一个记录集的例子
A U _ I D A U _ L N A M E A U _ F N A M E P H O N E
1 7 2 - 3 2 - 11 7 6 W h i t e B o b 408 496-7223
2 1 3 - 4 6 - 8 9 1 5 G r e e n M a r j o r i e 415 986-7020
2 3 8 - 9 5 - 7 7 6 6 C a r s o n C h e r y l 415 548-7723
2 6 7 - 4 1 - 2 3 9 4 O ' L e a r y M i c h a e l 408 286-2428
2 7 4 - 8 0 - 9 3 9 1 S t r a i g h t D e a n 415 834-2919
3 4 1 - 2 2 - 1 7 8 2 S m i t h M e a n d e r 913 843-0462
258计计 ASP 3 高级编程 下载这里有六行四列。打开一个记录集,当前记录就是第一个记录,即为 Bob White的那条记录。用什么来标识当前记录?用当前记录指针。那么又如何处理这个指针呢?当需要移到下一条记录或者是其他记录时,是通过光标来实现的。在访问当前行的字段时,光标知道目前位于哪一行,所以能返回正确的值。如果试图移出记录集的最后一行,光标也会处理。
理解光标的一种好方法是将光标想象成为一个可以在记录集内移动的窗口。这一窗口与记录集的单个行同样高,同样长,因此一次只能看到一行数据值。当你移到另一条记录时,
这个窗口也跟着移动。
也许认为这相当简单,但它确实很重要,因为能用光标做什么是由光标的类型决定的。
1,光标类型光标的类型标识了光标所能够提供的功能。这里有四种类型的光标:
静态 ( a d O p e n S t a t i c )。静态光标含有对记录的静态拷贝。这意味着在记录集建立之后,
记录集的内容就固定了。其他用户对记录的更改、添加和删除都是不可见的。允许在记录集中向前、向后移动。
只许前移 ( a d O p e n F o r w a r d O n l y )。缺省的光标类型,除了只允许向前移动外,其余的与静态光标相同。
动态 ( a d O p e n D y n a m i c )。动态的光标没有固定的记录集。其他用户的更改、添加或删除操作在记录集中是可见的。允许在记录集中向前、向后移动。
键集 ( a d O p e n K e y s e t )。键集类型的光标除了记录集是固定的,其余的与动态光标相似。
可以看到其他用户的修改,但新记录却不可见。如果别的用户删除了记录,那么这些记录在记录集中将会变得不可访问。这项功能是通过标识记录集的键来实现的,所以键一直保留着,即使改变或删除记录。
为了理解这些概念,再想相光标窗口。对于只许前移的光标,可以看作是一个位于单向齿轮上的窗口,只能向前移动。这一特点的有利之处在于一旦通过了一条记录,光标就会完全忘记该记录,因为永远不会回到该记录上。静态光标则移去了单向齿轮,允许向后移动;
因为也能向后移动,光标需要跟踪这些记录。由于这个原因,静态光标比只许前移的光标慢。
对于键集和动态类型的光标,窗口可以前后移动,但所看到的内容可能会改变。键集光标可以看到别人对数据的更改,但看不到新的或已删除的记录。因此,记录集是固定的,但不是内容不固定。动态光标将它扩展了,不仅可以改变记录的内容,而且可以改变记录集。
所以在动态光标中能够看到有新的记录出现,同时删除的记录从记录集中消失。
使用的光标类型取决于想达到的目的。如果只想浏览记录,也许是为了创建一个表格或一个选择列表,那么用只许前移的光标是最好不过了。虽然使用其他类型的光标速度可能会慢一些,但也可以正常工作。
光标的类型会影响性能,特别是服务器光标。例如,在微软的 SQL Server 6.5中,键集和静态类型的光标都需要在临时数据库 ( t e m p d b )中放入一个完整的数据拷贝。其中,键集类型的光标相比较而言稍微高效一些,因为它只将键拷入临时数据库。对于 SQL Server 7.0情况不是这样,不同类型的光标的运行效率差别不是很大。
2,光标位置既然已经解释了什么是光标,以及光标如何管理数据,但是光标在哪里呢?答案不是固定的,因为光标依赖于数据存储。某些数据存储,比如微软的 SQL Server,有自身的光标服第 8章 ADO 基 础 计计 259下载务;而别的如微软的 A c c e s s却没有光标服务。
当打开一个记录集时,必须选择是否希望数据存储管理光标,或是否希望 OLE DB和
A D O在本地为你管理光标。后者可以实现是因为 OLE DB有其自己的光标服务。通过使用
C o n n e c t i o n对象或 R e c o r d s e t对象的 C u r s o r L o c a t i o n属性可以设置这两个选项。可以设定该属性的值为:
adUseServer:让数据存储管理光标。
adUseClient:让 A D O管理光标。
可以在打开连接或记录集之前设置这个属性:
或者:
缺省的光标是基于服务器的,理解这两种类型的区别非常重要。对于一个服务器光标来说,数据存储的任务是管理记录,所以,当使用服务器光标建立一个记录集时,数据存储管理着记录的移动、记录的更新等等。
对于一个客户光标,记录集的全部内容复制给客户,受本地客户光标服务管理。这意味着对于一个客户光标,打开一个具有大量记录的记录集要比使用基于服务器的光标打开相同记录集所花费的时间长得多。也有需要使用基于客户的光标的时候,在本书后面,研究组件时,会看到更多的相关的例子。
3.,消防带”光标你可能知道“消防带” ( F i r e h o s e )光标,由于能给应用程序带来高的运行效率,所以对其进行解释显得非常重要。因为“消防带”光标是一种特殊类型的光标,只有在与微软的 S Q L
S e r v e r连接时才出现。 SQL Server创建用户请求的数据集,然后把数据直接传给客户以使其尽可能快地得到数据。 SQL Server自身几乎没有光标管理,这意味着它可以更快地处理数据。
也就是说数据可以在非常短的时间内迅速返回到客户端。从客户方看,类似于只许前移的光标。
那么,在前面讨论光标类型时,为什么没有涉及到“消防带”光标呢?因为这类光标专用于 SQL Server,并仅用于使用基于服务器的光标时。这不是一种真正的光标类型,获得一个“消防带”类型光标的方法就是不指定光标的类型。
8.4.2 锁定我们已经解释了光标和如何管理数据。现在可以创建记录集了吗?恐怕还不行,因为还有一个问题没有讨论,那就是锁定。
锁定就是如何确保数据的完整性,确保更改不会被覆盖。我们需要避免的典型情况是多次更新,比如一个用户改动了一些数据,接着另一个用户立即又将其做了修改。为了对这种情况加以保护,要锁定记录,有许多不同的方法可以保证记录得到保护。可通过锁定类型来设置这些方法。
1,锁定类型锁定类型决定更新记录时记录是否或如何被锁定。有四种类型的锁定:
260计计 ASP 3 高级编程 下载
只读 ( a d L o c k R e a d O n l y ):缺省锁定类型,记录集是只读的,不能修改记录。
悲观的 ( a d L o c k P e s s i m i s t i c ):当修改记录时,数据提供者将尝试锁定记录以确保成功地编辑记录。只要编辑一开始,则立即锁住记录。
乐观的 ( a d L o c k O p t i m i s t i c ):直到用 U p d a t e方法提交更新记录时才锁定记录。
批量乐观的 ( a d L o c k B a t c h O p t i m i s t i c ):允许修改多个记录,只有调用 U p d a t e B a t c h方法后才锁定记录。
当不需要改动任何记录时,应该使用只读的记录集,这样提供者不用做任何检测。对于一般的使用,乐观的锁定可能是最好的选择,因为记录只被锁定一小段时间,数据在这段时间被更新。这减少了资源的使用。
悲观的锁定提高了数据的完整性,但却是以牺牲并发性为代价的。并发性是许多用户在同一时间查阅数据的能力。锁定的记录对其他用户是不可见的,因而数据的并发性降低了。
乐观的锁定只在一小段时间内锁定记录,所以增强了数据的并发性,但同时其他用户修改数据的几率也增加了。
关于并发性和锁定的问题在微软出版的,Inside SQL Server 7.0,(作者 R o n
S o u k u p和 Kalen Delaney)中做了较好的论述。这是一本很权威的专著,所以无论如何应购买这本专著,该书有大量的有价值的资料。
8.4.3 创建记录集创建一个记录集十分容易,通过调用 R e c o r d s e t对象的 O p e n方法来实现:
其参数及说明如表 8 - 3所示。
表 8-3 Open方法的参数及说明参 数 说 明
S o u r c e 数据源。可以是数据库中的表名、存储的查询或过程,S Q L字符串,C o m m a n d对象或适用于提供者的其他命令对象
A c t i v e C o n n e c t i o n 记录集使用的连接。可以是一个连接字符串或者一个打开的 C o n n e c t i o n对象
C u r s o r Ty p e 使用的光标类型。必须是定义的光标类型中的一种,缺省值为 a d F o r w a r d O n l y
L o c k Ty p e 使用的锁定类型。必须是定义的锁定类型中的一种,缺省值为 a d L o c k R e a d O n l y
O p t i o n s 告诉提供者 S o u r c e参数的内容是什么,如表、文本字符串等等例如,要打开数据库 p u b s中 a u t h o r s表上的记录集:
注意,有几个参数没有指定。实际上,所有的参数都是可选的,可以在打开记录集之前第 8章 ADO 基 础 计计 261下载为它们设置相应的属性值:
一旦打开记录集,当前指针自动地位于第一条记录上。如果在记录集中没有记录,那么
E O F和 B O F属性都是 Tr u e:
1,Options参数
O p e n方法的 O p t i o n s参数允许指定命令文本内容。它可以是以下 C o m m a n d Ty p e E n u m常数之一:
adCmdTe x t:文本命令,比如 S Q L字符串。
adCmdTa b l e:表名。
adCmdStoredProc:存储过程名。
adCmdFile:保存的记录集的文件名。
adCmdTa b l e D i r e c t:表名。
adCmdURLBind,U R L地址。
a d C m d Ta b l e与 a d C m d Ta b l e D i r e c t的区别很小,如果想使用表中的全部列,使用
a d C m d Ta b l e D i r e c t将由于 A D O执行了某些内部优化而使运行速度变得稍快一些。
如果没有指定命令的类型,A D O必须推算出执行的命令的类型,这将导致额外的开销。
这里还有两个选项,a d C m d U n s p e c i f i e d表示没有指定类型; a d C m d U n k n o w表示命令的类型未知。一般地可能不会使用它们。
额外的选项
O p t i o n s参数可以是以上常数中的任一个,但也可以加入下列 E x e c u t e O p t i o n E n u m常数:
adAsyncExcute:异步地执行命令。
adAsyncFetch:取得初始的行集后,异步地获取剩下的行。
a d A s y n c F e t c h N o n B l o c k i n g:除了获取记录不阻止命令运行以外,其他与 a d A s y n c F e t c h
相似。
adExecuteNoRecords:命令不返回任何记录。
262计计 ASP 3 高级编程 下载异步处理意味着在后台执行操作,可以运行命令,然后继续其他工作,而不需等待其执行完毕 (同步操作 )。当创建用户界面时,这显得特别方便,因为可以从命令执行中返回,向用户显示一些内容,而同时数据的获取仍然在后台进行。当返回记录集时,这对 A S P程序员来说不是很有用,因为脚本语言不支持 A D O事件,所以记录集何时已完成填充移无法得知。当处理更新、删除或插入数据命令以及不返回记录集的时候,可以使用异步操作,即仅在不关心结果的情况下才能使用。
在另一方面,a d E x e c u t e N o R e c o r d s选项十分有用。它告诉 A D O执行的命令不返回任何数据。所以,就没有必要创建记录集 (总之,可能为空 )。这会加速正在运行的更新或添加数据的查询操作。
为了加入这些选项之一,可以使用 O r符号 (等同于加号,+” )
在下一章,将看到对相关内容更详细的介绍,因为这在处理命令 (而不是记录集 )时会更有用。
2,在记录集中移动一旦打开了一个记录集,经常需要遍历每一条记录。这需要使用 E O F属性。当到达记录集的末尾时,E O F就变为 Tr u e,因此可以这样创建一个循环:
上面的例子一直循环到 E O F属性值为 Tr u e时才退出。 M o v e N e x t方法用于移到下一条记录。
如果记录集允许向后移动,则可以使用 M o v e P r e v i o u s方法。在这种情况下,循环中需要检测 B O F属性值。另外分别还有移动到第一条和最后一条记录的 M o v e F i r s t和 M o v e L a s t方法:
3,使用 F i e l d s集合
F i e l d s集合包含记录集中每一字段 (列 )的 F i e l d s对象。 F i e l d s集合是记录集的缺省集合,因此在访问字段时可以省略,就如同上面的 W h i l e? We n d例子中的情况。因此,有多种访问字段的方法:
第 8章 ADO 基 础 计计 263下载可以使用字段名,或使用它在集合中的位置。使用名字是最好的,因为这样将使代码更易于维护。
Va l u e属性是字段的缺省属性,因此也可以省略,比如:
如果想遍历所有字段,可以使用 For Each结构:
这个例子将打印每一个字段的名字和值。
4,书签当在记录集中移动时,可能需要保留记录的位置,以后再移回来。同真实的书签相似,
一个记录集书签是一个指向单个记录的唯一的指针。
为了使用书签,只需将 B o o k m a r k属性值赋予一个变量:
然后,可以在记录集中移动,以后可以通过相反的命令将记录移到做过书签标记的相应记录上:
在记录集中查找记录时,书签是非常有用的。在本章稍后的 8,4,5节中有一个相关的例子。
注意,并非所有记录集都支持书签,S u p p o r t s方法 (在下面讨论 )将能识别其是否支持书签。
值得注意的重要一点是,不能跨越不同的记录集使用书签,即使这些记录集是用相同的命令创建的。考虑一下以下的代码:
尽管两个记录集是用相同的命令创建的,但记录集的书签是不一样的。
可以使用 C l o n e方法获得可交换的书签,但在这里我们不讨论它。
5,支持的功能如上所述,并非所有的记录集都支持书签。还有许多其他的记录集选项也不是被所有的提供者或记录集类型支持的,因此可以用 S u p p o r t s方法验证一下。
S u p p o r t s方法使用一个或多个 C u r s o r O p t i o n E n u m值作为参数,返回 Tr u e或 F a l s e表明是否支持该选项。这些值的列表相当庞大,所以将其列于附录 F中。
例如:
264计计 ASP 3 高级编程 下载可以使用 O r或加号,+”组合多个常数:
8.4.4 过滤记录集过滤是一种暂时地限定记录集中可见记录的一种方法。如果仅显示记录集中的某些记录,
但又不需要每次都重新查询数据库,这种方法非常有用。
1,使用条件过滤
F i l t e r属性拥有多个参数,其中一个就是条件表达式,它非常像 S Q L中 W h e r e字句:
这个语句限定记录集只显示州名为 c a的记录。使用这个过滤条件将使当前指针回到第一条匹配记录上。可以遍历记录集中的全部记录,并且只有匹配条件的记录才可见。
不仅仅限于单一条件,还可以使用 A n d或 O r把多个条件连接在一起:
这将过滤出姓为 F r a n c i s或 H o m e r的记录。
上面的例子显示了一个列匹配一个值的过滤方法,也可以使用下面操作符中的任何一种:
<,小于。
>,大于。
<=,小于等于。
>=,大于等于。
<>,不等于。
LIKE,通配符。
当使用通配符操作时,可以使用,*”或,%”符号。例如:
,*”或,%”作为一个通配符,匹配任何字符,因此上面的例子会匹配 a u _ l n a m e字段中以,H o”字符开始的所有记录。
可以使用空字符串清空过滤条件,这样将显示全部记录:
2,使用常数过滤
F i l t e r属性也能用 F i l t e r G r o u p E n u m常数作为其参数:
adFilterNone:清空当前过滤条件,与使用一个空字符串的效果相同。
a d F i l t e r P e n d i n g R e c o r d s:只显示那些已改变的,但还没有送到服务器的记录,只在成批更新模式下可用。
a d F i l t e r A ff e c t e d R e c o r d s:只显示那些受上一次调用 D e l e t e,R e s y n c,U p d a t e B a t c h和
C a n c e l B a t c h方法影响的记录。
a d F i l t e r F e t c h e d R e c o r d s:显示高速缓存中的记录,即上一次调用读取记录的命令时的结果。
adFilterConflictingRecords:显示在上一次成批更新中更新失败的记录。
稍后会看到关于成批更新的介绍。
第 8章 ADO 基 础 计计 265下载
3,使用书签过滤最后一种过滤记录集的方法是使用一个书签数组。可以使用这个技术创建一个记录列表,
然后再应用一个过滤条件对其过滤。例如:
当循环至记录集末尾位置时,会发现只有三条记录,因为只有三个书签应用于过滤条件。
注意,不能直接使用数组 a v a r B k m k,必须使用 A r r a y函数将各个书签转换成不同的数组。
8.4.5 查找记录查找单个的记录由 F i n d方法来完成。它类似于使用条件的过滤方法:
它们之间最主要的区别在于这种方法只能有一个条件,不允许使用 A n d或 O r。
可以使用可选的参数指定一些额外的选项,其完整的语法如下:
S k i p R o w s是一个数字,表示在开始查找记录前跳过的行数。缺省为 0,查询从当前行开始。
S e a r c h D i r e c t i o n可以是 a d S e a r c h F o r w a d,表示向前搜索记录;或者 a d S e a r c h B a c k w a r d,表示向后搜索记录。
S t a r t是一个书签,指出开始查找记录的位置。
如果找到相应的记录,当前指针将位于匹配的记录上,如果没有找到记录,那么将位于下面两个位置中的一个:
如果是向前搜索,则位于记录集末尾位置的后面,E O F被设置为 Tr u e。
如果是向后搜索,则位于记录集开始位置的前面,B O F被设置为 Tr u e。
使用书签保存位置如果没有找到相应的记录,记录的重新定位可以由书签轻松解决,因为可以为当前位置
266计计 ASP 3 高级编程 下载制作书签,如果在查找记录过程中没有找到所需的记录,那么再移回到上次保存的位置。
例如:
使用 F i l t e r属性强于 F i n d方法的一个原因是 F i n d语句只能指定一个查询条件,而 F i l t e r属性允许指定多个条件。也就是说,当想要查找的字段条件不止一个时,不能使用 F i n d方法。然而,可以先过滤记录,如果找到记录可以再删除过滤条件。
8.4.6 修改记录大部分的 We b只用来显示信息,而 We b应用程序正变得越来越普通。在这种情形下,如果只拥有只读数据确实没有什么用处。创建一个应用程序,几乎总是需要修改现存的数据或是添加新的数据,其方法有许多。在本节,将学习如何使用 R e c o r d s e t对象的方法来更改数据。
在下一章,将会看到如何使用查询完成相同的任务。
可以设置除了 a d L o c k R e a d O n l y之外的锁定类型,配合使用 R e c o r d s e t对象的方法去修改数据 (假定有相应的权限 )。记住,缺省的锁定类型是只读的。
1,添加记录要在记录集中添加记录,使用 A d d N e w方法。有两种使用 A d d N e w的方法。第一种没有任何参数,仅仅调用 A d d N e w,在记录集的最后添加一个空记录。在调用 U p d a t e方法保存所做的更改之前,可以随意地修改字段中的数据:
这只是添加了一条新纪录,设置四个强制型的字段值。
另一种方法是使用 A d d N e w方法的可选参数,这是两个数组,一个是字段名,另一个是字段的值。
第 8章 ADO 基 础 计计 267下载这个方法不需要调用 U p d a t e方法。
2,编辑记录编辑记录与添加记录的方法相似,不同之处在于不需要调用 A d d N e w方法:
这仅仅是将当前记录 (在这种情况下是第一条记录,因为刚刚打开记录集 )的 c o n t r a c t字段的值赋为 1。
3,删除记录删除记录需调用 D e l e t e方法。删除哪一条记录取决于可选的参数,可以是下面 A ff e c t E n u m
常数中的一个:
adAff e c t C u r r e n t:删除当前记录,缺省操作。
adAff e c t G r o u p:删除匹配当前过滤条件的所有记录。
adAf f e c t A l l:删除记录集中的全部记录。
adAf f e c t A l l C h a p t e r s:删除所有段 ( c h a p t e r )中的记录。
最简单的调用形式是:
这将删除当前记录。如果有一个过滤条件,并想删除所有匹配该条件的记录,那么仅需加上适当的常数:
4,自动递增的字段当添加一条新记录时,一般会碰到这样一个问题:如何处理那些自动递增的或标识字段
(Identity Filed)。这些字段是由服务器自动更新的数字字段,一般用于为每一行提供一个唯一的字段值。当数据库含有多个表时,那么这个唯一的字段经常被当作关联表的外键。所以,
添加一条新记录时,经常需要找出它们的值。
例如,考虑一下有两个字段的表,一个自动递增的 I D字段 (SQL Server中的 I D E N T I T Y字段或 A c c e s s中的 A u t o N u m b e r字段 ),一个字段名为 N a m e的文本字段。现在考虑一下下面的向表中添加记录的代码:
268计计 ASP 3 高级编程 下载看上去很平常,但添加记录后是否能够取到这个值依赖于光标的类型、锁定的类型以及
I D字段是否被索引。表 8 - 4列出了哪些组合允许获取新插入的 I D字段的值。其他没有列在表中的组合不能返回 I D字段的值。
表 8-4 获取 I D字段的值与光标、锁定的类型及 I D字段是否被索引的关系提 供 者 对 象 索 引 光 标 位 置 光 标 类 型 锁 定 类 型
O D B C Access 97 是 服务器 键集 悲观型乐观型
Access 2000 是 服务器 键集 悲观型乐观型否 客户 所有 悲观型乐观型
SQL Server 6.5 是 服务器 键集 悲观型乐观型
SQL Server 7.0 是 服务器 键集 悲观型乐观型客户 所有 悲观型乐观型否 客户 所有 悲观型乐观型
Jet 4.0 Access 97 是 服务器 所有 所有
Access 2000 是 服务器 所有 所有否 客户 所有 悲观型乐观型
SQL OLE DB SQL Server 6.5 是 服务器 键集 悲观型
SQL Server 7.0 乐观型客户 所有 悲观型乐观型否 客户 所有 悲观型乐观型这清楚地说明必须使用正确的组合,才能保证能取得 I D字段的正确值。否则,可能会得到 0、空值或 N U L L,这取决于组合的方式。
在下一章中处理存储过程时,将见到另一种从 SQL Server中获取 I D E N T I T Y字段值的方法。
8.5 管理错误处理数据存储时,发生错误的可能性总是存在的:安全性问题,试图更新已被其他用户删除的记录,诸如此类的问题很多。不能保证一切都运行良好,因此必须构建某种形式的错误控制。
在第 7章,研究了 A S P页面中一般的错误处理,但现在涉及的是数据存储,所以必须考虑使用额外的代码进行错误处理。先看一下 E r r o r s集合,再讨论其如何满足 ASP 3.0的错误处理机制。
8.5.1 Errors集合
E r r o r s集合包含由单个 A D O命令的执行而引起的每一个错误的 E r r o r对象。使用 E r r o r s集合的原因是由于在一个命令的执行过程中,可能会引起多个错误,OLE DB提供者需要提供一种方式通知客户方已有多个错误发生。
关于 E r r o r s集合有两个重要的地方需要注意:
第 8章 ADO 基 础 计计 269下载
每次执行 A D O命令,如果发生错误,就清空错误集,同时代之以新的错误内容。当然,
如果没有错误发生,E r r o r s集合不会受到影响。所以,即使 A D O命令成功执行,这个集合中也可能含有错误信息。
OLE DB提供者可能会将包含信息的消息或警告装入 E r r o r s集合,错误号为 0。所以不能只检查集合中的错误号而假定错误已经发生。比如,使用 O D B C提供者与 SQL Server连接,可能会得到一个“错误”,告知缺省的数据库已经被改变了。
如果回头看一下本章开始讲到的对象模型,可能会发现 E r r o r s集合只能由 C o n n e c t i o n对象访问。读者可能会觉得奇怪,如果不显式地创建一个 C o n n e c t i o n对象,如何访问 E r r o r s集合?
R e c o r d s e t对象有一个 A c t i v e C o n n e c t i o n属性,含有当前记录集的 C o n n e c t i o n对象,这意味着可以这样得到 E r r o r s集合:
如果想看发生的全部错误,则需要遍历整个 E r r o r s集合:
为了显示一些合理的错误信息,需要确切地知道在 E r r o r s集合中到底有些什么。
E r r o r对象包含表 8 - 5所示的属性。
表 8-5 Error对象的属性及说明属 性 说 明
N u m b e r A D O错误号
N a t i v e E r r o r 从数据提供者获得的错误号
S Q L S t a t e 连接到 S Q L数据库时,5位的 S Q L状态代码
S o u r c e 引起错误的对象
D e s c r i p t i o n 错误说明文本这意味着循环过程现在可以变成这样:
8.5.2 ASP页面中的 A D O错误在第 4,7章,我们研究了 A S P的错误,以及如何简洁并彻底地处理这些错误。 ASP 3.0的一个新特征就是自定义错误页面,但这对于 A D O确实用处不大,因为脚本中的变量无法传入自定义的错误页面。这就意味着我们无法检测 E r r o r s集合。
面对这样的情况,必须提供自己的错误处理。如果你使用 J S c r i p t作为服务器端编程语言,
那么你将拥有新的 t r y / c a t c h特性,但是 V B S c r i p t对于错误的处理仍然有许多不足。目前,最好的检测错误的方法是使用 On Error Resume Next语句,然后在可能会引起错误的每一行 A D O代
270计计 ASP 3 高级编程 下载码后检查 E r r o r s集合。就像这样:
这里可使用 C h e c k F o r E r r o r s子程序来检测是否有错误发生:
第 8章 ADO 基 础 计计 271下载这个程序检测是否有错误,如果有,则为每一个错误创建一个表格,并给出了如图 8 - 11
所示的结果。
图 8 - 11 显示的错误结果这并不是一个技术含量较高的解决方案,但确实是用 V B S c r i p t所能做到的最好的解决方案。真正的不足是必须自己检测错误。
8.6 小结本章讨论了许多内容,包括下面几个重要的方面:
ADO如何配合 A S P。
记录集结构基础。
如何访问一些基本的数据存储,如何处理从数据存储中取得的数据。
如何管理数据存取时的错误。
现在,应该扩展基础知识,研究 C o m m a n d对象,理解如何使用一些高级特性去改进性能和维护 A S P页面。
272计计 ASP 3 高级编程 下载