Microsoft Active X Data Objects (ADO) 开始页

ActiveX Data Objects 2.5 开始页

ADO
版本 2.5

目的

Microsoft ActiveX Data Objects (ADO) 使您的客户端应用程序能够通过 OLE DB 提供者访问和操作数据库服务器中的数据。它的主要优点是易于使用、速度快、内存支出低和占用磁盘空间少。ADO 支持用于建立客户端/服务器和基于 Web 的应用程序的主要功能。

RDS

ADO 的功能还包括远程数据服务 (RDS)，通过该服务可以在一次往返过程中将数据从服务器移动到客户端应用程序或网页上，并在客户端对数据进行处理，然后将更新结果返回给服务器。

ADO MD

Microsoft ActiveX Data Objects (Multidimensional) (ADO MD) 提供通过多种语言（如 Microsoft Visual Basic、Microsoft Visual C++ 和 Microsoft Visual J++）访问多维数据的便捷方式。ADO MD 扩展了 Microsoft ActiveX Data Objects (ADO)，使之包括专用于多维数据的对象，如 CubeDef 和 Cellset 对象。用 ADO MD 可以浏览多维模式、查询立方和检索结果。

同 ADO 一样，ADO MD 用基本的 OLE DB 提供者来访问数据。要使用 ADO MD，提供者必须是由 OLE DB for OLAP 规范定义的多维数据提供者 (MDP)。与用表格视图方式显示数据的表格数据提供者 (TDP) 相反，MDP 以多维视图方式显示数据。有关提供者支持的特定语法和行为的详细信息，请参阅 OLAP OLE DB 提供者的文档。

ADOX

Microsoft ActiveX Data Objects Extensions for Data Definition Language and Security (ADOX) 是对 ADO 对象和编程模型的扩展。ADOX 包括用于安全性以及创建和修改模式的对象。因为它是基于对象的模式操作方法，所以用户可以编写在各种数据源上都能运行的代码，而不必考虑它们原生语法的差异。

ADOX 是核心 ADO 对象的扩展库。它提供的附加对象可用于创建、修改和删除模式对象，如表和过程。它还包括安全性对象，可用于维护用户和组，并授予和取消对对象的权限。

ADO 2.5 的主要组件

程序员指南

ADO、RDS、ADO MD 和 ADOX 使用简介。

程序员参考

ADO 文档的本节包含关于每个 ADO、RDS、ADO MD 和 ADOX 对象、集合、属性、动态属性、方法、事件和枚举的主题。

反馈

可以将对 ADO 文档或范例的反馈直接发送给 ADO 文档组。

请参阅

  • ADO Technical Articles
  • OLE DB

© 1998-2003 Microsoft Corporation。保留所有权利。


ADO 程序员指南

要了解对《Microsoft ActiveX Data Objects (ADO) 程序员指南》的简介，请参阅以下主题：

  • 简介
  • ADO 的新增内容
  • 前提条件
  • 组成 ADO 家族的库
  • Microsoft Data Access 中 ADO 的角色
  • ADO 任务表
  • ADO 技术表


简介

ADO 程序员指南已经编制完成，其目的是要帮助作为 ADO 新手的开发人员，给他们提供一个对此技术的全面介绍。该指南描述了 ADO 家族的库，并使用各种语言的范例代码解释了如何使用库、使用库的最佳做法以及让 ADO 应用程序发挥最大化性能的提示和技巧。

ADO 程序员指南包含以下章节：

  • 第 1 节：ActiveX Data Objects (ADO)
    • 第 1 章：ADO 基础
    • 第 2 章：获得数据
    • 第 3 章：检查数据
    • 第 4 章：编辑数据
    • 第 5 章：更新和持久保留数据
    • 第 6 章：错误处理
    • 第 7 章：处理 ADO 事件
    • 第 8 章：理解游标和锁定
    • 第 9 章：数据构形
    • 第 10 章：记录和流
  • 第 2 节：远程数据服务 (RDS)
    • 第 11 章：RDS 基础
    • 第 12 章：RDS 教程
    • 第 13 章：RDS 用法和安全
  • 第 3 节：ActiveX Data Objects (Multidimensional)(ADO MD)
    • 第 14 章：ADO MD 基础
  • 第 4 节：ActiveX Data Objects Extensions for Data Definition Language and Security (ADOX)
    • 第 15 章：ADOX 基础
  • 第 5 节：附录
    • 附录 A：提供者
    • 附录 B：ADO 错误
    • 附录 C：使用 ADO 编程
    • 附录 D：ADO 范例
  • ADO 词汇表


ADO 的新增内容

ADO 2.5 版本中包含下列新功能以及改进的文档。此列表包含 ADO、ADO MD 和 ADOX。

新功能

Record 和 Stream

此版本的 ADO 引入了 Record 对象，它可以表示和管理诸如文件系统中的目录和文件、电子邮件系统中的文件夹和邮件之类的内容。Record 还可以表示 Recordset 中的一行，尽管 Record 和 Recordset 对象具有不同的方法和属性。

新的 Stream 对象提供了一种方式，用于读取、写入和管理组成文件或消息流的字节或文本的二进制流。

URL 的用法

此版本还引入了统一资源定位符 (URL)，它可以作为连接字符串和命令文本的替代品，用来命名数据存储对象。URL 可与现有的 Connection 和 Recordset 对象以及新的 Record 和 Stream 对象一起使用。

使用此版本，ADO 支持能识别自身 URL 模式的 OLE DB 提供者。例如，访问 Windows 2000 文件系统的 OLE DB Provider for Internet Publishing，可以识别现有的 HTTP 模式。

用于文档源提供者的特殊字段

称为“文档源”提供者的一类特殊提供者，用于管理文件夹和文档。当 Record 对象表示文档或者 Recordset 对象表示文档的文件夹时，文档源提供者使用一组描述文档特性的唯一字段预置这些对象。这些字段组成“资源”Record 或 Recordset。

新参考主题

此版本包含下列新属性。

属性 | 说明
Charset | 指示字符集，文本 Stream 对象的内容将被转换到该字符集中。
EOS | 指示当前位置是否在流的结尾处。
LineSeparator | 指示要在文本 Stream 对象中用作分行符的二进制字符。
Mode | 指示在 Connection、Record 或 Stream 对象中修改数据的有效权限。
ParentURL | 指示指向当前 Record 对象的父 Record 的绝对 URL 字符串。
Position | 指示在 Stream 对象中的当前位置。
RecordType | 指示 Record 对象的类型。
Size | 指示流的字节数。
Source | 指示由 Record 对象表示的项目。
State | 对所有适用的对象，指示该对象状态是打开的还是关闭的。 对执行异步方法的所有适用的对象，指示该对象的当前状态是正在连接、执行还是检索。
Type | 指示 Stream 对象中包含的数据类型（二进制或者文本）。

此版本包含下列新方法。

方法 | 说明
CopyRecord | 把文件或目录（及其内容）复制到另一个位置。
CopyTo | 把 Stream 对象中指定数目的字符或字节（取决于 Type）复制到另一个 Stream 对象。
DeleteRecord | 删除文件或目录（及其所有子目录）。
Flush | 将保留在 ADO 缓冲区中的 Stream 对象的内容强制到与 Stream 对象相关联的基本对象上。
GetChildren | 返回 Recordset，其中的行表示文件或子目录，这些文件和子目录位于由 Record 表示的目录中。
LoadFromFile | 将现有文件的内容加载到 Stream 对象中。
MoveRecord | 把文件或目录（及其内容）移动到另一个位置。
Open | 打开现有的 Record 对象，或者创建新的文件或目录。
Open | 打开 Stream 对象来操作二进制或文本数据的流。
Read | 从二进制 Stream 对象读取指定的字节数。
ReadText | 从文本 Stream 对象读取指定数目的字符。
SaveToFile | 把 Stream 的二进制内容保存到文件。
SetEOS | 设置流的结尾位置。
SkipLine | 读取文本 Stream 对象时跳过一整行。
Write | 将二进制数据写入 Stream 对象。
WriteText | 将指定的文本字符串写入 Stream 对象。

新增和改进文档

代码范例主题

增加了新的范例，包括用 Microsoft Visual C++® 和 Microsoft Visual J++® 编写的代码。可以将这些代码范例复制并粘贴到您的编辑器中。

提供者主题

包括一个新的主题，介绍如何将 ADO 与 OLE DB Provider for Internet Publishing 配合使用。

ADO 编程

此新章节包含通过各种编程语言使用 ADO 的提示和技巧。包含 Visual C++ Extensions for ADO 和 ADO/WFC 的现有语法索引，以及专门为使用 Microsoft Visual Basic®、Microsoft Visual Basic® Scripting Edition、Microsoft Jscript®、Microsoft Visual C++ 或 Microsoft Visual J++ 的开发人员提供的新信息。

© 1998-2002 Microsoft Corporation。保留所有权利。


前提条件

事实证明，《ADO 程序员指南》对于具有各种背景的开发人员都是有用的。读者至少应当有用 Microsoft Visual Basic 开发应用程序的中等水平的经验，因为指南中的大多数范例都是用该语言编写的。其他范例则是用 Microsoft Visual C++、Java、Visual Basic、Scripting Edition (VBScript) 和 Microsoft JScript 编写的。

由于 ADO 用于访问各种数据源中的数据，因此读者可能还需要对这些知识有一定的理解：基本的关系数据库管理系统概念、联机分析处理（OLAP）概念和基本的 Internet 和 Internet 协议知识。

ADO 是 Microsoft Data Access（UDA）策略的一部分。（有关 UDA 的详细信息，请参阅本章后面的 “ADO 在 Microsoft Data Access 中的角色”）。同样，它 OLE DB 技术有互操作关系。OLE DB 基于 Microsoft 组件对象模型 (COM)。因此，熟悉 COM 也会有助于理解 ADO 中的某些更高级的概念。


组成 ADO 家族的库

三个主要的库组成了 ADO 家族：ADO（包括 RDS）、ADO MD 和 ADOX。

ADO

ADO 使客户端应用程序能够通过 OLE DB 提供者访问和操作数据库服务器中的数据。它的主要优点是易于使用、速度快、内存支出低和占用磁盘空间少。ADO 支持用于建立客户端/服务器和基于 Web 的应用程序的主要功能。

ADO 的功能还包括远程数据服务 (RDS)，通过该服务可以在一次往返过程中将数据从服务器移动到客户端应用程序或网页上，并在客户端对数据进行处理，然后将更新结果返回给服务器。

ADO MD

Microsoft ActiveX Data Objects (Multidimensional) (ADO MD) 提供了通过各种语言（例如 Microsoft Visual Basic、Microsoft Visual C++ 和 Microsoft Visual J++）很方便地访问多维数据的功能。ADO MD 扩展了 ADO，使 ADO 包括了专用于多维数据的对象，例如 CubeDef 和 Cellset 对象。使用 ADO MD，可以浏览多维模式、查询立方和检索结果。

同 ADO 一样，ADO MD 用基本的 OLE DB 提供者来访问数据。要使用 ADO MD，提供者必须是由 OLE DB for OLAP 规范定义的多维数据提供者 (MDP)。与用表格视图方式显示数据的表格数据提供者 (TDP) 相反，MDP 以多维视图方式显示数据。有关提供者所支持的特定语法和行为的详细信息，请参阅 OLE DB for OLAP 提供者的文档。

ADOX

Microsoft ActiveX Data Objects Extensions for Data Definition Language and Security (ADOX) 是对 ADO 对象和编程模型的扩展。ADOX 包括用于安全性以及创建和修改模式的对象。因为它是基于对象的模式操作方法，所以用户可以编写在各种数据源上都能运行的代码，而不必考虑它们原生语法的差异。

ADOX 是核心 ADO 对象的伴随库。ADOX 提供的附加对象可用于创建、修改和删除模式对象，如表和过程。ADOX 还包括安全性对象，可用于维护用户和组，并授予和取消对对象的权限。

请参阅

第 1 节：ActiveX Data Objects (ADO) | 第 2 节：远程数据服务 (RDS) | 第 3 节：ADO (Multidimensional) (ADO MD) | 第 4 节：ADO Extensions for Data Definition Language and Security (ADOX)


ADO 在 Microsoft Data Access 中的作用

Microsoft Data Access Components (MDAC) 提供与数据存储、工具和语言无关的数据访问。它为几乎任何可用的数据存储提供高级别、易于使用的接口和低级别、高性能的接口。您可利用这一灵活性集成各种数据存储，并根据需要，通过所选择的工具、应用程序和平台服务来创建适当的解决方案。这些技术为在 Microsoft Windows 操作系统中的常规用途的数据访问提供了基本的框架。

在 MDAC 中有三种主要技术。ActiveX 数据对象 (ADO) 是一个高级的、易于使用的与 OLE DB 的接口。OLE DB 是一个低级的、高性能的接口，用来实现与各种数据存储的连接。ADO 和 OLE DB 均可处理关系（表格）和非关系（分级或流）数据。最后，开放式数据库互连 (ODBC) 是另一个专门为关系数据存储设计的低级的、高性能的接口。

ADO 为客户端或中间层应用程序与低级别的 OLE DB 接口之间提供了一个抽象层。ADO 利用一小组 Automation 对象提供到 OLE DB 的简单而有效的接口。该接口使得 ADO 成为使用高级语言（例如 Visual Basic 甚至是 VBScript）的开发人员的最佳选择，因为他们无须学习复杂的 COM 和 OLE DB 知识即可访问数据。


ADO 任务表

下表列出了包含在《ADO 程序员指南》中的编程任务，并为每个任务提供了参考。这些参考都是文本说明或代码范例，您可在其中看到有关执行任务的 ADO 功能的信息。

ADO 任务 | 参考
连接数据提供者 | 建立连接
执行命令或调用存储过程 | 使用 Command 对象
打开 Recordset | Recordset 对象的 Open 方法
确定 Recordset 的大小 | 对行计数和记录集的限制
移动到某个特定记录 | 导航数据
访问列值 | Fields 集合
搜索数据 | 使用 Recordset
修改数据并更改值 | 编辑现有记录
添加新数据 | 添加记录
删除数据 | 使用 Delete 方法删除记录
将更改传递到数据源 | 更新数据
开始、提交并回卷事务 | 事务处理
将记录存储到文件（XML 或二进制) | 保持数据
处理错误 | ADO 错误
处理事件，异步编程 | ADO 事件处理程序汇总
选择游标位置和类型 | 游标的类型
选择锁定类型 | 锁定类型
返回 Recordset 中的相关记录 | 数据构形汇总
访问半结构化数据 | Chapter 10: Records and Streams
发布到 IIS | 使用 ADO 进行 Internet 发布


ADO 技术表

下表列出了在《ADO 程序员指南》中论述的 Microsoft 产品、工具和技术。它还在可能的地方提供了与指南中相关主题的链接。

Microsoft 产品或技术 | 参考
Access/Jet | 使用 Recordset 第 15 章：ADOX 基础 Microsoft Jet 和复制对象 OLE DB Provider for Microsoft Jet
Active Directory Service Interfaces | Microsoft OLE DB Provider for Microsoft Active Directory Service
COM/DCOM | 必备条件 将业务对象标记为可安全执行脚本 在客户端注册业务对象以便配合 DCOM 使用 设置 DCOM 流调度格式 启用 DLL 以在 DCOM 上运行 在 Component Services 中运行业务对象
FrontPage | Microsoft OLE DB Provider for Internet Publishing
Indexing Service | Microsoft OLE DB Provider for Microsoft Indexing Service
Internet Explorer | Internet Explorer 错误代码
Internet Information Services | Chapter 10: Records and Streams 流和持久性 使用 ADO 进行 Internet 发布 远程数据访问的解决方案 在 IIS 上配置虚拟服务器 在 IIS 上指定每个处理程序的线程数 保护 RDS 应用程序 “Internet 服务器错误：访问被拒绝” Microsoft OLE DB Provider for Internet Publishing Internet Information Services 错误代码
JScript | 处理其他编程语言的错误 JScript ADO 编程 Microsoft JScript 中的 ADO 代码示例
ODBC | ADO 在 Microsoft Data Access 中的作用 使用 Connection 对象 将 RDS 与 ODBC Connection Pooling 配合使用 Microsoft OLE DB Provider for ODBC
OLE DB | ADO 在 Microsoft Data Access 中的作用 OLE DB 服务 附录 A：提供者 提供者错误
Oracle | Microsoft OLE DB Provider for Oracle
SQL Server 2000 | 控制事务 使用命令调用存储过程 对行计数 仅向前游标 Command 流 确保足够的 TempDB 空间 最小化日志文件空间的使用 Microsoft OLE DB Provider for SQL Server
Transaction Server | 在 Component Services 中运行业务对象
VBScript | 处理其他编程语言的错误 Visual Basic for Applications 函数 Command 流 远程数据访问的解决方案 RDS 方案 RDS 教程 (VBScript) VBScript ADO 编程 Microsoft Visual Basic Scripting Edition 中的 ADO 代码范例
Visual Basic | 错误 ADO 错误 不同语言的 ADO 事件实例 Visual Basic for Applications 函数 Chapter 12: RDS Tutorial 通过 Microsoft Visual Basic 使用 ADO Microsoft Visual Basic 中的 ADO 代码范例
Visual C++ | 处理其他编程语言的错误 不同语言的 ADO 事件实例 通过 Microsoft Visual C++ 使用 ADO Microsoft Visual C++ 中的 ADO 代码范例
Visual J++ | 处理其他编程语言的错误 不同语言的 ADO 事件实例 RDS 教程 (Visual J++) 通过 Microsoft Visual J++ 使用 ADO Microsoft Visual J++ 中的 ADO 代码范例
Visual Studio | 附录 D: ADO 范例
Windows 2000 | 地址簿应用程序的系统需求 授予 Web 服务器计算机客户特权 注册自定义业务对象 保护 RDS 应用程序 在 Windows 2000 上配置 RDS
XML | 以 XML 格式持久保持记录 Chapter 10: Records and Streams Command 流 将结果集检索到流


第 1 节：ActiveX Data Objects (ADO)

本节包含以下章节：

  • 第 1 章：ADO 基础
  • 第 2 章：获取数据
  • 第 3 章：检验数据
  • 第 4 章：编辑数据
  • 第 5 章：更新和保持数据
  • 第 6 章：错误处理
  • 第 7 章：处理 ADO 事件
  • 第 8 章：理解游标和锁定
  • 第 9 章：数据构形
  • 第 10 章：记录和流


第 1 章：ADO 基础

本章是对 ADO 库的简介。本章讨论可以用 ADO 做什么，然后审阅 ADO 层次结构中的对象，之后提供了一个简单的 ADO 应用程序，该程序使用了很多 ADO 对象来检索、编辑和更新来自数据源的数据。最后，本章讨论了两个对于编写 ADO 应用程序必须理解的重要问题：OLE DB 提供者和错误。


使用 ADO 能做些什么

ADO 的设计旨在为开发人员提供一个强大的逻辑对象模型，以便他们通过 OLE DB 系统接口以编程方式访问、编辑并更新各种各样的数据源。ADO 最普遍的用法就是在关系数据库中查询一个表或多个表，然后在应用程序中检索并显示查询结果，可能还允许用户更改并保存数据。通过编程使用 ADO 还可执行其他任务，包括：

  • 使用 SQL 查询数据库并显示结果。
  • 通过 Internet 访问文件存储中的信息。
  • 操作电子邮件系统中的消息和文件夹。
  • 将来自数据库的数据保存在 XML 文件中。
  • 允许用户查看数据库表中的数据并进行更改。
  • 创建并重新使用参数化的数据库命令。
  • 执行存储过程。
  • 动态创建称作 Recordset 的灵活结构，以保持、浏览和操作数据。
  • 执行事务型数据库操作。
  • 根据运行时条件，对数据库信息的本地副本进行过滤和排序。
  • 创建并操作来自数据库的分级结果。
  • 将数据库字段绑定到数据识别组件。
  • 创建远程的、断开连接的 Recordsets。

为提供这样的灵活性，ADO 必须显示各种选项和设置。因此很有必要采取系统的方法来学习如何在应用程序中使用 ADO，以及如何把每个目标分解为可管理的若干部分。

在大多数 ADO 程序中都涉及四种基本操作：获取数据、检验数据、编辑数据和更新数据。后面的四章将分别更加详细地检验每种操作。

在继续之前，请熟练掌握 ADO 对象模型中的对象。然后学习 HelloData：一个简单的 ADO 应用程序。此应用程序用 Visual Basic 编写，而且执行了四种 ADO 基本操作中的所有操作。

© 1998-2002 Microsoft Corporation。保留所有权利。


ADO 对象模型

ADO 只需要九个对象和四个集合就能提供其整个功能。下表介绍了这些对象和集合。

对象或集合 | 说明内容
Connection 对象 | 代表与数据源的唯一会话。在使用客户端/服务器数据库系统的情况下，该对象可以等价于与服务器的实际网络连接。Connection 对象的某些集合、方法或属性可能不可用，这取决于提供者支持的功能。
Command 对象 | 用来定义针对数据源运行的具体命令，例如 SQL 查询。
Recordset 对象 | 表示从基本表或命令执行的结果所得到的整个记录集合。所有 Recordset 对象均由记录（行）和字段（列）组成。
Record 对象 | 表示来自 Recordset 或提供者的一行数据。该记录可以表示数据库记录或某些其他类型的对象（例如文件或目录），这取决于提供者。
Stream 对象 | 表示二进制或文本数据的数据流。例如，XML 文档可以加载到数据流中以便进行命令输入，也可以作为查询结果从某些提供者那里返回。Stream 对象可用于对包含这些数据流的字段或记录进行操作。
Parameter 对象 | 表示与基于参数化查询或存储过程的 Command 对象相关联的参数。
Field 对象 | 表示一列普通数据类型数据。每个 Field 对象对应于 Recordset 中的一列。
Property 对象 | 表示由提供者定义的 ADO 对象的特征。ADO 对象有两种类型的属性：内置属性和动态属性。内置属性是指那些已在 ADO 中实现并且任何新对象可以立即使用的属性。Property 对象是基本提供者所定义的动态属性的容器。
Error 对象 | 包含有关数据访问错误的详细信息，这些错误与涉及提供者的单个操作有关。
Fields 集合 | 包含 Recordset 或 Record 对象的所有 Field 对象。
Properties 集合 | 包含对象特定实例的所有 Property 对象。
Parameters 集合 | 包含 Command 对象的所有 Parameter 对象。
Errors 集合 | 包含为响应单个提供者相关失败而创建的所有 Error 对象。

下图显示了 ADO 对象及其集合。单击对象或集合，可以获得“ADO 程序员参考”中的详细信息。


HelloData：简单的 ADO 应用程序

为了给探索 ADO 库做好准备，假定有一个名为 HelloData 的简单的 ADO 应用程序。HelloData 逐步执行四种 ADO 操作（获取、检查、编辑和更新数据）。为了重点介绍 ADO 的基础知识并避免代码混乱，本范例介绍了最简单的错误处理。

ADO 应用程序查询 Microsoft SQL Server 2000 附带的 Northwind 范例数据库。

运行 HelloData

  1. 创建一个新的引用 ADO 2.5 库的标准可执行 Visual Basic 工程。
  2. 在该窗体的顶部创建四个命令按钮，将 Name 和 Caption 属性设置为下表所示的值。
  3. 在按钮下面，添加一个 Microsoft DataGrid Control (Msdatgrd.ocx)。Msdatgrd.ocx 文件是随 Visual Basic 一起提供的，位于 \windows\system32 或 \winnt\system32 目录下。要将 DataGrid 控件添加到 Visual Basic Toolbox 窗格，请从“工程”菜单中选择“组件...”。然后选中“Microsoft DataGrid Control 6.0 (SP3) (OLEDB)”旁边的框，并单击“确定”。要将该控件添加到项目，请将 DataGrid 控件从 Toolbox 拖至 Visual Basic 窗体。
  4. 在网格下的窗体上创建一个“文本框”，并按下表所示设置其属性。完成之后，该窗体应如下图所示。
  5. 最后，将“HelloData 代码”中列出的代码复制并粘贴到该窗体的代码编辑器窗口。按 F5 运行该代码。
注意 在以下范例和整个指南中，密码为“123aBc”的用户 ID“MyId”用于验证服务器。应使用登录该服务器的有效登录凭据替换这些值。另外，应使用用户服务器的名称替换“MyServer”值。

有关代码的详细说明，请参阅“HelloData 详细信息”。

控件类型 | 属性 | 值
窗体 | Name | Form1
 | Height | 6500
 | Width | 6500
MS DataGrid | Name | grdDisplay1
文本框 | Name | txtDisplay1
 | Multiline | true
命令按钮 | Name | cmdGetData
 | Caption | Get Data
命令按钮 | Name | cmdExamineData
 | Caption | Examine Data
命令按钮 | Name | cmdEditData
 | Caption | Edit Data
命令按钮 | Name | cmdUpdateData
 | Caption | Update Data


HelloData 详细信息

HelloData 应用程序逐步执行典型 ADO 应用程序的基本操作：获取、检查、编辑和更新数据。启动 HelloData 应用程序之后，单击第一个按钮“Get Data”，将运行 GetData() 子例程。

GetData

GetData 将有效的连接字符串放到模块级变量 m_sConnStr 中。有关连接字符串的详细信息，请参阅创建连接字符串。

使用 Visual Basic OnError 语句分配错误处理程序。有关在 ADO 中处理的错误的详细信息，请参阅第 6 章：错误处理。由于 HelloData 范例创建了“断开连接的记录集”，所以要创建新的 Connection 对象，并将 CursorLocation 属性设置为 adUseClient。这意味着一旦从数据源提取出数据，将断开与该数据源的物理连接，但是仍然可以使用在 Recordset 对象中本地缓存的数据。

打开连接之后，将 SQL 字符串赋给变量 (sSQL)。然后实例化新的 Recordset 对象 m_oRecordset1。在下一行代码中，通过现有的 Connection 打开 Recordset，将 sSQL 作为 Recordset 的源进行传递。通过将最后一个参数中的 adCmdText 传递到 Recordset Open 方法，可以帮助 ADO 确定作为 Recordset 的源传递的 SQL 字符串是否是命令的文本定义。此代码行还设置了与 Recordset 相关的 LockType 和 CursorType。

下一行代码将 MarshalOptions 属性设置为 adMarshalModifiedOnly。MarshalOptions 指示应调度到中间层（或 Web 服务器）的记录。有关调度的详细信息，请参阅 COM 文档。将 adMarshalModifiedOnly 与客户端游标 (CursorLocation = adUseClient) 一起使用时，仅将已经在客户端上修改过的记录写回中间层。由于将 MarshalOptions 设置为 adMarshalModifiedOnly 时需要调度的行比较少，所以可以提高性能。

接下来，通过将 Recordset 的 ActiveConnection 属性设置为 Nothing 断开连接 Recordset。有关详细信息，请参阅“第 5 章：更新和持久保留数据”中的断开连接和重新连接 Recordset。

断开与数据源的连接并删除现有的 Connection 对象，这样可以释放 Connection 对象所占用的资源。

最后一步是将 Recordset 设置为窗体上 Microsoft DataBound Grid Control 的 DataSource，以便可以在窗体上方便地显示 Recordset 中的数据。

单击第二个按钮“Examine Data”，将运行 ExamineData 子例程。

ExamineData

ExamineData 使用 Recordset 对象的各种方法和属性来显示 Recordset 中的数据信息。它使用 RecordCount 属性报告记录数目。ExamineData 循环 Recordset，并打印窗体上显示文本框中 AbsolutePosition 属性的值。另外，在循环的同时将第三个记录的 Bookmark 属性的值放到 variant 变量 vBookmark 中，以备将来使用。

该例程使用以前存储的 bookmark 变量直接导航回第三个记录。该例程调用 WalkFields 子例程，该子例程循环 Recordset 的 Fields 集合，并显示有关该集合中每个 Field 的详细信息。

最后，ExamineData 使用 Recordset 的 Filter 属性在屏幕上只显示 CategoryId 等于 2 的记录。应用了此过滤的结果立即显示在该窗体的显示网格中。

有关 ExamineData 子例程中显示的功能的详细信息，请参阅第 3 章：检查数据。

接下来，单击第三个按钮“Edit Data”，将运行 EditData 子例程。

EditData

代码进入 EditData 子例程时，ExamineData 仍在对 Recordset 进行 CategoryId 等于 2 的过滤，因此只有符合此过滤条件的项目是可见的。EditData 子例程首先循环 Recordset，然后将 Recordset 中每个可见项目的价格提高 10％。通过将 Price 字段的 Value 属性设置为一个新的有效数量来更改该字段的值。

记住从数据源断开连接 Recordset。仅对数据的本地缓存副本做在 EditData 中所做的更改。有关详细信息，请参阅第 4 章：编辑数据。

单击第四个按钮“Update Data”之前不会对数据源做任何更改。单击该按钮将运行 UpdateData 子例程。

UpdateData

UpdateData 首先删除已经应用到 Recordset 的过滤。该代码删除 m_oRecordset1 并将其重置为该窗体上 Microsoft Bound DataGrid 的 DataSource，以便未被过滤的 Recordset 可以显示在网格中。

然后该代码查看用户是否可以通过将 Supports 方法与 adMovePrevious 参数配合使用在 Recordset 中向后移动。

该例程使用 MoveFirst 方法移动到第一个记录，并使用 Field 对象的 OriginalValue 和 Value 属性显示该字段的原始和当前值。这些属性以及 UnderlyingValue 属性（此处未使用）在第 5 章：更新和持久保留数据中均有论述。

接下来，创建新的 Connection 对象，并使用该对象重新建立与数据源的连接。通过将新的 Connection 设置为 Recordset 的 ActiveConnection 将 Recordset 重新连接到数据源。要将更新发送到服务器，该代码在 Recordset 上调用 UpdateBatch。

如果批更新成功，模块级标志变量 m_flgPriceUpdated 将被设置为 True。这将提醒您稍后清除对数据库所做的所有更改。

最后，该代码移动回 Recordset 中的第一个记录并显示原始和当前值。调用 UpdateBatch 之后，这两个值将相同。

有关更新数据的详细信息（包括在断开连接 Recordset 时如果服务器上的数据发生改变应执行的操作），请参阅第 5 章：更新和持久保留数据。

Form_Unload

Form_Unload 子例程之所以重要是由于以下几个方面的原因。首先，因为这是一个范例应用程序，Form_Unload 在应用程序退出之前将清除对数据库所做的更改。其次，该代码显示了如何使用 Execute 方法直接从打开的 Connection 对象执行命令。最后，该代码显示了对数据源执行不是以行返回的查询（UPDATE 查询）的一个范例。


HelloData 代码

'BeginHelloData
Option Explicit

Dim m_oRecordset As ADODB.Recordset
Dim m_sConnStr As String
Dim m_flgPriceUpdated As Boolean

Private Sub cmdGetData_Click()
    GetData

    If Not m_oRecordset Is Nothing Then
        If m_oRecordset.State = adStateOpen Then
            ' Set the proper states for the buttons.
            cmdGetData.Enabled = False
            cmdExamineData.Enabled = True
        End If
    End If
End Sub

Private Sub cmdExamineData_Click()
    ExamineData
End Sub

Private Sub cmdEditData_Click()
    EditData
End Sub

Private Sub cmdUpdateData_Click()
    UpdateData

    ' Set the proper states for the buttons.
    cmdUpdateData.Enabled = False
End Sub

Private Sub GetData()
    On Error GoTo GetDataError

    Dim sSQL As String
    Dim oConnection1 As ADODB.Connection

    m_sConnStr = "Provider='SQLOLEDB';Data Source='MySqlServer';" & _
                "Initial Catalog='Northwind';Integrated Security='SSPI';"

    ' Create and Open the Connection object.
    Set oConnection1 = New ADODB.Connection
    oConnection1.CursorLocation = adUseClient
    oConnection1.Open m_sConnStr

    sSQL = "SELECT ProductID, ProductName, CategoryID, UnitPrice " & _
             "FROM Products"

    ' Create and Open the Recordset object.
    Set m_oRecordset = New ADODB.Recordset
    m_oRecordset.Open sSQL, oConnection1, adOpenStatic, _
                        adLockBatchOptimistic, adCmdText

    m_oRecordset.MarshalOptions = adMarshalModifiedOnly

    ' Disconnect the Recordset.
    Set m_oRecordset.ActiveConnection = Nothing
    oConnection1.Close
    Set oConnection1 = Nothing

    ' Bind Recordset to the DataGrid for display.
    Set grdDisplay1.DataSource = m_oRecordset

    Exit Sub

GetDataError:
    If Err <> 0 Then
        If oConnection1 Is Nothing Then
           HandleErrs "GetData", m_oRecordset.ActiveConnection
        Else
           HandleErrs "GetData", oConnection1
        End If
    End If

    If Not oConnection1 Is Nothing Then
        If oConnection1.State = adStateOpen Then oConnection1.Close
        Set oConnection1 = Nothing
    End If
End Sub

Private Sub ExamineData()
    On Err GoTo ExamineDataErr

    Dim iNumRecords As Integer
    Dim vBookmark As Variant

    iNumRecords = m_oRecordset.RecordCount

    DisplayMsg "There are " & CStr(iNumRecords) & _
                " records in the current Recordset."

    ' Loop through the Recordset and print the
    ' value of the AbsolutePosition property.
    DisplayMsg "****** Start AbsolutePosition Loop ******"

    Do While Not m_oRecordset.EOF
        ' Store the bookmark for the 3rd record,
        ' for demo purposes.
        If m_oRecordset.AbsolutePosition = 3 Then _
            vBookmark = m_oRecordset.Bookmark

        DisplayMsg m_oRecordset.AbsolutePosition

        m_oRecordset.MoveNext
    Loop

    DisplayMsg "****** End AbsolutePosition Loop ******" & vbCrLf

    ' Use our bookmark to move back to 3rd record.
    m_oRecordset.Bookmark = vBookmark
    MsgBox vbCr & "Moved back to position " & _
            m_oRecordset.AbsolutePosition & " using bookmark.", , _
            "Hello Data"

    ' Display meta-data about each field. See WalkFields() sub.
    Call WalkFields

    ' Apply a filter on the type field.
    MsgBox "Filtering on type field. (CategoryID=2)", _
            vbOKOnly, "Hello Data"

    m_oRecordset.Filter = "CategoryID=2"

    ' Set the proper states for the buttons.
    cmdExamineData.Enabled = False
    cmdEditData.Enabled = True

    Exit Sub

ExamineDataErr:
    HandleErrs "ExamineData", m_oRecordset.ActiveConnection
End Sub

Private Sub EditData()
    On Error GoTo EditDataErr

    'Recordset still filtered on CategoryID=2.
    'Increase price by 10% for filtered records.
    MsgBox "Increasing unit price by 10%" & vbCr & _
        "for all records with CategoryID = 2.", , "Hello Data"

    m_oRecordset.MoveFirst

    Dim cVal As Currency
    Do While Not m_oRecordset.EOF
        cVal = m_oRecordset.Fields("UnitPrice").Value
        m_oRecordset.Fields("UnitPrice").Value = (cVal * 1.1)
        m_oRecordset.MoveNext
    Loop

    ' Set the proper states for the buttons.
    cmdEditData.Enabled = False
    cmdUpdateData.Enabled = True

    Exit Sub

EditDataErr:
    HandleErrs "EditData", m_oRecordset.ActiveConnection
End Sub

Private Sub UpdateData()
    On Error GoTo UpdateDataErr

    Dim oConnection2 As New ADODB.Connection

    MsgBox "Removing Filter (adFilterNone).", , "Hello Data"
    m_oRecordset.Filter = adFilterNone

    Set grdDisplay1.DataSource = Nothing
    Set grdDisplay1.DataSource = m_oRecordset

    MsgBox "Applying Filter (adFilterPendingRecords).", , "Hello Data"
    m_oRecordset.Filter = adFilterPendingRecords

    Set grdDisplay1.DataSource = Nothing
    Set grdDisplay1.DataSource = m_oRecordset

    DisplayMsg "*** PRE-UpdateBatch values for 'UnitPrice' field. ***"

    ' Display Value, UnderlyingValue, and OriginalValue for
    ' type field in first record.
    If m_oRecordset.Supports(adMovePrevious) Then
        m_oRecordset.MoveFirst
        DisplayMsg "OriginalValue   = " & _
            m_oRecordset.Fields("UnitPrice").OriginalValue
        DisplayMsg "Value           = " & _
            m_oRecordset.Fields("UnitPrice").Value
    End If

    oConnection2.ConnectionString = m_sConnStr
    oConnection2.Open

    Set m_oRecordset.ActiveConnection = oConnection2
    m_oRecordset.UpdateBatch

    m_flgPriceUpdated = True

    DisplayMsg "*** POST-UpdateBatch values for 'UnitPrice' field ***"

    If m_oRecordset.Supports(adMovePrevious) Then
         m_oRecordset.MoveFirst
         DisplayMsg "OriginalValue   = " & _
             m_oRecordset.Fields("UnitPrice").OriginalValue
         DisplayMsg "Value           = " & _
             m_oRecordset.Fields("UnitPrice").Value
    End If

    MsgBox "See value comparisons in txtDisplay.", , _
           "Hello Data"

    'Clean up
    oConnection2.Close
    Set oConnection2 = Nothing
    Exit Sub

UpdateDataErr:
    If Err <> 0 Then
        HandleErrs "UpdateData", oConnection2
    End If

    If Not oConnection2 Is Nothing Then
        If oConnection2.State = adStateOpen Then oConnection2.Close
        Set oConnection2 = Nothing
    End If
End Sub

Private Sub WalkFields()
    On Error GoTo WalkFieldsErr

    Dim iFldCnt As Integer
    Dim oFields As ADODB.Fields
    Dim oField As ADODB.Field
    Dim sMsg As String

    Set oFields = m_oRecordset.Fields

    DisplayMsg "****** BEGIN FIELDS WALK ******"

    For iFldCnt = 0 To (oFields.Count - 1)
        Set oField = oFields(iFldCnt)
        sMsg = ""
        sMsg = sMsg & oField.Name
        sMsg = sMsg & vbTab & "Type: " & GetTypeAsString(oField.Type)
        sMsg = sMsg & vbTab & "Defined Size: " & oField.DefinedSize
        sMsg = sMsg & vbTab & "Actual Size: " & oField.ActualSize

        grdDisplay1.SelStartCol = iFldCnt
        grdDisplay1.SelEndCol = iFldCnt
        DisplayMsg sMsg
        MsgBox sMsg, , "Hello Data"
    Next iFldCnt

    DisplayMsg "****** END FIELDS WALK ******" & vbCrLf

    'Clean up
    Set oField = Nothing
    Set oFields = Nothing
    Exit Sub

WalkFieldsErr:
    Set oField = Nothing
    Set oFields = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub

Private Function GetTypeAsString(dtType As ADODB.DataTypeEnum) As String
    ' To save space, we are only checking for data types
    ' that we know are present.
    Select Case dtType
        Case adChar
            GetTypeAsString = "adChar"
        Case adVarChar
            GetTypeAsString = "adVarChar"
        Case adVarWChar
            GetTypeAsString = "adVarWChar"
        Case adCurrency
            GetTypeAsString = "adCurrency"
        Case adInteger
            GetTypeAsString = "adInteger"
    End Select
End Function

Private Sub HandleErrs(sSource As String, ByRef m_oConnection As ADODB.Connection)
    DisplayMsg "ADO (OLE) ERROR IN " & sSource
    DisplayMsg vbTab & "Error: " & Err.Number
    DisplayMsg vbTab & "Description: " & Err.Description
    DisplayMsg vbTab & "Source: " & Err.Source

    If Not m_oConnection Is Nothing Then
        If m_oConnection.Errors.Count <> 0 Then
            DisplayMsg "PROVIDER ERROR"
            Dim oError1 As ADODB.Error
            For Each oError1 In m_oConnection.Errors
                DisplayMsg vbTab & "Error: " & oError1.Number
                DisplayMsg vbTab & "Description: " & oError1.Description
                DisplayMsg vbTab & "Source: " & oError1.Source
                DisplayMsg vbTab & "Native Error:" & oError1.NativeError
                DisplayMsg vbTab & "SQL State: " & oError1.SQLState
            Next oError1
            m_oConnection.Errors.Clear
            Set oError1 = Nothing
        End If
    End If

    MsgBox "Error(s) occurred. See txtDisplay1 for specific information.", , _
           "Hello Data"

    Err.Clear
End Sub

Private Sub DisplayMsg(sText As String)
    txtDisplay1.Text = (txtDisplay1.Text & vbCrLf & sText)
End Sub

Private Sub Form_Resize()
    grdDisplay1.Move 100, 700, Me.ScaleWidth - 200, (Me.ScaleHeight - 800) / 2
    txtDisplay1.Move 100, grdDisplay1.Top + grdDisplay1.Height + 100, _
                    Me.ScaleWidth - 200, (Me.ScaleHeight - 1000) / 2
End Sub

Private Sub Form_Load()
    cmdGetData.Enabled = True
    cmdExamineData.Enabled = False
    cmdEditData.Enabled = False
    cmdUpdateData.Enabled = False

    grdDisplay1.AllowAddNew = False
    grdDisplay1.AllowDelete = False
    grdDisplay1.AllowUpdate = False
    m_flgPriceUpdated = False
End Sub

Private Sub Form_Unload(Cancel As Integer)
    On Error GoTo ErrHandler:

    Dim oConnection3 As New ADODB.Connection
    Dim sSQL As String
    Dim lAffected As Long

    ' Undo the changes we've made to the database on the server.
    If m_flgPriceUpdated Then
        sSQL = "UPDATE Products SET UnitPrice=(UnitPrice/1.1) " & _
            "WHERE CategoryID=2"
        oConnection3.Open m_sConnStr
        oConnection3.Execute sSQL, lAffected, adCmdText

        MsgBox "Restored prices for " & CStr(lAffected) & _
            " records affected.", , "Hello Data"
    End If

    'Clean up
    oConnection3.Close
    Set oConnection3 = Nothing
    m_oRecordset.Close
    Set m_oRecordset = Nothing
    Exit Sub

ErrHandler:

    If Not oConnection3 Is Nothing Then
        If oConnection3.State = adStateOpen Then oConnection3.Close
        Set oConnection3 = Nothing
    End If
    If Not m_oRecordset Is Nothing Then
        If m_oRecordset.State = adStateOpen Then m_oRecordset.Close
        Set m_oRecordset = Nothing
    End If
End Sub

'EndHelloData


OLE DB 提供者

《ADO 程序员指南》中的简介一文论述了 ADO 以及 Microsoft Data Access 体系结构其余部分之间的关系。OLE DB 定义了一组 COM 接口，以便为应用程序提供对存储在不同信息源中的数据的统一访问。此方法允许数据源通过支持适用于数据源的众多 DBMS 功能的接口共享数据。OLE DB 的高性能体系结构得益于它使用了灵活的、基于组件的服务模型。OLE DB 只需要完成特定任务所需的组件，而不预先规定应用程序和数据之间的中间层数。

例如，假设有位用户需要运行查询功能。请考虑下面的方案：

  • 数据驻留在关系数据库中，目前存在针对该数据库的 ODBC 驱动程序，但没有原生的 OLE DB 提供者。应用程序使用 ADO 与 OLE DB Provider for ODBC 通信，OLE DB Provider for ODBC 然后加载适当的 ODBC 驱动程序。ODBC 驱动程序将 SQL 语句传递给 DBMS，由 DBMS 检索数据。
  • 数据驻留在 Microsoft SQL Server 中，针对该服务器存在原生的 OLE DB 提供者。应用程序使用 ADO 与 OLE DB Provider for Microsoft SQL Server 通信，无须中间环节。
  • 数据驻留在 Microsoft Exchange Server 中，尽管存在用于该服务器的 OLE DB 提供者，但它并不显露引擎来处理 SQL 查询：应用程序使用 ADO 与 OLE DB Provider for Microsoft Exchange 通信，并调用某个 OLE DB 查询处理器组件来处理查询任务。
  • 数据以文档形式驻留在 Microsoft NTFS 文件系统中：使用原生的 OLE DB 提供者通过 Microsoft Indexing Service 可访问数据，Microsoft Indexing Service 索引文档系统中文档的内容和属性来支持有效的内容搜索。

在前面所有的范例中，应用程序都可以查询数据。使用最小数目的组件即可满足用户的要求。在每种情况下，仅在需要时才使用额外的组件，而且只有需要的组件得到调用。这种可重用、可共享的组件的按需加载方式大大提高了 OLE DB 在使用时的性能。

提供者分为两类：提供数据的提供者和提供服务的提供者。数据提供者拥有自己的数据并把数据以表格形式显露给应用程序。服务提供者通过产生和消费数据来封装服务，以增加 ADO 应用程序中的功能。也可以将服务提供者进一步定义为服务组件，服务组件必须与其他服务提供者或组件结合使用。

ADO 为不同的 OLE DB 提供者提供一致的高级接口。


数据提供者

数据提供者代表不同的数据来源，例如 SQL 数据库、索引后续文件、电子表格、文档存储和邮件文件。提供者一律使用称为行集的公共抽象来显露数据。

ADO 之所以具有强大的功能和灵活性，是因为它可以连接几种不同的数据提供者，并且仍然显露同一个编程模型，而不考虑任何给定的提供者的具体功能。但是，由于每个数据提供者是唯一的，所以应用程序与 ADO 交互的方式将根据数据提供者的不同而不同。

例如，OLE DB Provider for SQL Server（用来访问 Microsoft SQL Server 数据库）的功能和特性与 Microsoft OLE DB Provider for Internet Publishing 的功能和特性（用来访问 Web 服务器上的文件存储）有相当大的差异。


服务提供者和组件

服务提供者是通过实现数据存储原本并不支持的扩充接口来扩展数据提供者功能的组件。

Microsoft Data Access 提供了“组件体系结构”，允许单个专门组件在功能较弱的存储之上实现不同的数据库功能或“服务”。这样，服务组件就提供了一种任何应用程序在访问任何数据存储时都能够使用的常规实现方法，而无须强制每个数据存储提供自己的扩充功能实现或强制普通应用程序在内部实现数据库功能。因此，哪些功能是由数据存储本身实现的，哪些功能是通过普通组件实现的，这些对应用程序来说都一目了然。

例如，某个游标引擎（如 Microsoft Cursor Service for OLE DB）是一个能够消费连续的、仅向前数据存储中的数据以产生滚动数据的服务组件。其他的由 ADO 经常使用的服务提供者包括 Microsoft OLE DB Persistence Provider（用于将数据存储到文件）、Microsoft Data Shaping Service for OLE DB（用于分级结构的 Recordsets）和 Microsoft OLE DB Remoting Provider（用于调用远程计算机上的数据）。

有关服务提供者和数据提供者的详细信息，请参阅附录 A：提供者


错误

任何涉及 ADO 对象的操作都可能产生一个或多个提供者错误。发生每个错误时，将把一个或多个 Error 对象放在 Connection 对象的 Errors 集合中。有关在 ADO 应用程序中处理警告和错误的详细内容，请参阅第 6 章：错误处理。

可以由单独的机制引发应用程序错误。例如，在 Visual Basic 中，Err 对象将包含应用程序级别的错误。


第 2 章：获得数据

前一章介绍了在创建 ADO 应用程序的过程中所涉及的四个主要操作：获得数据、检查数据、编辑数据和更新数据。这一章的重点是详细介绍与第一项操作“获得数据”相关的概念。

几个 ADO 对象可以在该操作中发挥作用。首先，使用 ADO Connection 对象（有时需要隐式地创建该对象）连接到数据源。然后，使用 ADO Command 对象（也可以隐式地创建）将您要做什么的指令传递给数据源。将命令传递给数据源并接收其响应的结果通常将呈现在 ADO Recordset 对象中。

若要获得数据，应用程序必须与数据源（例如 DBMS、文件存储或逗号分隔的文本文件）通讯。该通讯体现为“连接”，即交换数据所需的环境。

ADO 对象模型以 Connection 对象（它是很多 ADO 功能的基础）来体现连接概念。Connection 对象的目的是：

  • 定义与数据源通讯并创建会话时 ADO 所需要的信息。
  • 定义会话的事务功能。
  • 允许针对数据源创建和执行命令。
  • 以架构行集的形式提供关于设计基本数据源的信息。有关架构行集的详细信息，请参阅 OpenSchema 方法。


建立连接

若要连接数据源，必须指定“连接字符串”，而对每个提供者和数据源来说，连接字符串的参数可能各不相同。详细信息，请参阅创建连接字符串。

绝大多数情况下，ADO 通过使用 Connection 对象的 Open 方法打开连接。下面是 Open 方法的语法：

Dim connection as New ADODB.Connection
connection.Open ConnectionString, UserID, Password, OpenOptions

另外，也可以使用一种快捷技术 Recordset.Open 来打开隐式连接并通过该连接发出命令。要这样做，需要将一个有效的连接字符串作为 ActiveConnection 参数传递给 Open 方法。下面是在 Visual Basic 中每种方法的语法：

Dim recordset as ADODB.Recordset
Set recordset = New ADODB.Recordset
recordset.Open Source, ActiveConnection, CursorType, LockType, Options
注意 什么时候应当使用 Connection 对象和 Recordset.Open 快捷方法呢？如果计划打开多个 Recordset 或执行多个命令时，应当使用 Connection 对象。使用 Recordset.Open 快捷方法时，连接仍然由 ADO 以隐式方式创建。


使用 Connection 对象

Connection 对象表示与数据源的唯一会话。在使用客户端/服务器数据库系统的情况下，该对象可以等价于到服务器的实际网络连接。Connection 对象的某些集合、方法或属性可能无效，这取决于提供者支持的功能。

在打开 Connection 对象之前，必须定义有关数据源和连接类型的某些信息。Connection 对象 Open 方法的 ConnectionString 参数，或 Connection 对象上的 ConnectionString 属性通常包含多数这样的信息。连接字符串是定义数量不等的参数的字符串。这些参数（某些参数是 ADO 所需的，但另一些参数要视具体提供者而定）包含 Connection 对象完成其任务所必需的信息。组成 ConnectionString 参数的参数用分号 (;) 分隔。

注意 还可在连接字符串中定义 ODBC 数据源名称 (DSN) 或数据链接 (UDL) 文件。有关 DSN 的详细信息，请参阅 OLE DB Programmer's Reference 中 Part 1 的“Data Sources”。有关 UDL 的详细信息，请参阅 OLE DB Programmer's Reference 中的“Data Link API Overview”。


创建连接字符串

在连接字符串中，ADO 直接支持五个参数。其他参数则传递给在 Provider 参数中指定的提供者，ADO 不对这些参数进行任何处理。

参数 | 说明
Provider | 指定用于连接的提供者的名称。
File Name | 指定提供者特有的文件（例如，持久保留的数据源对象）的名称，这些文件中包含预置的连接信息。
URL | 指定连接字符串为标识资源（如文件或目录）的绝对 URL。
Remote Provider | 指定当打开客户端连接时使用的提供者的名称。（仅限于远程数据服务。）
Remote Server | 指定当打开客户端连接时使用的服务器的路径名称。（仅限于远程数据服务。）
注意 在以下范例中以及在整个《ADO 程序员指南》中，均使用密码为“123aBc”的用户 ID“MyId”来应对服务器的身份验证。应当将这些值替换为有效的服务器登录凭据。而且，请用您的服务器名称替换“MySqlServer”。

在第 1 章中的 HelloData 应用程序使用了以下连接字符串：

m_sConnStr = "Provider='SQLOLEDB';Data Source='MySqlServer';" & _
             "Initial Catalog='Northwind';Integrated Security='SSPI';"

在该连接字符串中，所提供的唯一 ADO 参数是“Provider=SQLOLEDB”，它表示 Microsoft OLE DB Provider for SQL Server。通过参考各个提供者的文档，可以确定能够在连接字符串中传递的其他有效参数。按照 OLE DB Provider for SQL Server 文档，可以用“Server”代替 DataSource 参数并用“Database”代替 InitialCatalog 参数。因而，以下连接字符串会产生与第一个连接字符串相同的结果：

m_sConnStr = "Provider='SQLOLEDB';Server='MySqlServer';" & _
             "Database='Northwind';Integrated Security='SSPI';"

若要打开连接，只需在 Connection 对象的 Open 方法中将连接字符串作为第一个参数传递：

objConn.Open m_sConnStr

通过在打开连接之前设置 Connection 对象的属性，也能提供很多这样的信息。例如，通过使用以下代码也会取得与使用上面的连接字符串时相同的效果：

With objConn
   .Provider = "SQLOLEDB"
   .DefaultDatabase = "Northwind"
   .Properties("Data Source") = "MySqlServer"
   .Properties("Integrated Security") = "SSPI"
   .Open
End With


控制事务

“事务”用于分隔在连接过程中发生的一系列数据访问操作的开始和结束。为了服从于数据源的事务功能，Connection 对象也使用户可创建和管理事务。例如，通过使用 Microsoft OLE DB Provider for SQL Server 来访问 Microsoft SQL Server 2000 上的数据库，可以为所执行的命令创建多个嵌套事务。

ADO 确保由事务中的操作所造成的对数据源的更改是全部成功还是全部失败。

如果取消事务或它的一个操作失败，最终的结果是事务中的操作好象都没有发生过。数据源将保持事务开始前的状态。

ADO 对象模型并不会显式地包括事务，但通过一组 Connection 对象方法（BeginTrans、CommitTrans 和 RollbackTrans）来表示事务。

有关事务的详细信息，请参阅第 5 章：更新和保持数据。


使用 Command 对象

连接到数据源后，需要执行对数据源的请求，以获取结果集。ADO 将这一类型的命令功能封装在 Command 对象中。

可使用 Command 对象向提供者请求任何类型的操作，条件是提供者能够正确解释命令字符串。数据提供者的常用操作是查询数据库，并将记录返回到 Recordset 对象中。Recordset 将在本章的后面部分和其他章中详细论述；就现在而言，可以把它们看作是用来保持和查看结果集的工具。与许多 ADO 对象一样，在引用某些 Command 集合、方法或属性时可能会产生错误，这取决于提供者的功能。

并不总是需要创建 Command 对象对数据源执行命令。可使用 Connection 对象上的 Execute 方法或 Recordset 上的 Open 方法。但是，如果需要重用代码中的命令或者需要将详细的参数信息传递给命令，就应当使用 Command 对象。本章的后面部分更加详细地论述了这些方案。

注意 某些 Command 可将结果集作为二进制流或单个的 Record 返回，而不是作为 Recordset 返回，如果提供者支持这一返回方式。而且，有些 Command 根本不会返回任何结果集（例如，SQL Update 查询）。但本章将涵盖最典型的方案：执行将结果返回到 Recordset 对象中的 Command。有关将结果返回 Record 或 Stream 中的详细信息，请参阅 Chapter 10: Records and Streams。


Command 对象概述

用 Command 对象的集合、方法和属性可以执行下列操作：

  • 通过使用 CommandText 属性来定义命令（例如，SQL 语句或存储过程）的可执行文本。
  • 通过使用 Parameter 对象和 Parameters 集合来定义参数化查询或存储过程参数。
  • 如果合适的话，通过使用 Execute 方法来执行命令并返回 Recordset 对象。
  • 执行前用 CommandType 属性来指定命令类型，以优化性能。
  • 用 Prepared 属性控制执行命令前提供者是否保存准备好（或编译过）的命令版本。
  • 用 CommandTimeout 属性设置提供者等待命令执行的最长秒数。
  • 通过设置 ActiveConnection 属性使打开的连接与 Command 对象相关联。
  • 设置 Name 属性以便将 Command 对象标识为与之关联的 Connection 对象的方法。
  • 将 Command 对象传递给 Recordset 的 Source 属性以获取数据。

© 1998-2002 Microsoft Corporation。保留所有权利。


创建并执行简单的命令

下面的代码虽然不是 Command 对象的典型用法，但它显示了使用 Command 对象对数据源执行命令的基本方法。在本例中，该对象是一个行返回命令，因此它将命令执行的结果返回到 Recordset 对象中。

    'BeginBasicCmd
    On Error GoTo ErrHandler:

    Dim objConn As New ADODB.Connection
    Dim objCmd As New ADODB.Command
    Dim objRs As New ADODB.Recordset

    objCmd.CommandText = "SELECT OrderID, OrderDate, " & _
                         "RequiredDate, ShippedDate " & _
                         "FROM Orders " & _
                         "WHERE CustomerID = 'ALFKI' " & _
                         "ORDER BY OrderID"
    objCmd.CommandType = adCmdText

    ' Connect to the data source.
    Set objConn = GetNewConnection
    objCmd.ActiveConnection = objConn

    ' Execute once and display...
    Set objRs = objCmd.Execute

    Debug.Print "ALFKI"
    Do While Not objRs.EOF
        Debug.Print vbTab & objRs(0) & vbTab & objRs(1) & vbTab & _
                    objRs(2) & vbTab & objRs(3)
        objRs.MoveNext
    Loop

    'clean up
    objRs.Close
    objConn.Close
    Set objRs = Nothing
    Set objConn = Nothing
    Set objCmd = Nothing
    Exit Sub

ErrHandler:
    'clean up
    If objRs.State = adStateOpen Then
        objRs.Close
    End If

    If objConn.State = adStateOpen Then
        objConn.Close
    End If

    Set objRs = Nothing
    Set objConn = Nothing
    Set objCmd = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
'EndBasicCmd

需要执行的命令使用 CommandText 属性指定。

注意 在本节中的几个范例都调用了一个实用函数 GetNewConnection 以建立与数据提供者的连接。为避免重复，该函数只在下面列出了一次：
'BeginNewConnection
Private Function GetNewConnection() As ADODB.Connection
    Dim oCn As New ADODB.Connection
    Dim sCnStr As String

    sCnStr = "Provider='SQLOLEDB';Data Source='MySqlServer';" & _
             "Integrated Security='SSPI';Database='Northwind';"
    oCn.Open sCnStr

    If oCn.State = adStateOpen Then
        Set GetNewConnection = oCn
    End If

End Function
'EndNewConnection


Command 对象参数

下一个范例演示了 Command 对象的更有趣的用法，在该范例中，SQL 命令的文本已经经过修改以使该命令参数化。这使重用该命令成为可能，从而可以每次传递不同的参数值。由于将 Command 对象的 Prepared 属性设置为等于 True，ADO 将要求提供者在第一次执行之前编译 CommandText 中所指定的命令，而且编译好的命令会保留在内存中。这样做会在第一次执行命令时轻微减缓命令的执行速度，因为执行准备需要占用系统资源，但在这之后会在每次调用命令时使性能得到提高。因而，只有当命令将多次使用时才应准备命令。

'BeginManualParamCmd
    On Error GoTo ErrHandler:

    Dim objConn As New ADODB.Connection
    Dim objCmd As New ADODB.Command
    Dim objParm1 As New ADODB.Parameter
    Dim objRs As New ADODB.Recordset

    ' Set the CommandText as a parameterized SQL query.
    objCmd.CommandText = "SELECT OrderID, OrderDate, " & _
                         "RequiredDate, ShippedDate " & _
                         "FROM Orders " & _
                         "WHERE CustomerID = ? " & _
                         "ORDER BY OrderID"
    objCmd.CommandType = adCmdText

    ' Prepare command since we will be executing it more than once.
    objCmd.Prepared = True

    ' Create new parameter for CustomerID. Initial value is ALFKI.
    Set objParm1 = objCmd.CreateParameter("CustId", adChar, _
                    adParamInput, 5, "ALFKI")
    objCmd.Parameters.Append objParm1

    ' Connect to the data source.
    Set objConn = GetNewConnection
    objCmd.ActiveConnection = objConn

    ' Execute once and display...
    Set objRs = objCmd.Execute

    Debug.Print objParm1.Value
    Do While Not objRs.EOF
        Debug.Print vbTab & objRs(0) & vbTab & objRs(1) & vbTab & _
                    objRs(2) & vbTab & objRs(3)
        objRs.MoveNext
    Loop

    ' ...then set new param value, re-execute command, and display.
    objCmd("CustId") = "CACTU"
    Set objRs = objCmd.Execute

    Debug.Print objParm1.Value
    Do While Not objRs.EOF
        Debug.Print vbTab & objRs(0) & vbTab & objRs(1) & vbTab & _
                    objRs(2) & vbTab & objRs(3)
        objRs.MoveNext
    Loop

    'clean up
    objRs.Close
    objConn.Close
    Set objRs = Nothing
    Set objConn = Nothing
    Set objCmd = Nothing
    Set objParm1 = Nothing
    Exit Sub

ErrHandler:
    'clean up
    If objRs.State = adStateOpen Then
        objRs.Close
    End If

    If objConn.State = adStateOpen Then
        objConn.Close
    End If

    Set objRs = Nothing
    Set objConn = Nothing
    Set objCmd = Nothing
    Set objParm1 = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
'EndManualParamCmd

并非所有提供者都支持准备好的命令。如果提供者不支持命令准备，则一旦将此属性设置为 True，提供者便可能返回错误。如果它不返回错误，则提供者仅忽略准备命令的请求，并将 Prepared 属性设置为 False。


使用命令调用存储过程

也可以在调用存储过程时使用命令。以下代码调用 Northwind 范例数据库中的存储过程 CustOrdersOrders，其定义如下：

CREATE PROCEDURE CustOrdersOrders @CustomerID nchar(5) AS
SELECT OrderID, OrderDate, RequiredDate, ShippedDate
FROM Orders
WHERE CustomerID = @CustomerID
ORDER BY OrderID

该存储过程类似于在 Command 对象参数中使用的命令，相同之处在于该存储过程同样获取客户 ID 参数，并返回关于该客户定单的信息。下面的代码使用该存储过程作为 ADO Recordset 的数据源。

使用该存储过程可以访问另一个 ADO 功能：Parameters 集合的 Refresh 方法。通过使用该方法，ADO 可以在运行时自动填入命令所需要的所有参数信息。但使用该技术可能会降低性能，因为 ADO 必须查询数据源以获得关于参数的信息。

其他重要差异存在于下面的代码与 Command 对象参数中的代码之间，在后一种情况下参数需要手动输入。首先，该代码没有将 Prepared 属性设置为 True，因为它是 SQL Server 存储过程并且由定义进行预编译。其次，在第二个范例中，Command 对象的 CommandType 属性会更改为 adCmdStoredProc，以通知 ADO 该命令是存储过程。

'BeginAutoParamCmd
    On Error GoTo ErrHandler:

    Dim objConn As New ADODB.Connection
    Dim objCmd As New ADODB.Command
    Dim objParm1 As New ADODB.Parameter
    Dim objRs As New ADODB.Recordset

    ' Set CommandText equal to the stored procedure name.
    objCmd.CommandText = "CustOrdersOrders"
    objCmd.CommandType = adCmdStoredProc

    ' Connect to the data source.
    Set objConn = GetNewConnection
    objCmd.ActiveConnection = objConn

    ' Automatically fill in parameter info from stored procedure.
    objCmd.Parameters.Refresh

    ' Set the param value.
    objCmd(1) = "ALFKI"

    ' Execute once and display...
    Set objRs = objCmd.Execute

    Debug.Print objParm1.Value
    Do While Not objRs.EOF
        Debug.Print vbTab & objRs(0) & vbTab & objRs(1) & vbTab & _
                    objRs(2) & vbTab & objRs(3)
        objRs.MoveNext
    Loop

    ' ...then set new param value, re-execute command, and display.
    objCmd(1) = "CACTU"
    Set objRs = objCmd.Execute

    Debug.Print objParm1.Value
    Do While Not objRs.EOF
        Debug.Print vbTab & objRs(0) & vbTab & objRs(1) & vbTab & _
                    objRs(2) & vbTab & objRs(3)
        objRs.MoveNext
    Loop

    'clean up
    objRs.Close
    objConn.Close
    Set objRs = Nothing
    Set objConn = Nothing
    Set objCmd = Nothing
    Set objParm1 = Nothing
    Exit Sub

ErrHandler:
    'clean up
    If objRs.State = adStateOpen Then
        objRs.Close
    End If

    If objConn.State = adStateOpen Then
        objConn.Close
    End If

    Set objRs = Nothing
    Set objConn = Nothing
    Set objCmd = Nothing
    Set objParm1 = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
'EndAutoParamCmd

© 1998-2002 Microsoft Corporation。保留所有权利。


命名命令

可以设置 Command 对象的 Name 属性，然后通过调用它来执行命令，就好像它是 Command 对象的 ActiveConnection 属性的方法。以下范例对此进行了演示，在该范例中命令被命名为 GetCustomers。请注意，代码将一个经过声明和实例化的 Recordset 对象传递给 GetCustomers“方法”。如果 Command 需要参数，还可以向“方法”传递这些参数。

'BeginNamedCmd
    On Error GoTo ErrHandler:

    Dim objConn As New ADODB.Connection
    Dim objCmd As New ADODB.Command
    Dim objRs As New ADODB.Recordset

    ' Connect to the data source.
    Set objConn = GetNewConnection

    objCmd.CommandText = "SELECT CustomerID, CompanyName FROM Customers"
    objCmd.CommandType = adCmdText

    'Name the command.
    objCmd.Name = "GetCustomers"

    objCmd.ActiveConnection = objConn

    ' Execute using Command.Name from the Connection.
    objConn.GetCustomers objRs

    ' Display.
    Do While Not objRs.EOF
        Debug.Print objRs(0) & vbTab & objRs(1)
        objRs.MoveNext
    Loop

    'clean up
    objRs.Close
    objConn.Close
    Set objRs = Nothing
    Set objConn = Nothing
    Set objCmd = Nothing
    Exit Sub

ErrHandler:
    'clean up
    If objRs.State = adStateOpen Then
        objRs.Close
    End If

    If objConn.State = adStateOpen Then
        objConn.Close
    End If

    Set objRs = Nothing
    Set objConn = Nothing
    Set objCmd = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
'EndNamedCmd


将数据添加到 Recordset

Recordset 可能是最常用的 ADO 对象。在 ADO 中，Recordset 是将来自数据源的结果集与它的关联游标行为组合在一起的最好方法。因而，可以将数据放在 Recordset 中，然后使用 Recordset 方法和属性定位到数据的各行、查看行中的值或者操纵结果集。

这一节将重点讨论如何将数据添加到 Recordset 中。有关定位数据或更新数据的信息，请参阅第 4 章：编辑数据和第 5 章：更新和持久保留数据。并非总是需要 Command 对象的高级功能才能将结果集添加到 Recordset 中。通常，可以通过设置 Recordset 的 Source 属性或将命令字符串传递给 Recordset 对象的 Open 方法来执行命令。

将数据从数据源添加到 Recordset 的方法有很多。要用什么技术取决于应用程序的需要以及提供者的能力。


Recordset 对象的 Open 方法

打开一个 ADO Recordset 需要的所有指令构成 Open 方法。可在不创建任何其他对象的情况下使用此方法。此方法的语法如下所示：

recordset.Open Source, ActiveConnection, CursorType, LockType, Options

所有的参数均可选，因为它们传递的信息能够以其他方式传送给 ADO。但了解各个参数可以帮助您理解许多重要的 ADO 概念。以下主题将详细说明此方法的各个参数。

Source 和 Options 参数

Source 和 Options 参数两者联系紧密，因而出现在同一主题中。

recordset.Open Source, ActiveConnection, CursorType, LockType, Options

Source 参数是一个 Variant，用来计算有效的 Command 对象、命令文本（例如 SQL 语句）、表名称、存储过程调用、URL 、文件名或包含持久存储的 Recordset 的 Stream 对象。如果 Source 是一个文件路径名，那么它可以是完整路径（“C:\dir\file.rst”）、相对路径（“..\file.rst”）或 URL（“http://files/file.rst”）。还可在 Recordset 对象的 Source 属性中指定此信息并将 Source 参数保留为空。

Options 参数是一个指示以下两方面或任一方面的 Long 值：

  • 当 Source 参数表示的不是 Command 对象时，提供者用于计算此参数的方法。
  • Recordset 应当从以前保存的文件中恢复。

此参数可包含 CommandTypeEnum 或 ExecuteOptionEnum 值的位掩码。在 Options 参数中传递的 CommandTypeEnum 设置 Recordset 的 CommandType 属性。

注意 adExecuteNoRecords 和 adExecuteStream 的 ExecuteOpenEnum 值不能与 Open 一起使用。

如果 CommandType 属性值等于 adCmdUnknown（默认值），可能会降低系统性能，因为 ADO 必须调用提供者来确定 CommandText 属性是 SQL 语句、存储过程还是表名称。如果知道正在使用的命令的类型，那么设置 CommandType 属性可以提示 ADO 直接转入相关代码。如果 CommandType 属性与 CommandText 属性中的命令类型不匹配，那么在调用 Open 方法时将出现错误。

有关将这些枚举常量用于 Options 以及其他 ADO 方法和属性的详细信息，请参阅 CommandTypeEnum 和 ExecuteOptionEnum。

ActiveConnection 参数

可将 Connection 对象或连接字符串作为 ActiveConnection 参数传入。

recordset.Open Source, ActiveConnection, CursorType, LockType, Options

ActiveConnection 参数与 ActiveConnection 属性相对应，可以指定以哪种连接打开 Recordset 对象。如果传递此参数的连接定义，ADO 将用指定的参数打开新连接。用客户端游标 (CursorLocation = adUseClient) 打开 Recordset 后，即可更改该属性的值，然后将更新内容发送给其他提供者。还可以将此属性设置为 Nothing（在 Microsoft Visual Basic 中）或 NULL 断开 Recordset 与任何提供者的连接。但更改服务器端游标的 ActiveConnection 将产生错误。

如果传递了 Source 参数中的 Command 对象，同时又传递了 ActiveConnection 参数，就会出现错误。因为 Command 对象的 ActiveConnection 属性必须已经被设置为有效的 Connection 对象或连接字符串。

CursorType 参数

recordset.Open Source, ActiveConnection, CursorType, LockType, Options

正如游标位置的重要性中所论述的那样，应用程序所使用的游标类型将确定哪些功能可用于所得到的 Recordset（如果有）。有关对游标类型的详细检验，请参阅第 8 章：理解游标和锁定。

CursorType 参数可以接受任何 CursorTypeEnum 值。

LockType 参数

recordset.Open Source, ActiveConnection, CursorType, LockType, Options

设置 LockType 属性，以指定提供者在打开 Recordset 时使用的锁定类型。有关锁定的不同类型在第 8 章：理解游标和锁定中有所论述。

LockType 参数可以接受任何 LockTypeEnum 值。

检索多个 Recordsets

您可能偶尔需要执行将返回多个结果集的命令。运行于 SQL Server 数据库的存储过程就是一个常见的范例，如下例所示。该存储过程包含一个返回表中所有产品的平均价格的 COMPUTE 子句。此存储过程的定义如下：

CREATE PROCEDURE ProductsWithAvgPrice
AS
SELECT ProductID, ProductName, UnitPrice
  FROM PRODUCTS
  COMPUTE AVG(UnitPrice)

当该命令包含 COMPUTE 子句时，Microsoft OLE DB Provider for SQL Server 就会返回多个结果集。因此，ADO 代码必须使用 NextRecordset 方法来访问第二个结果集中的数据，如下所示：

'BeginNextRs
    On Error GoTo ErrHandler:

    Dim objConn As New ADODB.Connection
    Dim objCmd As New ADODB.Command
    Dim objRs As New ADODB.Recordset

    Set objConn = GetNewConnection
    objCmd.ActiveConnection = objConn

    objCmd.CommandText = "ProductsWithAvgPrice"
    objCmd.CommandType = adCmdStoredProc

    Set objRs = objCmd.Execute

    Do While Not objRs.EOF
        Debug.Print objRs(0) & vbTab & objRs(1) & vbTab & _
                    objRs(2)
        objRs.MoveNext
    Loop

    Set objRs = objRs.NextRecordset

    Debug.Print "AVG. PRICE = $ " & objRs(0)

    'clean up
    objRs.Close
    objConn.Close
    Set objRs = Nothing
    Set objConn = Nothing
    Set objCmd = Nothing
    Exit Sub

ErrHandler:
    'clean up
    If objRs.State = adStateOpen Then
        objRs.Close
    End If

    If objConn.State = adStateOpen Then
        objConn.Close
    End If

    Set objRs = Nothing
    Set objConn = Nothing
    Set objCmd = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
'EndNextRs

有关详细信息，请参阅 NextRecordset。


第 3 章：检查数据

第 2 章解释了如何从数据源中作为 Recordset 对象检索数据。这一章将更详细讨论 Recordset，包括如何在 Recordset 中进行定位和查看数据。

下图描述了 Recordset 对象的对象模型。单击对象或集合可以查看详细信息。

Recordsets 有专门用来进行定位和检查其内容的方法和属性。某些 Recordset 方法或属性可能不可用，这取决于提供者支持的功能。为了继续探究 Recordset 对象，现在假设有一个从 Microsoft SQL Server 2000 上的 Northwind 范例数据库返回的 Recordset，下面是相应的代码：

'BeginRsTour
Public Sub RecordsetTour()
    On Error GoTo ErrHandler:

    Dim objRs As New ADODB.Recordset
    Dim strSQL As String

    strSQL = "SELECT ProductID, ProductName, UnitPrice FROM Products " & _
        "WHERE CategoryID = 7"          '7 = Produce

    objRs.Open strSQL, strConnStr, adOpenForwardOnly, _
        adLockReadOnly, adCmdText

    'Clean up
    objRs.Close
    Set objRs = Nothing
    Exit Sub

ErrHandler:
    If Not objRs Is Nothing Then
        If objRs.State = adStateOpen Then objRs.Close
        Set objRs = Nothing
    End If

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndRsTour

该 SQL 查询返回的 Recordset 有五行（记录）和三列（字段）。每行的值显示在下表中。

FIELD 0 Name = ProductID | FIELD 1 Name = ProductName | FIELD 2 Name = UnitPrice
7 | 梨干 | 30.0000
14 | 豆腐 | 23.2500
28 | 韩国泡菜 | 45.6000
51 | 苹果干 | 53.0000
74 | 长寿豆腐 | 10.0000

下一步节将解释如何定位游标在该范例 Recordset 中的当前位置。


定位当前记录

游标在 Recordset 中的当前位置反映了当前的记录位置。假设所发出的命令返回了结果，那么，当调用 Recordset Open 方法时，游标将被自动放在第一个记录处。所以，对于范例 Recordset，游标会在第一个记录“梨干”上。


对行计数

RecordCount 属性返回指示 Recordset 中记录数目的 Long 值。用 RecordCount 属性可查找 Recordset 对象中的记录数目。如果 ADO 无法确定记录数目或者提供者或游标类型不支持 RecordCount，则该属性返回 -1。读取已关闭的 Recordset 的 RecordCount 属性将产生错误。

Recordset 属性取决于提供者的功能和游标类型。对于仅向前游标，RecordCount 属性将返回 -1；对于静态或键集游标，将返回实际计数；而对于动态游标，则返回 -1 或实际计数，这取决于数据源。

在检验数据中介绍的范例 Recordset 由于仅向前游标被打开将返回 –1。为了使用 RecordCount 属性，您需要利用更先进的游标（静态或键集）打开 Recordset。

在某些情况下，您的提供者或游标在首先从数据源提取所有的记录之前无法提供 RecordCount 值。若要强制执行这种类型的记录提取，请在调用 RecordCount 之前调用 Recordset 的 MoveLast 方法。

如果将调用 Recordset 的 Open 方法的代码行替换为下面的代码：

oRs.Open sSQL, sCnStr, adOpenStatic, adLockOptimistic, adCmdText

您就能够使用 RecordCount 属性，因为 Microsoft OLE DB Provider for SQL Server 的静态游标支持 RecordCount。例如，假定此游标支持 RecordCount 属性，下面的代码就会将该命令返回的记录数目输出到调试窗口：

Debug.Print oRs.RecordCount   ' Output: 4

在这个基础上，再假定使用了这些功能更强（但占用资源更多）的游标和锁定类型。


记录集的限制

使用 BOF 和 EOF 属性确定 Recordset 对象是否包含记录，或者从一个记录移动到另一个记录时是否超出 Recordset 对象的限制。可以把 BOF 和 EOF 看作是定位于 Recordset 开始和结尾的“幻像”记录 。如果根据检验数据中的 Recordset 建立这样的限制，它将显示如下：

ProductID | ProductName | UnitPrice
BOF |  |
7 | 梨干 | 30.0000
14 | 豆腐 | 23.2500
28 | 韩国泡菜 | 45.6000
51 | 苹果干 | 53.0000
74 | 长寿豆腐 | 10.0000
EOF |  |

如果当前记录位于第一个记录之前，则 BOF 属性返回 True (-1)。如果当前记录是第一个记录或位于第一个记录之后，则返回 False (0)。

如果当前记录位于最后一个记录之后，则 EOF 属性返回 True。如果当前记录是最后一个记录或位于最后一个记录之前，则返回 False。

如果 BOF 或 EOF 属性为 True，则没有当前记录，如以下代码所示：

If oRs.BOF And oRs.EOF Then
    ' Command returned no records.
End If

如果打开了不包含记录的 Recordset 对象，则 BOF 和 EOF 属性都会设置为 True，而且Recordset 对象的 RecordCount 属性设置的值将取决于游标类型。对于动态游标 (CursorType = adOpenDynamic)，将返回 -1；对于其他游标，将返回 0。

当打开至少包含一个记录的 Recordset 对象时，第一个记录是当前记录，并且 BOF 和 EOF 属性均为 False。

如果删除 Recordset 对象中保留的最后一个记录，则游标处于不定状态。BOF 和 EOF 属性将保持 False，直到重新定位当前记录为止，这取决于提供者。


导航数据

在针对数据源执行了命令，并确定结果集中包含数据之后，就可以使用由 Recordset 对象提供的导航方法和属性在结果中定位。以下主题描述了如何使用范例 Recordset 的这些方法和属性：

  • 跳转到记录
  • 在 Recordset 中移动的更多方法
  • 使用书签
  • 使用页
  • Recordset 定位


跳转到记录

Move 方法允许通过使用下面的语法在 Recordset 中按照指定的数目向前或向后移动记录：

oRs.Move NumRecords, Start

所有 Recordset 对象都支持 Move 方法。

如果 NumRecords 参数大于零，则当前记录位置向前移动（向 Recordset 的结尾移动）。如果 NumRecords 小于零，则当前记录位置向后移动（向 Recordset 的开始移动）。

如果 Move 调用将当前记录位置移动到首记录之前，ADO 会将当前记录的位置设置在 Recordset 的首记录之前（BOF 为 True）。在 BOF 属性设置为 True 时，试图向后移动将产生错误。

如果 Move 调用将当前记录位置移动到最后一个记录之后，ADO 会将当前记录的位置设置在 Recordset 的最后一个记录之后（EOF 为 True）。在 EOF 属性设置为 True 时，试图向后移动将产生错误。

从空的 Recordset 对象调用 Move 方法将产生错误。

假定Recordset 支持书签，如果在 Start 参数中传递书签，将相对于具有此书签的记录移动。书签可通过 Bookmark 属性获得。如果未指定书签，将相对于当前记录移动。

如果使用 CacheSize 属性在本地缓存来自提供者的记录，传送将当前记录位置移动到当前缓存记录组之外的 NumRecords 参数时，将强制 ADO 从目标记录开始检索新的记录组。CacheSize 属性确定新检索的组的大小，而目标记录是检索的第一个记录。


在 Recordset 中移动的更多方法

后面的四种方法用来在 Recordset 中来回移动或滚动：MoveFirst、MoveLast、MoveNext 和 MovePrevious。（其中有的方法对仅向前游标不可用。）

使用 MoveFirst 方法将当前记录位置移动到 Recordset 中的第一个记录。使用 MoveLast 方法将当前记录位置移动到 Recordset 中的最后一个记录。若要使用 MoveFirst 或 MoveLast 方法，Recordset 对象必须支持书签或向后移动游标；否则调用该方法将产生错误。

使用 MoveNext 方法将当前记录向前移动一个位置。如果在调用 MoveNext 时处于最后一条记录的位置，则 EOF 被设置为 True。使用 MovePrevious 方法将当前记录向后移动一个位置。如果在调用 MovePrevious 时处于第一条记录的位置，则 BOF 被设置为 True。在使用这些方法时检查 EOF 和 BOF 属性并在超出 Recordset 的任意一端时将游标移回到有效的当前记录位置不失为明智之举，如下所示：

. . .
oRs.MoveNext
If oRs.EOF Then oRs.MoveLast
. . .

或者，在 MovePrevious 方法下：

. . .
oRs.MovePrevious
If oRs.BOF Then oRs.MoveFirst
. . .

在 Recordset 已被过滤或排序且当前记录的数据已更改的情况下，位置可能也会改变。在这种情况下，MoveNext 方法运行正常，但应注意该位置已从新位置向前移动一个记录，而非原来的位置。例如，更改当前记录的数据，使记录移动到已排序的 Recordset 的结尾，这意味着调用 MoveNext 将导致 ADO 将当前记录位置设置在 Recordset 中的最后一个记录之后 (EOF = True)。

Recordset 对象的各种 Move 方法的行为在某种程度上取决于 Recordset 中的数据。添加到 Recordset 的新记录最初是以特定的顺序添加的，该顺序由数据源定义，而且可能显式或隐式依赖于新记录的数据。例如，如果在预置 Recordset 的查询内进行了排序或连接，新记录就会插入到 Recordset 的适当位置。如果在创建 Recordset 时未显式排定顺序，那么在数据源实现中所做的更改会导致返回的行的顺序发生不经意的改变。此外，Recordset 的排序、过滤和编辑功能也会影响记录的顺序，而且可能会影响数据集中的哪些行将是可见的。

因此，MoveNext、MovePrevious、MoveFirst、MoveLast 和 Move 对在同一个 Recordset 中执行的其他操作都很敏感。ADO 在显式移动当前的位置之前会始终尽量保持这个位置，但有时插入的更改使得用户很难理解进行后续移动的效果。例如，如果您调用 MoveFirst 方法定位到已排序的 Recordset 的第一行，然后将升序排列改为降序排列，那么您仍然处于同一行，但此刻是处于 Recordset 的最后一行。使用 MoveFirst 方法将把您带到不同的一行（新的第一行）。

再举一个范例，如果您定位于 Recordset 中间的某个特定行，您调用了 Delete，然后又调用了 MoveNext，那么您现在处于紧跟在已删除记录的下一个记录上。而调用 MovePrevious 使得所删除记录的前一个记录成为当前记录，因为被删除的记录不再被计入 Recordset 的活动成员范围之内。

在当前记录中的数据发生更改时，对于相对于当前记录进行移动的方法（MovePrevious、MoveNext 和 Move）而言，针对所有的提供者定义一致的移动语义尤为困难。例如，如果您在使用一个已排序、已过滤的 Recordset 工作，您更改了当前记录中的数据以便它能够处于其他所有记录之前，但您所更改的数据也不再与过滤器匹配，因此 MoveNext 操作将把您带到什么位置也就无从知晓了。最安全的结论是如果在编辑、添加或删除记录时数据发生了变化，那么 Recordset 中的相对移动要比绝对移动（例如，使用 MoveFirst 或 MoveLast）风险更大。排序和过滤应当基于主键或 ID，因为这一类型的值不会更改。


使用书签

在 Recordset 的记录之间来回移动后，无须逐一滚动每个记录和比较记录值即可直接返回到某个特定记录常常极为有用。例如，您试图使用 Find 方法来搜索一个记录，但搜索结果并未返回任何记录，这时，您就会自动处于 Recordset 两端中的一端。但如果您的提供者支持书签功能，那么您就可以在使用 Find 方法之前利用书签在当前位置做上标记，这样您就能够直接返回到原来的位置。书签是 Variant 类型值，用于唯一地标识 Recordset 对象中的记录。

还可将 Recordset 的 Filter 方法用于 Variant 书签数组来过滤一组选定的记录。有关该技术的详细信息，请参阅本章后面的使用 Recordset 主题中的“过滤结果”。

可利用 Bookmark 属性获得记录的书签，或将 Recordset 对象中的当前记录设置为由有效书签标识的记录。下面的代码使用 Bookmark 属性设置了一个书签，在移动至其他记录后又返回到这个带有标识的记录。若要确定 Recordset 是否支持书签功能，请使用 Supports 方法。

'BeginBookmarkEg
    Dim varBookmark As Variant
    Dim blnCanBkmrk As Boolean

    objRs.Open strSQL, strConnStr, adOpenStatic, adLockOptimistic, adCmdText

    If objRs.RecordCount > 4 Then
        objRs.Move 4                       ' move to the fifth record
        blnCanBkmrk = objRs.Supports(adBookmark)
        If blnCanBkmrk = True Then
            varBookmark = objRs.Bookmark   ' record the bookmark
            objRs.MoveLast                 ' move to a different record
            objRs.Bookmark = varBookmark   ' return to the bookmarked (sixth) record
        End If
    End If
'EndBookmarkEg

Supports 方法将在后面详细讨论。

除了复制的 Recordset 以外，各书签对于在其中创建它们的 Recordset 都是唯一的，即使使用同样的命令也是如此。这意味着不能使用从一个 Recordset 得到的 Bookmark，将它移动到用同一命令打开的第二个 Recordset 中的相同记录。


使用页

用 PageCount 属性确定 Recordset 对象中数据的页数。Pages 是大小与 PageSize 属性设置相等的记录组。即使最后一页因为记录比 PageSize 值少而不完整，在 PageCount 值中仍作为附加页计数。如果 Recordset 对象不支持此属性，则 PageCount 值为 -1，指示该 PageCount 无法确定。

用 PageSize 属性确定组成一个数据逻辑页的记录数目。建立页大小允许用 AbsolutePage 属性移动到特定页的第一个记录。如果要在 Web 服务器方案中允许用户逐页查看数据，那么此属性将非常有用，因为用户可以一次查看一定数量的记录。

可以随时设置此属性，其值将用来计算特定页的第一个记录的位置。

用 AbsolutePage 属性可标识当前记录所在的页码。同样，提供者必须支持相应的功能才能使用此属性。

AbsolutePage 从 1 开始，并且在当前记录是 Recordset 的第一个记录时等于 1。设置此属性可移动到某一页的第一个记录。通过 PageCount 属性可获得总页数。


Recordset 定位

使用 AbsolutePosition 属性可根据在 Recordset 对象中的序号位置移动到某一记录，或确定当前记录的序号位置。提供者必须支持相应的功能才能使用此属性。

AbsolutePosition 从 1 开始，并且在当前记录是 Recordset 的第一个记录时等于 1。正如前面提到的那样，可以通过 RecordCount 属性获取 Recordset 对象中记录的总数目。

设置 AbsolutePosition 属性时，即使该属性指向当前缓存中的记录，ADO 也将使用以用户指定的记录开始的新记录组来重载缓存。CacheSize 属性决定此记录组的大小。

注意 不应将 AbsolutePosition 属性作为替代的记录编号使用。删除前面的记录时，给定记录的位置将发生更改。如果重新查询或重新打开 Recordset 对象，则无法保证给定的记录会有相同的 AbsolutePosition。书签是保持和返回给定位置的建议方式，并且是跨越 Recordset 对象的所有类型定位的唯一方式。


了解 Recordset 结构

每个 Recordset 都包含由一个或多个 Field 对象组成的 Fields 集合。一个 Field 对象通常表示一个表列。下面的主题将解释如何循环 Fields 集合并获取有关各个字段的信息。然后它们将讨论您通过 Field 对象能够获取哪些可用信息以及使用这些信息的方法。

  • Fields 集合
  • Field 对象
  • 使用 Recordset


Fields 集合

Fields 集合是 ADO 的固有集合之一。集合是一组有序的项，可以被看作是一个单元。有关 ADO 集合的详细信息，请参阅第 1 章中的 ADO 对象模型。

Fields 集合包含 Recordset 中针对每个字段（列）的 Field 对象。与所有的 ADO 集合一样，它具有 Count 和 Item 属性以及 Append 和 Refresh 方法。它还具有 CancelUpdate、Delete、Resync 和 Update 方法，而这些方法对其他 ADO 集合都不可用。

检验 Fields 集合

请考虑本章所介绍的范例 Recordset 中的 Fields 集合。范例 Recordset 源自 SQL 语句

SELECT ProductID, ProductName, UnitPrice FROM Products WHERE CategoryID = 7

由此，您就会发现 Recordset 的 Fields 集合包含三个字段。

'BeginWalkFields
    Dim objFields As ADODB.Fields

    objRs.Open strSQL, strConnStr, adOpenForwardOnly, adLockReadOnly, adCmdText

    Set objFields = objRs.Fields

    For intLoop = 0 To (objFields.Count - 1)
        Debug.Print objFields.Item(intLoop).Name
    Next
'EndWalkFields

此代码仅使用 Count 属性确定 Fields 集合中 Field 对象的数目，并循环该集合，返回每个 Field 对象的 Name 属性的值。可使用 Field 的更多属性来获取有关某个字段的信息。有关查询 Field 的详细信息，请参阅 Field 对象。

计算列

正如您所期望的那样，Count 属性返回 Fields 集合中 Field 对象的实际数目。因为集合成员的编号从零开始，因此应该始终以零成员开始并以 Count 属性值减 1 结束来编写循环代码。如果正在使用 Microsoft Visual Basic 并希望在不检查 Count 属性的情况下循环集合的成员，请使用 For Each...Next 命令。

如果 Count 属性为零，说明此集合中没有对象。

访问 Field

与任何 ADO 集合一样，Item 属性是该集合的默认属性。它返回由传递给它的名称和索引所指定的单个 Field 对象。因此，下列语句与范例 Recordset 异曲同工：

objField = objRecordset.Fields.Item("ProductID")
objField = objRecordset.Fields("ProductID")
objField = objRecordset.Fields.Item(0)
objField = objRecordset.Fields(0)

如果这些方法对等，那么哪种方法最好呢？依情况而定。使用索引从该集合中检索某个 Field 速度更快，因为它无须执行字符串查找即可直接访问该 Field。但在另一方面，必须了解该集合中 Field 的顺序，如果顺序被更改，对 Field 的索引的引用也会在顺序发生更改的地方随之更改。尽管使用 Field 的名称进行检索速度稍慢一些，但使用起来更加灵活，因为它并不依赖集合中 Field 的顺序。

使用 Refresh 方法

与其他的一些 ADO 集合不同，使用 Fields 集合的 Refresh 方法将没有可视效果。要从基本数据库结构中检索更改，必须使用 Requery 方法；如果 Recordset 对象不支持书签，则必须使用 MoveFirst 方法，该方法将使命令针对提供者再执行一次。

将字段添加到 Recordset

Append 方法用来将字段添加到 Recordset。

可使用 Append 方法在不打开到数据源的连接的情况下通过编程虚构 Recordset。如果在打开的 Recordset 的 Fields 集合上或者在设置了 ActiveConnection 属性的 Recordset 上调用 Append 方法，将发生运行时错误。只能将字段追加到未打开且未连接到数据源的 Recordset。但是，若要指定新追加的 Field 的值，必须首先打开 Recordset。

开发人员经常需要在某个地方临时存储一些数据，或者需要某些数据充当来自服务器的数据，以使其参与用户接口中的数据绑定。ADO（连同 Microsoft Cursor Service for OLE DB）使开发人员能够通过指定列信息并调用 Open 来建立空的 Recordset 对象。在下面的示例中，三个新字段被追加到一个新的 Recordset 对象。然后 Recordset 被打开并添加了两个新记录，而且此 Recordset 被持久保存在文件中。（有关 Recordset 持久性的详细信息，请参阅第 5 章：更新和保持数据。）

    'BeginFabricate
    Dim objRs As New ADODB.Recordset

    With objRs.Fields
        .Append "StudentID", adChar, 11, adFldUpdatable
        .Append "FullName", adVarChar, 50, adFldUpdatable
        .Append "PhoneNmbr", adVarChar, 20, adFldUpdatable
    End With

    With objRs
        .Open

        .AddNew
        .Fields(0) = "123-45-6789"
        .Fields(1) = "John Doe"
        .Fields(2) = "(425) 555-5555"
        .Update

        .AddNew
        .Fields(0) = "123-45-6780"
        .Fields(1) = "Jane Doe"
        .Fields(2) = "(615) 555-1212"
        .Update
    End With

    objRs.Save App.Path & "\FabriTest.adtg", adPersistADTG

    objRs.Close
    'EndFabricate

Fields 的 Append 方法对于 Recordset 对象和 Record 对象用法有所不同。有关 Record 对象的详细信息，请参阅第 10 章：Record 和 Stream。

请参阅

虚构分级记录集


Field 对象

通常，每个 Field 对象都对应于数据库表中的一列。但是，Field 也可以表示指向另一个 Recordset（称为子集）的指针。例外情况（例如子集列）将在本指南随后的内容中介绍。

使用 Field 对象的 Value 属性可以设置或返回当前记录的数据。Field 对象的某些集合、方法或属性可能不可用，这取决于提供者显露的功能。

用 Field 对象的集合、方法和属性可以执行下列操作：

  • 使用 Name 属性可以返回字段名。
  • 使用 Value 属性可以查看或更改字段中的数据。Value 是 Field 对象的默认属性。
  • 使用 Type、Precision 和 NumericScale 属性可以返回字段的基本特性。
  • 使用 DefinedSize 属性可以返回已声明的字段大小。
  • 使用 ActualSize 属性可以返回给定字段中的数据的实际大小。
  • 使用 Attributes 属性和 Properties 集合可以确定给定字段所支持的功能类型。
  • 使用 AppendChunk 和 GetChunk 方法可以操作包含长二进制或长字符数据的字段值。

如果提供者支持批更新，请用 OriginalValue 和 UnderlyingValue 属性在批更新过程中解决字段值之间的差异。

描述字段

下面的主题将讨论 Field 对象的属性，该对象所表示的信息描述了 Field 对象本身（即关于该字段的元数据）。该信息可以用来确定关于 Recordset 的架构的很多信息。这些属性包括 Type、DefinedSize 和 ActualSize、Name 以及 NumericScale 和 Precision。

发现数据类型

Type 属性表示字段的数据类型。《ADO 程序员参考》中的 DataTypeEnum 描述了ADO 所支持的数据类型枚举常量。

对于浮点型数字类型（比如 adNumeric），可以获得更多信息。NumericScale 属性指示在小数点右侧有多少位数字将用于代表 Field 的值。Precision 属性指定用来代表 Field 值的数字的最大个数。

确定字段大小

用 DefinedSize 属性确定 Field 对象的数据容量。

用 ActualSize 属性返回 Field 对象的值的实际长度。对于所有字段，ActualSize 属性均为只读。如果 ADO 无法确定 Field 对象的值的长度，ActualSize 属性将返回 adUnknown。

DefinedSize 和 ActualSize 属性用途不同。例如，假设 Field 对象声明类型为 adVarChar，DefinedSize 属性值为 50，并包含单个字符。该对象返回的 ActualSize 属性值是单个字符的字节长度。

确定字段内容

数据源中列的标识符由 Field 的 Name 属性表示。Field 对象的 Value 属性返回或设置字段的实际数据内容。这是默认的属性。

若要更改字段中的数据，请将 Value 属性设置为等于类型正确的新值。游标类型必须支持用于更改字段内容的更新。在这里，数据库验证不能在批模式中完成，因此，在这种情况下调用 UpdateBatch 时需要检查是否有错误。某些提供者还支持 ADO Field 对象的 UnderlyingValue 和 OriginalValue 属性，以便在您试图执行批更新时帮助您解决冲突。关于如何解决冲突的详细内容，请参阅第 4 章：编辑数据。

注意 将新的 Fields 追加到 Recordset 中时，不能设置 Recordset Field 值。新的 Fields 可以追加到关闭的 Recordset 中。然后，必须打开 Recordset，只有这时才能对这些 Fields 赋值。

获得更多字段信息

ADO 对象有两种类型的属性：内置属性和动态属性。对于这一点，只有 Field 对象的内置属性已经讨论过。

内置属性是在 ADO 中实现的属性，任何新对象都可以用 MyObject.Property 语法立即访问这些属性。在对象的 Properties 集合中，它们并不作为 Property 对象出现。

动态属性由基本数据提供者定义，并出现在适当的 ADO 对象的 Properties 集合中。例如，提供者特有的属性可能会指示 Recordset 对象是否支持事务或更新。这些附加属性在该 Recordset 对象的 Properties 集合中将作为 Property 对象出现。动态属性只能通过集合进行引用，引用时使用语法 MyObject.Properties(0) 或 MyObject.Properties("Name")。

这两种属性都无法删除。

动态 Property 对象自身有四个内置属性：

  • Name 属性是一个用于标识属性的字符串。
  • Type 属性是一个用于指定属性数据类型的整数。
  • Value 属性是一个包含属性设置的变体。Value 是 Property 对象的默认属性。
  • Attributes 属性是一个 Long 值，用于指示提供者特有的属性的特征。

Field 对象的 Properties 集合包含关于字段的额外的元数据。该集合的内容取决于提供者而各不相同。以下代码范例检查在本章开头所介绍的范例 Recordset 的 Properties 集合。它首先查看集合的内容。该代码使用 OLE DB Provider for SQL Server，因此 Properties 集合包含与提供者相关的信息。

'BeginFieldProps
    Dim objProp As ADODB.Property

    For intLoop = 0 To (objFields.Count - 1)
        Debug.Print objFields.Item(intLoop).Name

        For Each objProp In objFields(intLoop).Properties
            Debug.Print vbTab & objProp.Name & " = " & objProp.Value
        Next objProp
    Next intLoop
'EndFieldProps

处理二进制数据

使用 Field 对象的 AppendChunk 方法可以填充 Long 类型二进制数据或字符数据。在系统内存有限的情况下，可使用 AppendChunk 方法操作部分而非全部的 Long 值。

如果 Field 对象的 Attributes 属性中的 adFldLong 位设置为 True，则可以对该字段使用 AppendChunk 方法。

在 Field 对象上的第一个 AppendChunk 调用将数据写入字段，覆盖任何现有数据。后续的 AppendChunk 调用向现有数据中添加数据。如果要将数据追加到一个字段然后在当前记录中设置或读取其他字段的值，ADO 会认为已完成向第一个字段追加数据。如果在第一个字段上再次调用 AppendChunk 方法，ADO 将把这次调用解释为新的 AppendChunk 操作并覆盖现有数据。访问其他 Recordset 对象（并非第一个 Recordset 对象的副本）中的字段将不会中断 AppendChunk 操作。

使用 Field 对象的 GetChunk 方法来检索其中的部分或全部长二进制或字符数据。在系统内存有限的情况下，可使用 GetChunk 方法操作部分而非全部 Long 值。

GetChunk 调用返回的数据将被分配给 variable。如果 Size 大于剩余的数据，GetChunk 方法仅返回剩余的数据而不用空格填充 variable。如果该字段为空，GetChunk 方法将返回 Null 值。

每个后续的 GetChunk 调用将从上一次 GetChunk 调用停止处开始检索数据。但是，如果从一个字段中检索数据，然后设置或读取当前记录中另一个字段的值，那么，ADO 将假设您已经完成从第一个字段检索数据的操作。如果对第一个字段再次调用 GetChunk 方法，ADO 将把这次调用解释为新的 GetChunk 操作，并从数据的开始处读取。访问其他 Recordset 对象（并非第一个 Recordset 对象的副本）中的字段将不会中断 GetChunk 操作。

如果 Field 对象的 Attributes 属性中的 adFldLong 位设置为 True，可以对该字段使用 GetChunk 方法。

如果使用 Field 对象的 Getchunk 或 AppendChunk 方法时没有当前记录，将产生错误 3021（没有当前记录）。

若要查看使用这些方法操作二进制数据的范例，请参阅《ADO 程序员参考》中的 AppendChunkMethod 和 GetChunkMethod 范例。


使用 Recordset

Recordset 对象具有内置功能，借助这些功能您可重新排列结果集中数据的顺序，基于您提供的条件搜索特定的记录，甚至利用索引优化这些搜索操作。这些功能是否可用取决于提供者，在某些情况下（例如在 Index 属性情况下），取决于数据源本身的结构。

排列数据

通常情况下，对 Recordset 中的数据进行排序的最有效方式是在将结果返回 Recordset 的 SQL 命令中指定 ORDER BY 子句。但是，可能需要更改已经创建的 Recordset 中的数据顺序。可使用 Sort 属性来建立遍历 Recordset 行的顺序。而且，Filter 属性可确定遍历行时可访问的行。

Sort 属性设置或返回 String 值，指示要作为 Recordset 排序基准的字段名称。每个名称均由逗号分隔，逗号后面还可以有一个空格和关键字 ASC（按升序对字段进行排序）或 DESC（按降序对字段进行排序）。如果未指定关键字，默认情况下将按升序对字段进行排序。

由于并没有对数据进行物理上的重新排列，因此排序操作仍有效，只不过是按索引指定的顺序进行访问。

Sort 属性要求将 CursorLocation 属性设置为 adUseClient。如果索引已不存在，则将为 Sort 属性中指定的每个字段创建临时索引。

将 Sort 属性设置为空字符串将会把行重置为原始顺序并删除临时索引。现有的索引不会被删除。

假设 Recordset 包含三个字段，名称为 firstName、middleInitial 和 lastName。如果将 Sort 属性设置为字符串“lastName DESC, firstName ASC”，则会按姓氏对 Recordset 进行降序排序，然后按名字进行升序排序。中间名被忽略。

不能将在排序条件字符串中引用的字段命名为“ASC”或“DESC”，因为这些名称与关键字 ASC 和 DESC 相冲突。请使用返回 Recordset 的查询中的 AS 关键字来为有名称冲突的字段设置别名。

有关 Recordset 过滤的详细信息，请参阅本主题后面的“过滤结果”。

查找特定的记录

ADO 提供了 Find 和 Seek 方法来定位 Recordset 中特定的记录。许多提供者都支持 Find 方法，但此方法仅限于单个的搜索条件。而 Seek 方法支持多个条件下的搜索，但许多供应者不支持此方法。

对字段进行索引可以大大提高 Recordset 对象的 Find 方法以及 Sort 和 Filter 属性的性能。通过设置 Field 对象的动态 Optimize 属性可以创建该对象的内部索引。将 CursorLocation 属性设置为 adUseClient 时，此动态属性将被添加到 Field 对象的 Properties 集合中。请记住，此索引只在 ADO 内部使用，您不能访问该索引或者将其用于任何其他目的。而且，此索引有别于 Recordset 对象的 Index 属性。

Find 方法可迅速定位 Recordset 列（字段）中的值。用 Optimize 属性创建一个列的索引，通常可以提高对列执行 Find 方法的操作速度。

Find 方法把搜索条件限定为某个字段的内容。Seek 方法要求您有索引，它也有其他的限制。如果需要搜索不以索引为基础的多个字段，或者提供者不支持索引，可用 Recordset 对象的 Filter 属性来限制搜索结果。

Find

Find 方法搜索 Recordset 中满足指定条件的行。可选择指定搜索方向、起始行和从起始行的偏移量。如果满足条件，当前行的位置将设置在找到的记录上；否则将根据搜索方向把当前行位置设置为 Recordset 的结尾（或开始）处。

只能对条件指定单列名称，换句话说，此方法不支持多列搜索。

条件中的比较操作符可以是“>”（大于）、“<”（小于）、“=”（等于）、“>=”（大于或等于）、“<=”（小于或等于）、“<>”（不等于）或“LIKE”（模式匹配）。

条件值可以是字符串、浮点数或者日期。字符串值用单引号或“#”标记（数字号）分隔（如“state = 'WA'”或“state = #WA#”）。日期值用“#”标记（数字号）分隔（如“start_date > #7/22/97#”）。

如果比较操作符为“like”，可以在字符串值中包含星号 (*) 以查找一次或多次出现的任意字符或子字符串。例如，“state like 'M*'”与 Maine 和 Massachusetts 匹配。您还可以使用前导和后续星号以查找包含在值内的子字符串。例如，“state like '*as*'”与 Alaska、Arkansas 和 Massachusetts 匹配。

星号可以只在条件字符串的结尾使用，也可以在条件字符串的开头和结尾一起使用，如上所示。不能将星号作为前导通配符 ('*str') 或嵌入通配符 ('s*r') 使用。这将引发错误。

Seek 和 Index

如果基本提供者支持 Recordset 对象上的索引，请将 Seek 方法和 Index 属性结合使用。用 Supports (adSeek) 方法确定基本提供者是否支持 Seek，用 Supports(adIndex) 方法确定提供者是否支持索引。（例如，OLE DB Provider for Microsoft Jet 支持 Seek 和 Index。）

如果 Seek 没有找到所需的行，将不会产生错误，该行将被放在 Recordset 的结尾处。执行此方法前，请先将 Index 属性设置为所需的索引。

此方法只受服务器端游标支持。如果 Recordset 对象的 CursorLocation 属性值为 adUseClient，将不支持 Seek。

只有当 CommandTypeEnum 值为 adCmdTableDirect 时打开 Recordset 对象，才可以使用此方法。

过滤结果

Find 方法把搜索条件限定为某个字段的内容。Seek 方法要求您有索引，它也有其他的限制。如果需要搜索不以索引为基础的多个字段，或者提供者不支持索引，可用 Recordset 对象的 Filter 属性来限制搜索结果。

用 Filter 属性可选择性地屏蔽 Recordset 对象中的记录。经过过滤的 Recordset 变为当前游标，这意味着不满足 Filter 条件的记录直到 Filter 被删除后才可用在 Recordset 中。基于当前游标返回值的其他属性将受到影响，如 AbsolutePosition、AbsolutePage、RecordCount 及 PageCount。这是因为将 Filter 属性设置为特定值可将当前记录移动到满足新值的第一个记录。

Filter 属性接受 Variant 参数。该值表示使用 Filter 属性时用到的三种方法之一：条件字符串、FilterGroupEnum 常量或书签数组。有关详细信息，请参阅本主题后面的“使用条件字符串过滤”、“使用常量过滤”和“使用书签过滤”。

注意 当要选择的数据已知时，使用有效过滤结果集的 SQL 语句打开 Recordset 通常更为有效，而不是依赖 Filter 属性。

若要将过滤器从 Recordset 删除，请使用 adFilterNone 常量。将 Filter 属性设置为零长度字符串 ("") 与使用 adFilterNone 常量具有相同效果。

使用条件字符串过滤

条件字符串由 FieldName Operator Value 格式（例如“LastName = 'Smith'”）子句组成。通过连接单独的 AND（例如“LastName = 'Smith' AND FirstName = 'John'”）和 OR（如“LastName = 'Smith' OR LastName = 'Jones'”）子句可以创建复合子句。关于条件字符串，请遵循以下规则：

  • FieldName 必须是 Recordset 中有效的字段名。如果字段名包含空格，必须将字段名括在方括号中。
  • Operator 必须是下列字符串之一：<、>、<=、>=、<>、= 或 LIKE。
  • Value 是用于与字段值进行比较的值（如 'Smith'、#8/24/95#、12.345 或 $50.00）。字符串使用单引号，日期使用磅符号 (#)。数字可以使用小数点、美元符号和科学符号。如果 Operator 为 LIKE，则 Value 可以使用通配符。只允许使用星号 (*) 和百分号 (%) 通配符，而且必须是字符串的尾字符。Value 不能为 Null。
    注意 若要在过滤 Value 中包括单引号 (')，请用两个单引号表示一个引号。例如，若要过滤 O'Malley，则条件字符串应为“col1 = 'O''Malley'”。若要在过滤值的开始和结尾处都包括单引号，请用磅符号 (#) 将字符串括起来。例如，若要过滤 '1'，则条件字符串应为“col1 = #'1'#”。

AND 和 OR 在级别上没有先后之分。可用括号将子句分组。但不能象下例所示那样先将由 OR 连接的子句分组，然后再用 AND 将该组连接到其他子句：

(LastName = 'Smith' OR LastName = 'Jones') AND FirstName = 'John'

与之相反，可将此过滤构造为：

(LastName = 'Smith' AND FirstName = 'John') OR (LastName = 'Jones' AND FirstName = 'John')

在 LIKE 子句中，可在模式的开头和结尾使用通配符（例如 LastName Like '*mit*'），或者只在模式的结尾使用通配符（例如 LastName Like 'Smit*'）。

使用常量过滤

下面的常量可用来过滤 Recordsets。

常量 | 说明
adFilterAffectedRecords
 过滤器，用于仅查看受最后一次 Delete、Resync、UpdateBatch 或 CancelBatch 调用影响的记录。
adFilterConflictingRecords | 过滤器，用于查看使最后一次批更新失败的记录。
adFilterFetchedRecords | 过滤器，用于查看当前缓存（即最后一次检索数据库中记录的结果）中的记录。
adFilterNone | 删除当前过滤器，并恢复查看所有记录。
adFilterPendingRecords | 过滤器，用于仅查看已更改但尚未发送到服务器的记录。仅对批更新模式适用。

通过仅允许查看诸如上次调用 UpdateBatch 方法时受到影响的记录，过滤常量可以更容易地解决在批更新模式中发生的单个记录冲突，如以下范例所示：

'BeginDeleteGroup
    'add some bogus records
    With objRs1
        For i = 0 To 8
            .AddNew
            .Fields("CompanyName") = "Shipper Number " & i + 1
            .Fields("Phone") = "(425) 555-000" & (i + 1)
            .Update
        Next i

    're-connect & update
        .ActiveConnection = GetNewConnection
        .UpdateBatch

    'filter on newly added records
        .Filter = adFilterAffectedRecords
        Debug.Print "Deleting the " & .RecordCount & _
                    " records you just added."

    'delete the newly added bogus records
        .Delete adAffectGroup
        .Filter = adFilterNone
        Debug.Print .RecordCount & " records remain."

        .Close
    End With
'EndDeleteGroup

使用书签过滤

最后，可将书签的 Variant 数组传递给 Filter 属性。所得到的游标将只包含书签被传递给该属性的记录。下面的代码范例用 Recordset 中 ProductName 字段包含“B”的记录创建一个书签数组，然后将数组传递给 Filter 属性，并显示关于生成的经过过滤的 Recordset 信息。

'BeginFilterBkmk
    Dim vBkmkArray() As Variant
    Dim i As Integer

    'Recordset created using "SELECT * FROM Products" as command.
    'So, we will check to see if ProductName has a capital B, and
    'if so, add to the array.
    i = 0
    Do While Not objRs.EOF
        If InStr(1, objRs("ProductName"), "B") Then
            ReDim Preserve vBkmkArray(i)
            vBkmkArray(i) = objRs.Bookmark
            i = i + 1
            Debug.Print objRs("ProductName")
        End If
        objRs.MoveNext
    Loop

    'Filter using the array of bookmarks.
    objRs.Filter = vBkmkArray

    objRs.MoveFirst
    Do While Not objRs.EOF
        Debug.Print objRs("ProductName")
        objRs.MoveNext
    Loop
    'EndFilterBkmk

创建 Recordset 的副本

使用 Clone 方法可创建多个相同的 Recordset 对象，这对于想要在给定的记录组中保留多个当前记录尤其有用。使用 Clone 方法比创建和打开与原对象定义相同的新 Recordset 对象更为有效。

将新创建副本的当前记录设置为首记录。复制的 Recordset 中的当前记录指针将不再与原 Recordset 同步，反之亦然。您可在 Recordset 中独立导航。

不管游标类型如何，对一个 Recordset 对象所做的更改将在其所有副本中显示。但是在对原 Recordset 执行 Requery 后，副本将不再与原 Recordset 同步。

关闭原 Recordset 时并不关闭其副本，而关闭副本也不会关闭原 Recordset 或任何其他副本。

只有在 Recordset 对象支持书签时才能复制该对象。书签值是可交换的，也就是说，来自一个 Recordset 对象的书签引用可引用其任何副本中的相同记录。


第 4 章：编辑数据

前面两章解释了如何使用 ADO 执行这些操作：连接到数据源、执行命令、获得 Recordset 对象中的结果、在 Recordset 中导航。这一章集中讨论下一个基本 ADO 操作：编辑数据。

这一章继续使用第 3 章中介绍的范例 Recordset，但有一个重要更改。以下代码用来打开 Recordset：

    . . .
'BeginEditIntro
    Dim strSQL As String
    Dim objRs1 As ADODB.Recordset

    strSQL = "SELECT * FROM Shippers"

    Set objRs1 = New ADODB.Recordset

    objRs1.Open strSQL, GetNewConnection, adOpenStatic, _
                adLockBatchOptimistic, adCmdText

    ' Disconnect the Recordset from the Connection object.
    Set objRs1.ActiveConnection = Nothing
'EndEditIntro

    . . .

对代码的重要更改涉及在 GetNewConnection 函数（在下面显示）中将 Connection 对象的 CursorLocation 属性设置为等于 adUseClient，这将指示程序使用客户端游标。有关客户端游标和服务器端游标之间的差异的详细信息，请参阅第 8 章：理解游标和锁定。

CursorLocation 属性的 adUseClient 设置将把游标位置从数据源（在这里是 SQL Server）移动到客户端代码的位置（桌面工作站）。该设置将强制 ADO 在客户端调用 Client Cursor Engine for OLE DB，以便创建和管理游标。

您可能还注意到：Open 方法的 LockType 参数已更改为 adLockBatchOptimistic。这将在批模式中打开游标。（提供者将缓存多个更改，只有当调用 UpdateBatch 方法时，才会将这些更改写入基本数据源。）对 Recordset 进行的更改将在调用 UpdateBatch 方法之后才能更新到数据库中。

最后，本章代码使用了经过修改的 GetNewConnection 函数版本，第 2 章对此进行了介绍。现在，该版本函数返回的是客户端游标。函数类似下例：

'BeginNewConnection
Public Function GetNewConnection() As ADODB.Connection
    Dim objConn1 As ADODB.Connection
    Set objConn1 = New ADODB.Connection

    strConnStr = "Provider=SQLOLEDB;Initial Catalog=Northwind;" & _
                 "Data Source=MySrvr;Integrated Security=SSPI;"

    objConn1.ConnectionString = strConnStr
    objConn1.CursorLocation = adUseClient
    objConn1.Open

    Set GetNewConnection = objConn1
End Function
'EndNewConnection


编辑现有记录

若要编辑现有记录，请移动到想要编辑的行，并更改相应字段的 Value 属性。有关 Field 对象的 Value 属性的详细信息，请参阅第 3 章：检验数据。使用 Update 或 UpdateBatch（取决于游标类型）可以将更改发送回数据源。详细信息，请参阅第 5 章：更新和保持数据。

因为存储过程不需要创建游标，所以，通常更有效的方法是：配合命令对象使用存储过程来执行更新，并执行其他操作。有关游标的详细信息，请参阅第 8 章：理解游标和锁定。


添加记录

使用 AddNew 方法在现有的 Recordset 中创建并初始化新记录。可以使用带有 adAddNew CursorOptionEnum 值的 Supports 方法来验证是否能够将记录添加到当前的 Recordset 对象。

在调用 AddNew 方法后，新记录将成为当前记录，并在调用 Update 方法后仍保持为当前记录。如果 Recordset 对象不支持书签，那么一旦移至其他记录则无法访问此新记录。因此，根据游标类型，可能需要调用 Requery 方法以访问新记录。

如果在编辑当前记录或添加新记录时调用 AddNew，ADO 将调用 Update 方法以保存更改，然后创建新记录。


用 AddNew 添加记录

这是 AddNew 方法的基本语法：

recordset.AddNew FieldList, Values

FieldList 和 Values 参数是可选的。FieldList 是新记录中字段的单个名称、名称数组或序号位置数组。

Values 参数是新记录中字段的单个值或值的数组。

通常，要添加一个单个记录时，会调用不带任何参数的 AddNew 方法。特别是会调用 AddNew 来设置新记录中每个字段的 Value，然后调用 Update 和/或 UpdateBatch。使用带 adAddNew 枚举常量的 Supports 属性，可以确保您的 Recordset 支持添加新记录。

下列代码使用这一技术将一个新的 Shipper 添加到范例 Recordset。ShipperID 字段值是由 SQL Server 自动提供的，所以代码不尝试为新记录提供字段值。

'BeginAddNew1.1
    If objRs1.Supports(adAddNew) Then
        With objRs1
            .AddNew
            .Fields("CompanyName") = "Sample Shipper"
            .Fields("Phone") = "(931) 555-6334"
            .Update
        End With
    End If
'EndAddNew1.1

由于在批模式下，代码使用带有客户端游标的断开连接的 Recordset，因此在能够调用 UpdateBatch 方法将更改传递到数据库之前，必须用新的 Connection 对象将 Recordset 重新连接到数据源。通过使用新函数 GetNewConnection 很容易完成这一操作。

'BeginAddNew1.2
    'Re-establish a Connection and update
    Set objRs1.ActiveConnection = GetNewConnection
    objRs1.UpdateBatch
'EndAddNew1.2


添加多个字段

有时候，将字段及其相应的值以数组的形式传递给 AddNew 方法，可能要比为每个新的字段多次设置 Value 效率更高。如果 FieldList 是数组，那么 Values 也必须是具有相同数目成员的数组；否则将发生错误。字段名称的次序必须与每个数组中的字段值的次序相匹配。下列代码将一个字段数组和一个值数组传递给 AddNew 方法。

'BeginAddNew2
    Dim avarFldNames As Variant
    Dim avarFldValues As Variant

    avarFldNames = Array("CompanyName", "Phone")
    avarFldValues = Array("Sample Shipper 2", "(931) 555-6334")

    If objRs1.Supports(adAddNew) Then
        objRs1.AddNew avarFldNames, avarFldValues
    End If

    'Re-establish a Connection and update
    Set objRs1.ActiveConnection = GetNewConnection
    objRs1.UpdateBatch
'EndAddNew2


确定编辑模式

ADO 负责维护一个与当前记录相关联的编辑缓冲区。EditMode 属性指示是否已更改了该缓冲区，或是否已创建新记录。使用 EditMode 可以确定当前记录的编辑状态。如果编辑进程已中断，则可以测试是否有挂起的更改，并确定是否需要使用 Update 或 CancelUpdate 方法。

EditMode 返回 EditModeEnum 常量之一，下表列出了这些常量。

常量 | 说明
adEditNone | 指示没有进行编辑操作。
adEditInProgress | 指示当前记录中的数据已修改但未保存。
adEditAdd | 指示已调用 AddNew 方法，而复制缓冲区中的当前记录是个尚未保存到数据库的新记录。
adEditDelete | 指示当前记录已被删除。

EditMode 只有存在当前记录时才返回有效值。如果 BOF 或 EOF 为 True 或当前记录已被删除，则 EditMode 将返回错误。


在“立即模式”和“批模式”中使用 AddNew

AddNew 方法的行为取决于 Recordset 对象的更新模式以及是否传送 Fieldlist 和 Values 参数。

在“立即更新模式”下（在这种模式下，一旦调用 Update 方法，提供者将把更改写入基本数据源），调用不带参数的 AddNew 方法将 EditMode 属性设置为 adEditAdd。提供者在本地缓存任何字段值的更改。调用 Update 方法可将新记录传递到数据库并将 EditMode 属性重置为 adEditNone。如果传递 FieldList 和 Values 参数，ADO 立即将新记录记入数据库（不必调用 Update）；EditMode 属性值不更改（adEditNone）。

在批更新模式下，调用不带参数的 AddNew 方法可将 EditMode 属性设置为 adEditAdd。提供者在本地缓存任何字段值的更改。调用 Update 方法可将新记录添加到当前 Recordset 并将 EditMode 属性重置为 adEditNone，但在调用 UpdateBatch 方法之前，提供者不会将更改传递到基本数据库。如果传递 FieldList 和 Values 参数，ADO 将把新记录发送给提供者以便存储在缓存中；需要调用 UpdateBatch 方法将新记录传递到基本数据库。有关 Update 和 UpdateBatch 的详细信息，请参阅第 5 章：更新和持久保存数据。


确定可支持的功能

Supports 方法用来确定是否指定的 Recordset 对象支持特定的功能类型。其语法以下：

boolean = recordset.Supports( CursorOptions )

Supports 返回布尔值，该值指示是否由 CursorOptions 参数所标识的所有功能都可以被提供者支持。可以使用 Supports 方法确定 Recordset 对象支持哪些功能类型。如果 Recordset 对象支持其对应常量包括在 CursorOptions 中的功能，则 Supports 方法返回 True。否则，它将返回 False。

使用 Supports 方法，可以检查 Recordset 对象是否支持以下功能：添加新记录、使用书签、使用 Find 方法、使用滚动、使用 Index 属性和执行批更新。若要查看常量及其意义的完整列表，请参阅 CursorOptionEnum。

尽管对于给定的功能，Supports 方法可能返回 True，但它不保证提供者能使该功能在所有情况下都可用。如果符合特定条件，Supports 方法只返回提供者是否能支持指定功能的信息。例如，Supports 方法可能指示 Recordset 对象支持更新，即使游标基于多个表联接 — 其中的某些列是不可更新的。


使用 Delete 方法删除记录

使用 Delete 方法将把 Recordset 对象中的当前记录或一组记录标记为删除。如果 Recordset 对象不允许删除记录，将发生错误。如果处在立即更新模式中，将在数据库中立即执行删除操作。如果无法成功删除记录（例如，由于违反数据库完整性），则在调用 Update 之后记录将继续处于编辑模式中。这意味着必须先使用 CancelUpdate 取消更新，然后才能离开当前记录（例如，使用 Close、Move 或 NextRecordset）。

如果处在批更新模式中，则记录将标记为从缓存中删除，并在调用 UpdateBatch 方法时才发生实际删除。（若要查看已删除的记录，请在调用 Delete 之后将 Filter 属性设置为 adFilterAffectedRecords。）

如果试图从已删除的记录中检索字段值，将生成错误。删除当前记录后，在移动到其他记录之前，已被删除的记录将保持为当前记录。一旦离开已删除的记录，就不能再访问它。

如果在事务中嵌套删除，可以用 RollbackTrans 方法恢复删除的记录。如果处于批更新模式中，可以用 CancelBatch 方法取消一个或一组挂起的删除。

如果因与基本数据冲突（如记录已被其他用户删除）而导致删除记录的尝试失败，提供者将向 Errors 集合返回警告，但不终止程序执行。只有在所有请求的记录都冲突时，才会产生运行时错误。

如果设置了 Unique Table 动态属性，并且 Recordset 是对多个表执行 JOIN 操作的结果，那么，Delete 方法将只从在 Unique Table 属性中命名的表内删除行。

Delete 方法可以接受可选参数，该参数允许指定哪些记录会受 Delete 操作的影响。该参数的唯一有效值是下面的 ADO AffectEnum 枚举常量之一：

  • adAffectCurrent 只影响当前记录。
  • adAffectGroup 只影响满足当前 Filter 属性设置的记录。必须将 Filter 属性设置为 FilterGroupEnum 值或 Bookmarks 数组才能使用该选项。

以下范例代码演示当调用 Delete 方法时如何指定 adAffectGroup。该范例将某些记录添加到范例 Recordset 中并更新数据库。然后使用 adFilterAffectedRecords 筛选枚举常量对 Recordset 进行筛选，这样将只留下刚刚添加的记录在 Recordset 中可见。最后，调用 Delete 方法，并指定满足当前 Filter 属性设置的所有记录（新记录）为应当删除的记录。

'BeginDeleteGroup
    'add some bogus records
    With objRs1
        For i = 0 To 8
            .AddNew
            .Fields("CompanyName") = "Shipper Number " & i + 1
            .Fields("Phone") = "(425) 555-000" & (i + 1)
            .Update
        Next i

    're-connect & update
        .ActiveConnection = GetNewConnection
        .UpdateBatch

    'filter on newly added records
        .Filter = adFilterAffectedRecords
        Debug.Print "Deleting the " & .RecordCount & _
                    " records you just added."

    'delete the newly added bogus records
        .Delete adAffectGroup
        .Filter = adFilterNone
        Debug.Print .RecordCount & " records remain."

        .Close
    End With
'EndDeleteGroup


替代方案：使用 SQL 语句

ADO 还允许使用命令作为其用于编辑数据的内置属性和方法的替代方案。在这一章中提到的所有操作也可以通过向数据源传递命令来完成，这取决于提供者。例如，SQL UPDATE 语句可以用来修改数据，而不用使用 Field 的 Value 属性。可以用 SQL INSERT 语句将新记录添加到数据源，而不需要使用 ADO 方法 AddNew。有关 SQL 或提供者的数据操作语言的详细信息，请参阅数据源文档。

例如，可以将包含 DELETE 语句的 SQL 字符串传递给数据库，以下代码显示了该方法：

'BeginSQLDelete
strSQL = "DELETE FROM Shippers WHERE ShipperID = " & intId
objConn.Execute strSQL, , adCmdText + adExecuteNoRecords
'EndSQLDelete


第 5 章：更新和保持数据

前面的几章论述了如何使用 ADO 获取数据源中的数据，如何在数据中来回移动，甚至如何编辑数据。当然，如果您的应用程序的目标是允许用户更改数据，您就需要理解如何保存这些更改。可以使用 Save 方法将 Recordset 更改保存到文件，也可以使用 Update 或 UpdateBatch 方法将更改发送回数据源来存储更改。

在前面的几章中，已经更改完 Recordset 多个行中的数据。ADO 支持两个基本概念，这两个概念与数据行的添加、删除和修改有关。

第一个概念是不立即更改 Recordset，而是将更改写入内部“复制缓冲区”。如果您不需要这些更改，复制缓冲区中的更改将被放弃。如果希望保留更改，复制缓冲区中的更改将被应用到 Recordset。

第二个概念是只要声明行的工作完成便立即将更改传播到数据源（即“立即”模式），或者在声明行集合的工作完成之前收集对行集合的所有更改（即“批”模式）。LockType 属性确定何时对基本数据源进行更改。adLockOptimistic 或 adLockPessimistic 指定立即模式，而 adLockBatchOptimistic 则指定批模式。CursorLocation 属性会影响可用的 LockType 设置。例如，如果将 CursorLocation 属性设置为 adUseClient，则不支持 adLockPessimistic 设置。

在立即模式中，每次调用 Update 方法都会将更改传播到数据源。在批模式中，每次调用 Update 或移动当前行的位置时，都会将更改保存到复制缓冲区，但只有 UpdateBatch 方法将更改传播到数据源。


更新数据

更新行为和功能在很大程度上取决于更新模式（锁定类型）、游标类型和游标位置。

在调用 AddNew 方法或在更改现有记录中的任一字段值之后，可用 Update 方法保存对 Recordset 对象的当前记录所做的全部更改。Recordset 对象必须支持更新。

如果 Recordset 对象支持批更新，在调用 UpdateBatch 方法之前，可以把对一个或多个记录所做的多个更改在本地缓存。如果调用 UpdateBatch 方法时正在编辑当前记录或添加新记录，那么在将批更改传送到提供者之前，ADO 将自动调用 Update 方法保存对当前记录所做的所有挂起的更改。

调用 Update 或 UpdateBatch 方法后，当前记录仍然保持为当前记录。


立即模式

当 LockType 属性设置为 adLockOptimistic 或 adLockPessimistic 时立即模式生效。在立即模式中，只要通过调用 Update 方法来完成对行的声明，对记录的更改就会传播到数据源。

调用更新

如果调用 Update 方法前离开了正在添加或编辑的记录，ADO 将自动调用 Update 来保存更改。如果要取消对当前记录所做的任何更改或放弃新添加的记录，必须在定位之前调用 CancelUpdate 方法。

调用 Update 方法后，当前记录仍然保持当前。

CancelUpdate

使用 CancelUpdate 方法可以取消对当前行所做的更改或放弃新添加的行。调用 Update 方法之后，无法取消对当前行或新行所做的更改，除非更改是可以用 RollbackTrans 方法回卷的事务的一部分，或者是批更新的一部分。在批更新的情况下，可以用 CancelUpdate 或 CancelBatch 方法取消 Update。

如果调用 CancelUpdate 方法时在添加新行，调用 AddNew 之前的当前行将成为当前行。

如果尚未更改当前行或添加新行，调用 CancelUpdate 方法将产生错误。


批模式

当 LockType 属性设置为 adLockBatchOptimistic 并且提供者支持批更新时，批模式有效。某些锁定类型设置不可用，这要取决于游标位置。例如，当 CursorLocation 设置为 adUseClient 时，保守式锁定类型不可用。相反，当游标位置在服务器上时，提供者可能不支持批开放式锁定。批更新应当只与键集游标或静态游标配合使用。

UpdateBatch 方法用于将复制缓冲区中所存储的 Recordset 更改发送到服务器，以更新数据源。在下一节中，我们将在批模式中打开 Recordset，然后更改复制缓冲区，再通过调用 UpdateBatch 将更改发送到数据源。


发送更新：UpdateBatch

ADO 2.5

发送更新：UpdateBatch 方法

下面的代码通过将 LockType 属性设置为 adLockBatchOptimistic，将 CursorLocation 设置为 adUseClient 以批模式打开了一个 Recordset。它添加了两个新记录，并更改了一个现有记录中某个字段的值，在保存原始值之后调用了 UpdateBatch 以便将所做更改发送回数据源。

'BeginBatchUpdate
    strSQL = "SELECT ShipperId, CompanyName, Phone FROM Shippers"

    objRs1.CursorLocation = adUseClient
    objRs1.Open strSQL, strConn, adOpenStatic, adLockBatchOptimistic, adCmdText

    ' Change value of Phone field for first record in Recordset, saving value
    ' for later restoration.
    intId = objRs1("ShipperId")
    strPhone = objRs1("Phone")

    objRs1("Phone") = "(111) 555-1111"

    'Add two new records
    For i = 0 To 1
        objRs1.AddNew
        objRs1(1) = "New Shipper #" & CStr((i + 1))
        objRs1(2) = "(nnn) 555-" & i & i & i & i
    Next i

    ' Send the updates
    objRs1.UpdateBatch
'EndBatchUpdate

如果调用 UpdateBatch 方法时正在编辑当前记录或添加新记录，那么在将批更改传送到提供者之前，ADO 将自动调用 Update 方法保存对当前记录所做的所有挂起的更改。


对更新记录进行筛选

在调用 UpdateBatch 之前，通过使用 Recordset 的 Filter 属性，可以只查看那些自从 Recordset 打开或最后一次调用 UpdateBatch 以来已经发生更改的记录。要这样做，请将 Filter 设置为等于 adFilterPendingRecords，以确定将更新多少个记录，如下例所示。

该范例扩展了前面的 UpdateBatch 范例，它在即将调用 UpdateBatch 之前筛选 Recordset，这样，就可以向用户显示哪些记录将发生更改并允许用户取消更新（使用 CancelBatch 方法）。

'BeginFilterAffected
    objRs1.Filter = adFilterPendingRecords
    objRs1.MoveFirst

    strMsg = "The following " & objRs1.RecordCount & " values will " & _
             "be updated. Do you wish to proceed?"
    While Not objRs1.EOF
        strMsg = strMsg & vbCrLf & objRs1(0) & vbTab & objRs1(1) & vbTab & _
                 objRs1(2) & vbCrLf
        objRs1.MoveNext
    Wend

    blnResp = MsgBox(strMsg, vbYesNo, "Proceed with Update?")
    If blnResp = True Then
        objRs1.UpdateBatch
    Else
        objRs1.CancelBatch
    End If
'EndFilterAffected


处理失败的更新

更新最终以错误结束时，如何解决错误将取决于错误的性质和严重性以及应用程序的逻辑。但是，如果数据库已共享给其他用户，则典型的错误是其他人在您修改某个字段之前先修改了该字段。这种类型的错误称为“冲突”。ADO 将检测这种情况并报告错误。

如果存在更新错误，它们将被错误处理例程捕获。通过使用 adFilterConflictingRecords 常量来筛选 Recordset，可以只显示冲突行。在该范例中，错误解决策略只是打印作者的名和姓（au_fname 和 au_lname）。

提醒用户注意更新冲突的代码类似于以下代码：

objRs.Filter = adFilterConflictingRecords
objRs.MoveFirst
Do While Not objRst.EOF
   Debug.Print "Conflict: Name =  "; objRs!au_fname; " "; objRs!au_lname
   objRs.MoveNext
Loop


检测和解决冲突

如果在立即模式中处理 Recordset，则很少出现并发问题。另一方面，如果应用程序使用批模式更新，则在保存由一个正在编辑记录的用户所作的更改之前，编辑同一个记录的另一个用户比较有可能会更改记录。在这种情况下，需要应用程序准确处理冲突。您可能希望第一个人将更新发送给服务器“wins”，或者可能希望通过向最靠近的用户提供两个冲突值作为选择项，让该用户来决定哪个更新应当优先。

无论是哪种情况，都可以使用 ADO 提供的 Field 对象的 UnderlyingValue 和 OriginalValue 属性来处理这些类型的冲突。请将这些属性与 Recordset 的 Resync 方法和 Filter 属性配合使用。

检测错误

在批更新期间 ADO 遇到冲突时，将在 Errors 集合中放入警告。因此，调用 BatchUpdate 之后，一定要立即检查是否有错误，如果找到了错误，则应当假设已遇到冲突并开始进行测试。第一步要将 Recordset 的 Filter 属性设置为等于 adFilterConflictingRecords（在前一章中讨论了 Filter 属性）。该设置将使视图 Recordset 限制为只显示哪些发生冲突的记录。如果这一步之后 RecordCount 属性等于零，就说明错误是由冲突以外的其他原因引起的。

调用 BatchUpdate 时，ADO 和提供者将生成对数据源执行更新的 SQL 语句。请记住，某些数据源对哪些类型的列可以用在 WHERE 子句中存在限制。

下一步，调用 Recordset 的 Resync 方法，并且将 AffectRecords 参数设置为等于 adAffectGroup，将 ResyncValues 参数设置为等于 adResyncUnderlyingValues。Resync 方法将用来自基本数据库中的数据刷新在当前 Recordset 对象中的数据。通过使用 adAffectGroup，可以确保只有使用当前筛选设置的情况下可见的记录（即只有冲突记录）会与数据库重新同步。如果处理的是大型 Recordset，该操作会对性能有较大影响。通过在调用 Resync 时将 ResyncValues 参数设置为 adResyncUnderlyingValues，可以确保 UnderlyingValue 属性将包含数据库中的（冲突）值，并确保 Value 属性仍然是由用户输入的值，还会确保 OriginalValue 属性将持有字段的原始值（即在上一次成功进行 UpdateBatch 调用之前该字段所拥有的值）。然后，可以使用这些值通过编程方式解决冲突，或要求用户选择将要使用的值。

下面的代码范例显示了该技术。在调用 UpdateBatch 之前，该范例通过使用单独的 Recordset 来更改基本表中的值，人为地创建了一个冲突。

'BeginConflicts
    On Error GoTo ErrHandler:

    Dim objRs1 As New ADODB.Recordset
    Dim objRs2 As New ADODB.Recordset
    Dim strSQL As String
    Dim strMsg As String

    strSQL = "SELECT * FROM Shippers WHERE ShipperID = 2"

    'Open Rs and change a value
    objRs1.CursorLocation = adUseClient
    objRs1.Open strSQL, strConn, adOpenStatic, adLockBatchOptimistic, adCmdText
    objRs1("Phone") = "(111) 555-1111"

    'Introduce a conflict at the db...
    objRs2.Open strSQL, strConn, adOpenKeyset, adLockOptimistic, adCmdText
    objRs2("Phone") = "(999) 555-9999"
    objRs2.Update
    objRs2.Close
    Set objRs2 = Nothing

    On Error Resume Next
    objRs1.UpdateBatch

    If objRs1.ActiveConnection.Errors.Count <> 0 Then
        Dim intConflicts As Integer

        intConflicts = 0

        objRs1.Filter = adFilterConflictingRecords

        intConflicts = objRs1.RecordCount

        'Resync so we can see the UnderlyingValue and offer user a choice.
        'This sample only displays all three values and resets to original.
        objRs1.Resync adAffectGroup, adResyncUnderlyingValues

        If intConflicts > 0 Then
            strMsg = "A conflict occurred with updates for " & intConflicts & _
                     " record(s)." & vbCrLf & "The values will be restored" & _
                     " to their original values." & vbCrLf & vbCrLf

            objRs1.MoveFirst
            While Not objRs1.EOF
                strMsg = strMsg & "SHIPPER = " & objRs1("CompanyName") & vbCrLf
                strMsg = strMsg & "Value = " & objRs1("Phone").Value & vbCrLf
                strMsg = strMsg & "UnderlyingValue = " & _
                                   objRs1("Phone").UnderlyingValue & vbCrLf
                strMsg = strMsg & "OriginalValue = " & _
                                   objRs1("Phone").OriginalValue & vbCrLf
                strMsg = strMsg & vbCrLf & "Original value has been restored."

                MsgBox strMsg, vbOKOnly, _
                      "Conflict " & objRs1.AbsolutePosition & _
                      " of " & intConflicts

                objRs1("Phone").Value = objRs1("Phone").OriginalValue
                objRs1.MoveNext
            Wend

            objRs1.UpdateBatch adAffectGroup
        Else
            'Other error occurred. Minimal handling in this example.
             strMsg = "Errors occurred during the update. " & _
                        objRs1.ActiveConnection.Errors(0).Number & " " & _
                        objRs1.ActiveConnection.Errors(0).Description
        End If

        On Error GoTo 0
    End If

    objRs1.MoveFirst

    'Clean up
    objRs1.Close
    Set objRs1 = Nothing
    Exit Sub

ErrHandler:

    If Not objRs1 Is Nothing Then
        If objRs1.State = adStateOpen Then objRs1.Close
        Set objRs1 = Nothing
    End If

    If Not objRs2 Is Nothing Then
        If objRs2.State = adStateOpen Then objRs2.Close
        Set objRs2 = Nothing
    End If

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

'EndConflicts

可以使用当前 Record 的或特定 Field 的 Status 属性来确定已发生的冲突种类。

有关错误处理的更详细信息，请参阅第 6 章：错误处理。


断开和重新连接 Recordset

ADO 最强大的功能之一是它能够打开来自数据源的客户端 Recordset，然后断开 Recordset 与数据源的连接。一旦 Recordset 已断开，即可关闭与数据源的连接，这样可以释放服务器用来维护该连接的资源。用户可以在断开连接的情况下继续查看和编辑 Recordset 中的数据，随后，可以重新连接到数据源，并以批模式发送更新。

若要断开 Recordset，请使用 adUseClient 的游标位置打开该 Recordset，然后将 ActiveConnection 属性设置为 Nothing。（C++ 用户应该将 ActiveConnection 设置为 NULL 以便断开。）

在这一章随后的内容中，将使用断开的 Recordset。我们将假设有这样一个场景：在客户端计算机不连接网络的情况下，需要让一个应用程序能够访问 Recordset 中的数据。利用这个场景，我们将讨论如何保持 Recordset。


更新 JOIN 结果：Unique Table

借助 Unique Table 动态属性，ADO 使您能够严密控制对 Recordset 中的特定基本表所做的修改，但 Recordset 必须是通过在多个基本表上执行 JOIN 操作得到的。有关使用 Unique Table 的详细信息，请参阅《ADO 程序员参考》中有关 Unique Table 和 Update Resynch 动态属性的主题。


事务处理

ADO 提供了下面的方法来控制事务：BeginTrans、CommitTrans 和 RollbackTrans。如果想要以独立单元保存或取消对源数据所做的一系列更改，请对 Connection 对象使用这些方法。例如，要进行转帐，从一个帐户中减去某个数额并将对等数额添加到另一个帐户中。如果任何一个更新失败，都将导致帐户收支不平衡。在打开的事务中进行这些更改可确保只能选择进行全部更改或不做任何更改。

注意 并非所有的提供者都支持事务。验证提供者定义的属性“Transaction DDL”显示在 Connection 对象的 Properties 集合中，该属性表明提供者支持事务。如果提供者不支持事务，调用这些方法之一将返回错误。

在调用 BeginTrans 方法后，提供者将不再立即提交所做的更改，直到调用 CommitTrans 或 RollbackTrans 以结束事务为止。

调用 CommitTrans 方法将保存连接上打开的事务中所做的更改并结束事务。调用 RollbackTrans 方法还原打开事务中所做的更改并结束事务。在无打开的事务时调用任何一种方法都会产生错误。

根据 Connection 对象的 Attributes 属性，调用 CommitTrans 或 RollbackTrans 方法都可以自动启动新事务。如果 Attributes 属性设置为 adXactCommitRetaining，在调用 CommitTrans 后提供者将自动启动新事务。如果 Attributes 属性设置为 adXactAbortRetaining，在调用 RollbackTrans 后提供者将自动启动新事务。

事务隔离级别

用 IsolationLevel 属性可设置 Connection 对象上事务的隔离级别。该设置直到下次调用 BeginTrans 方法时才生效。如果请求的隔离级别不可用，提供者可能返回下一个更高的隔离级别。有关有效值的详细信息，请参阅《ADO 程序员参考》中的 IsolationLevel 属性。

嵌套事务

对于支持嵌套事务的提供者，在打开的事务中调用 BeginTrans 方法将启动新的嵌套事务。返回值将指示嵌套层次：返回值为“1”指示打开了顶层事务（即此事务未嵌套在其他事务中），返回值为“2”指示打开了第二层事务（嵌套在顶层事务中的事务），依此类推。调用 CommitTrans 或 RollbackTrans 只影响最新打开的事务；在处理任何更高层事务之前必须关闭或回卷当前事务。


持久保留数据

便携计算（例如，使用笔记本计算机）已经对在连接和断开状态下均可运行的应用程序产生了需求。ADO 已添加了对该功能的支持，方法是让开发人员能够将客户端游标 Recordset 保存到磁盘并随后重新加载。

在几个情形下可以使用该类型的功能，这些情形包括：

  • 旅行： 在旅途中取得应用程序时，一定要提供允许用户进行更改和添加新记录并且可以在随后重新连接数据库时提交更改和新记录的功能。
  • 很少更新的查找对象： 通常在应用程序中，将表作为查找对象（例如，国税表）。它们很少更新并且是只读的。所以，应用程序不需要每次启动时从服务器重新读取该数据，而只需从本地持久保留的 Recordset 中加载该数据。

在 ADO 中，若要保存和加载 Recordsets，请对 ADO Recordset 对象使用 Recordset.Save 和 Recordset.Open(,,,,adCmdFile) 方法。

可以使用 Recordset Save 方法将 ADO Recordset 持久保留到文件磁盘中。（还可以将 Recordset 保存到 ADO Stream 对象中。随后将在指南中讨论 Stream 对象。）之后，准备使用 Recordset 时，可以使用 Open 方法将它重新打开。默认情况下，ADO 将 Recordset 保存到专有的 Microsoft Advanced Data TableGram (ADTG) 格式中。该二进制格式是使用 adPersistADTG PersistFormatEnum 值指定的。另一种选择是，使用 adPersistXML 将 Recordset 另存为 XML。有关将 Recordsets 另存为 XML 的详细信息，请参阅以 XML 格式持久保留记录。

Save 方法的语法如下：

recordset.Save Destination, PersistFormat

第一次保存 Recordset 时，可以指定 Destination，也可以不指定。如果省略 Destination，将创建一个新文件，其名称被设置为 Recordset 的 Source 属性的值。

第一次保存之后再次调用 Save 时，请省略 Destination，否则将产生运行时错误。如果用新的 Destination 再次调用 Save，Recordset 将保存到新的目标中。但是，新的目标和原始目标都将是打开的。

Save 不关闭 Recordset 或 Destination，因此您可以继续使用 Recordset 并保存最近所作的更改。关闭 Recordset 前，Destination 将保持打开，在此过程中其他应用程序可以读取 Destination，但不能写入。

为安全起见，Save 方法只允许使用由 Microsoft Internet Explorer 执行的脚本中的低和自定义级别安全设置。有关安全问题的详细说明，请参阅 Microsoft Data Access Technical Articles 中 ActiveX Data Objects (ADO) Technical Articles 下的 ADO and RDS Security Issues in Microsoft Internet Explorer。

如果在异步 Recordset 提取、执行或更新操作时调用 Save 方法，那么，将一直等到该异步操作完成后才会执行 Save。

从 Recordset 的第一行开始保存记录。当完成 Save 方法时，当前行位置将移动到 Recordset 的第一行。

要得到最佳结果，请用 Save 将 CursorLocation 属性设置为 adUseClient。如果提供者不支持保存 Recordset 对象所必需的所有功能，Cursor Service 将提供该功能。

在 CursorLocation 属性设置为 adUseServer 的情况下持久保留 Recordset 时，Recordset 的更新能力将受到限制。通常，只允许针对一个表进行的更新、插入和删除（这取决于提供者功能）。Resync 方法在此配置下也不可用。

由于 Destination 参数可以接受支持 OLE DB IStream 接口的所有对象，因此可以将 Recordset 直接保存到 ASP Response 对象中。

在以下范例中，使用了 Save 和 Open 方法来持久保留 Recordset 并在随后重新打开它：

'BeginPersist
    conn.ConnectionString = _
    "Provider='SQLOLEDB';Data Source='MySqlServer';" _
        & "Integrated Security='SSPI';Initial Catalog='pubs'"
    conn.Open

    conn.Execute "create table testtable (dbkey int " & _
        "primary key, field1 char(10))"
    conn.Execute "insert into testtable values (1, 'string1')"

    Set rst.ActiveConnection = conn
    rst.CursorLocation = adUseClient

    rst.Open "select * from testtable", conn, adOpenStatic, _
       adLockBatchOptimistic

    'Change the row on the client
    rst!field1 = "NewValue"

    'Save to a file--the .dat extension is an example; choose
    'your own extension. The changes will be saved in the file
    'as well as the original data.
    MyFile = Dir("c:\temp\temptbl.dat")
    If MyFile <> "" Then
        Kill "c:\temp\temptbl.dat"
    End If

    rst.Save "c:\temp\temptbl.dat", adPersistADTG
    rst.Close
    Set rst = Nothing

    'Now reload the data from the file
    Set rst = New ADODB.Recordset
    rst.Open "c:\temp\temptbl.dat", , adOpenStatic, _
       adLockBatchOptimistic, adCmdFile

    Debug.Print "After Loading the file from disk"
    Debug.Print "   Current Edited Value: " & rst!field1.Value
    Debug.Print "   Value Before Editing: " & rst!field1.OriginalValue

    'Note that you can reconnect to a connection and
    'submit the changes to the data source
    Set rst.ActiveConnection = conn
    rst.UpdateBatch
'EndPersist


有关 Recordset 持久性的详细信息

ADO Recordset 对象支持使用 Recordset 对象的 Save 方法将其内容保存在文件中。持久存储的文件可以存在于本地驱动器和网络服务器上，或者以 URL 形式存在于网站上。随后，可以用 Recordset 对象的 Open 方法或 Connection 对象的 Execute 方法恢复该文件。

此外，GetString 方法还将 Recordset 对象转换为一种以指定的字符分隔行和列的格式。

要使 Recordset 具有持久性，应先将其转换为可在文件中保存的格式。存储 Recordset 对象的格式既可以是专用的 Advanced Data TableGram (ADTG) 格式，也可以是开放的可扩展标记语言 (XML) 格式。ADTG 范例如下所述。有关 XML 持久性的详细信息，请参阅以 XML 格式持久保留记录。

将所有挂起更改保存到持久文件。这样，使用户可以发布返回 Recordset 对象的查询、编辑该 Recordset、保存该记录集和挂起更改、以后恢复该 Recordset、然后再用所保存的挂起更改更新数据源。

有关持久存储 Stream 对象的详细信息，请参阅第 10 章中的流和持久性。

有关 Recordset 持久性的范例，请参阅 XML Recordset 持久性方案。

范例

保存 Recordset：

Dim rs as New ADODB.Recordset
rs.Save "c:\yourFile.adtg", adPersistADTG

使用 Recordset.Open 打开持久文件：

Dim rs as New ADODB.Recordset
rs.Open "c:\yourFile.adtg", "Provider='MSPersist'",,,adCmdFile

此外，如果 Recordset 不包含活动的连接，那么您可以接受所有默认值并编写如下简单代码：

Dim rs as New ADODB.Recordset
rs.Open "c:\yourFile.adtg"

使用 Connection.Execute 打开持久文件：

Dim conn as New ADODB.Connection
Dim rs as ADODB.Recordset
conn.Open "Provider='MSPersist'"
Set rs = conn.execute("c:\yourFile.adtg")

使用 RDS.DataControl 打开持久文件：

在本范例中，未设置 Server 属性。

Dim dc as New RDS.DataControl
dc.Connection = "Provider='MSPersist'"
dc.SQL = "c:\yourFile.adtg"
dc.Refresh

请参阅

GetString 方法 | Microsoft OLE DB Persistence Provider | Recordset 对象 | 流和持久性


持久保留筛选和分级的 Recordsets

如果 Filter 属性在对 Recordset 生效，则只会保存在筛选后可访问的行。如果 Recordset 是分级的，将保存当前的子 Recordset 及其孩子，包括父 Recordset。如果调用子 Recordset 的 Save 方法，那么该子对象及其所有子对象都将被保存，而父对象则不保存。有关分级 Recordsets 的详细信息，请参阅第 9 章：数据构形。

注意 以 XML 格式保存分级 Recordsets （数据构形）时，会受到某些限制。详细信息，请参阅 XML 中的分级 Recordsets。


以 XML 格式持久保留记录

像 ADTG 格式一样，以 XML 格式进行的 Recordset 持久保留是通过 Microsoft OLE DB 持久保留提供者实现的。该提供者将从保存的 XML 文件或流式数据（其中包含由 ADO 生成的架构信息）生成仅向前、只读的行集。同样，它可以取得 ADO Recordset、生成 XML 并将它保存到文件或任何实现 COM IStream 接口的对象中（实际上，文件只是支持 IStream 的对象的另一个范例）。对于 2.5 版和更高版本，ADO 依靠 Microsoft XML 语法分析程序（MSXML）将 XML 加载到 Recordset 中；因此，msxml.dll 是必需的。对于 2.5 版本，MSXML 与 Internet Explorer 5 一同交付。对于 2.6 版，MSXML 与 SQL Server 2000 一同交付。

注意 将分级 Recordsets（数据构形）保存到 XML 格式时会受到某些限制。如果分级 Recordset 包含挂起的更新，则无法将它保存到 XML，并且无法保存参数化的分级 Recordset。详细信息，请参阅 XML 中的分级 Recordsets。

将数据持久保留到 XML 并通过 ADO 再次加载它的最容易的方式是分别使用 Save 和 Open 方法。以下 ADO 代码范例演示了如何将 Titles 表中的数据保存到名为 titles.sav 的文件中。

Dim rs as new Recordset
Dim rs2 as new Recordset
Dim c as new Connection
Dim s as new Stream

' Query the Titles table.
c.Open "provider='sqloledb';data source='mydb';initial catalog='pubs';Integrated Security='SSPI'"
rs.cursorlocation = adUseClient
rs.Open "select * from titles", c, adOpenStatic

' Save to the file in the XML format. Note that if you don't specify
' adPersistXML, a binary format (ADTG) will be used by default.
rs.Save "titles.sav", adPersistXML

' Save the Recordset into the ADO Stream object.
rs.save s, adPersistXML
rs.Close
c.Close

set rs = nothing

' Reopen the file.
rs.Open "titles.sav",,,,adCmdFile
' Open the Stream back into a Recordset.
rs2.open s

ADO 始终会持久保留整个 Recordset 对象。如果想只持久保留 Recordset 对象的行的子集，请使用 Filter 方法缩小行的范围，或更改选择子句。但是，必须使用客户端游标 (CursorLocation = adUseClient) 打开 Recordset 对象，才能使用 Filter 方法保存行的子集。例如，若要检索以字母“b”开头的标题，可以应用筛选以打开 Recordset 对象：

rs.Filter "title_id like 'B*'"
rs.Save "btitles.sav", adPersistXML

ADO 始终使用客户端游标引擎行集来在由持久保留提供者所生成的仅向前数据的顶部产生可滚动的、可以用书签标记的 Recordset 对象。


XML 持久性格式

ADO 为它持久保留的 XML 流使用 UTF-8 编码。

ADO XML 格式分为架构节和数据节两节：架构节在前，数据节在后。以下是一个来自 Northwind 数据库中 Shippers 表的 XML 文件范例。XML 的各个部分都在此范例中有所涉及。

<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
xmlns:rs="urn:schemas-microsoft-com:rowset"
xmlns:z="#RowsetSchema">
  <s:Schema id="RowsetSchema">
    <s:ElementType name="row" content="eltOnly" rs:updatable="true">
      <s:AttributeType name="ShipperID" rs:number="1"
        rs:basetable="shippers" rs:basecolumn="ShipperID"
        rs:keycolumn="true">
        <s:datatype dt:type="int" dt:maxLength="4" rs:precision="10"
          rs:fixedlength="true" rs:maybenull="false"/>
      </s:AttributeType>
      <s:AttributeType name="CompanyName" rs:number="2"
        rs:nullable="true" rs:write="true" rs:basetable="shippers"
        rs:basecolumn="CompanyName">
        <s:datatype dt:type="string" dt:maxLength="40" />
      </s:AttributeType>
      <s:AttributeType name="Phone" rs:number="3" rs:nullable="true"
        rs:write="true" rs:basetable="shippers"
        rs:basecolumn="Phone">
        <s:datatype dt:type="string" dt:maxLength="24"/>
      </s:AttributeType>
      <s:extends type="rs:rowbase"/>
    </s:ElementType>
  </s:Schema>

  <rs:data>
    <z:row ShipperID="1" CompanyName="Speedy Express"
      Phone="(503) 555-9831"/>
    <z:row ShipperID="2" CompanyName="United Package"
      Phone="(503) 555-3199"/>
    <z:row ShipperID="3" CompanyName="Federal Shipping"
      Phone="(503) 555-9931"/>
  </rs:data>
</xml>

上面的模式显示了名称空间的声明、架构节和数据节。架构节包含对行的定义：ShipperID、CompanyName 和 Phone 。

架构定义遵循 XML-Data 规范而且能够完全得到验证（但验证不会在 Internet Explorer 5 下进行）。可在下面的路径下查看此规范：http://www.w3.org/TR/1998/NOTE-XML-data/。目前，对于 Recordset 的持久性，XML-Data 是唯一受到支持的架构格式。

数据节中有三行包含有关发货人的信息。对于空的行集合，数据节会为空，但 <rs:data> 标记必须存在。如果没有数据，可将此标记简写为 <rs:data/>。任何以“rs”为前缀的标记指示它存在于由 urn:schemas-microsoft-com:rowset 定义的名称空间中。此架构的全部定义均在本文档的附录中详细说明。


名称空间

在 ADO 中，XML 持久保留格式使用了以下四个名称空间。

前缀 | 说明
s | 是指“XML 数据”名称空间，其中包含用于定义当前 Recordset 的架构的元素和属性。
dt | 是指数据类型定义规范。
rs | 是指名称空间，其中包含 ADO Recordset 属性和属性特有的元素和属性。
z | 是指当前行集的架构。

客户端不应当将其自己的标记添加到由规范所定义的这些名称空间中。例如，客户端不应当将名称空间定义为“urn:schemas-microsoft-com:rowset”，然后写出诸如“rs:MyOwnTag”这样的内容。若要了解关于名称空间的更多信息，请参阅 http://www.w3.org/TR/REC-xml-names/。

要点 架构标记的 ID 必须是“RowsetSchema”，并且用来引用当前行集的架构的名称空间必须指向“#RowsetSchema”。

注意：名称空间的前缀（即冒号右侧和等号左侧的部分）是任意。

xmlns:rs="urn:schemas-microsoft-com:rowset"

只要在整个 XML 文档中一致地使用该名称，用户就可以将该名称定义为任何名称。ADO 总是写出“s”、“rs”、“dt”和“z”，但这些前缀名称不会硬编码到加载组件中。


架构节

架构节是必需的。正如前面的范例所示，ADO 写出了关于每列的详细的元数据，以尽可能多地保留数据值的语义以备数据的更新。但是，ADO 只需要各列的名称以及这些列所属的行集合，即可将元数据加载到 XML 中。以下是一个最小架构的范例：

<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
    xmlns:rs="urn:schemas-microsoft-com:rowset"
    xmlns:z="#RowsetSchema">
  <s:Schema id="RowsetSchema">
    <s:ElementType name="row" content="eltOnly">
      <s:AttributeType name="ShipperID"/>
      <s:AttributeType name="CompanyName"/>
      <s:AttributeType name="Phone"/>
      <s:Extends type="rs:rowbase"/>
    </s:ElementType>
  </s:Schema>
  <rs:data>
...
  </rs:data>
</xml>

在上面的情况下，ADO 将把数据视为变长字符串，因为这个架构中不包括类型信息。

为列名创建别名

rs:name 属性允许为列名创建别名，这样，友好的名称就会出现在行集合所显示的列信息中，而且在数据节可能会使用较短的名称。例如，上面的架构可以修改为将 ShipperID 映射到 s1，将 CompanyName 映射到 s2，并将 Phone 映射到 s3，如下所示：

<s:Schema id="RowsetSchema">
<s:ElementType name="row" content="eltOnly" rs:updatable="true">
<s:AttributeType name="s1" rs:name="ShipperID" rs:number="1" ...>
...
</s:AttributeType>
<s:AttributeType name="s2" rs:name="CompanyName" rs:number="2" ...>
...
</s:AttributeType>
<s:AttributeType name="s3" rs:name="Phone" rs:number="3" ...>
...
</s:AttributeType>
...
</s:ElementType>
</s:Schema>

然后，在数据节中，这一行就会使用 name 属性（不是 rs:name）引用该列：

"<row s1="1" s2="Speedy Express" s3="(503) 555-9831"/>

只要列名不是 XML 中合法的属性或标记名，就需要为其创建别名。例如，“LastName”必须有一个别名，因为包含空格的名称是非法属性。XML 分析程序不会正确处理下面的代码行，因此必须再创建一个不包含空格的名称作为别名：

<row last name="Jones"/>

不管为 name 属性使用的是什么样的值，都必须在由 XML 文档的架构和数据节引用该列的所有地方保持使用的一致性。下例显示了对 s1 的一致性使用：

<s:Schema id="RowsetSchema">
  <s:ElementType name="row" content="eltOnly">
    <s:attribute type="s1"/>
    <s:attribute type="CompanyName"/>
    <s:attribute type="s3"/>
    <s:extends type="rs:rowbase"/>
  </s:ElementType>
  <s:AttributeType name="s1" rs:name="ShipperID" rs:number="1"
    rs:maydefer="true" rs:writeunknown="true">
    <s:datatype dt:type="i4" dt:maxLength="4" rs:precision="10"
      rs:fixedlength="true" rs:maybenull="true"/>
  </s:AttributeType>
</s:Schema>
<rs:data>
  <z:row s1="1" CompanyName="Speedy Express" s3="(503) 555-9831"/>
</rs:data>

同样，由于没有为上面的 CompanyName 定义别名，CompanyName 也必须在文档中保持使用的一致性。

数据类型

可使用 dt:type 属性将数据类型应用到列。有关许可的 XML 类型的权威性指南，请参阅 http://www.w3.org/TR/1998/NOTE-XML-data-0105/#Datatypes。可以两种方式指定数据类型：即可以在列定义上直接指定 dt:type 属性，也可以把 s:datatype 构造作为列定义的嵌套元素来使用。例如：

<s:AttributeType name="Phone" >
  <s:datatype dt:type="string"/>
</s:AttributeType>

等价于

<s:AttributeType name="Phone" dt:type="string"/>

如果在行定义中完全省略了 dt:type 属性，那么默认情况下，该列的类型将为变长字符串。

如果除类型名称以外，还有其他类型的信息（例如，dt:maxLength），那么使用 s:datatype 子元素可读性更好。但这只是一个约定，并非硬性要求。

下面的范例进一步显示了将类型信息包含到架构中的方法：

<!-- 1. String with no max length -->
<s:AttributeType name="title_id"/>
<!—or -->
<s:AttributeType name="title_id" dt:type="string"/>

<!—- 2. Fixed length string with max length of 6 -->
<s:AttributeType name="title_id">
    <s:datatype dt:type="string" dt:maxLength="6" rs:fixedlength="true" />
</s:AttributeType>

<!—- 3. Variable length string with max length of 6 -->
<s:AttributeType name="title_id">
    <s:datatype dt:type="string" dt:maxLength="6" />
</s:AttributeType>

<!—- 4. Integer -->
<s:AttributeType name="title_id" dt:type="int"/>

在第二个范例中巧妙使用了 rs:fixedlength 属性。rs:fixedlength 属性被设置为 true 的列意味着数据的长度必须等于架构中所定义的长度。在这种情况下，“123456” 是 title_id 的一个合法值，"123 ." 也是一个合法值。但是，“123”是无效的，因为它的长度是 3，而不是 6。请参阅“OLE DB Programmer's Guide”，了解 fixedlength 属性的更全面说明。

处理 Null 值

Null 值由 rs:maybenull 属性处理。如果此属性设置为 true，那么该列的内容可以包含 Null 值。而且，如果在数据行中未发现该列，从行集合读取数据的用户就会从 IRowset::GetData() 得到 Null 状态。请考虑下列 Shippers 表的列定义：

<s:AttributeType name="ShipperID">
  <s:datatype dt:type="int" dt:maxLength="4"/>
</s:AttributeType>
<s:AttributeType name="CompanyName">
  <s:datatype dt:type="string" dt:maxLength="40" rs:maybenull="true"/>
</s:AttributeType>

该定义允许 CompanyName 为 Null ，但 ShipperID 不能包含 Null 值。如果数据节包含下面的行，则保持提供者将 CompanyName 列数据的状态设置为 OLE DB 状态常量 DBSTATUS_S_ISNULL：

<z:row ShipperID="1"/>

如果该行全部为空（如下所示），则保持提供者将对 ShipperID 返回 DBSTATUS_E_UNAVAILABLE 的 OLE DB 状态，对 CompanyName 返回 DBSTATUS_S_ISNULL。

<z:row/>

请注意零长度字符串与 Null 是不相同的。

<z:row ShipperID="1" CompanyName=""/>

对于前面的一行，保持提供者将针对这两列返回 DBSTATUS_S_OK 的 OLE DB 状态。在这种情况下，CompanyName 只是 ""（一个零长度字符串）。

有关在针对 OLE DB 的 XML 文档架构中可使用的 OLE DB 构造，请参阅“urn:schemas-microsoft-com:rowset”的定义以及“OLE DB Programmer's Guide”。


数据节

数据节用于定义行集的数据以及任何挂起的更新、插入或删除。数据节可能包含零个或多个行。数据节可能只包含来自一个行集的数据，并且行集中的行是由架构定义的。而且，前面已经提到，不含任何数据的列是可以忽略的。如果在数据节中使用了一个属性或子元素，并且架构节中没有定义该构造，就将安静地忽略这个属性或子元素。

String

在文本数据中的保留 XML 字符必须替换为合适的字符实体。例如，在公司名称“Joe's Garage”中，单引号字符必须替换为实体。实际的行类似如下：

<z:row CompanyName="Joe&apos;s Garage"/>

后面这些字符在 XML 中是保留字符，必须替换为字符实体：{',",&,<,>}。

Binary

二进制数据采用 bin.hex 编码（即一个字节映射到两个字符，每四个位对应一个字符）。

DateTime

变体 VT_DATE 格式不受 XML-Data 数据类型的直接支持。对于同时包含数据和时间的日期来说，正确的格式是 yyyy-mm-ddThh:mm:ss。

有关由 XML 指定的日期格式的详细信息，请参考 http://www.w3.org/TR/1998/NOTE-XML-data-0105/#Datatypes。

当 XML-Data 规范定义了两个等价的数据类型时（例如，i4 == int），ADO 将写出友好名称，但同时读入两个数据类型。

管理挂起更改

Recordset 可以在立即或批更新模式中打开。使用客户端游标在批更新模式中打开时，对 Recordset 所作的所有更改都将处于挂起状态，直到调用了 UpdateBatch 方法。保存 Recordset 时，挂起的更改还会被保持下来。在 XML 中，使用在 urn:schemas-microsoft-com:rowset 中定义的“update”元素来表示它们。此外，如果行集可以更新，那么，可更新的属性在行的定义中必须设置为 True。例如，若要定义 Shippers 表包含挂起的更改，则行的定义应当类似于下面的范例：

<s:ElementType name="row" content="eltOnly" updatable="true">
  <s:attribute type="ShipperID"/>
  <s:attribute type="CompanyName"/>
  <s:attribute type="Phone"/>
  <s:extends type="rs:rowbase"/>
</s:ElementType>

这将通知保持提供者整理数据，以便 ADO 可以构造可更新的 Recordset 对象。

以下范例数据显示插入、更改和删除在保持文件中的外观：

<rs:data>
  <z:row ShipperID="2" CompanyName="United Package"
    Phone="(503) 555-3199"/>
<rs:update>
  <rs:original>
    <z:row ShipperID="3" CompanyName="Federal Shipping"
      Phone="(503) 555-9931"/>
  </rs:original>
  <z:row Phone="(503) 552-7134"/>
</rs:update>
<rs:insert>
  <z:row ShipperID="12" CompanyName="Lightning Shipping"
    Phone="(505) 111-2222"/>
  <z:row ShipperID="13" CompanyName="Thunder Overnight"
    Phone="(505) 111-2222"/>
  <z:row ShipperID="14" CompanyName="Blue Angel Air Delivery"
    Phone="(505) 111-2222"/>
</rs:insert>
<rs:delete>
  <z:row ShipperID="1" CompanyName="Speedy Express" Phone="(503) 555-9831"/>
</rs:delete>
</rs:data>

更新总是包含整个原始行数据，其后为更改后的行数据。更改后的行可能包含所有列，或者只包含那些已实际更改的列。在前面的范例中，Shipper 2 的行没有更改，只有 Phone 列有 Shipper 3 的更改后的值，因此 Phone 列是唯一包括在更改行中的列。Shippers 12、13 和 14 的插入行作为一批放在一起，并位于一个 rs:insert 标记的下面。注意，被删除的行也可能分在同一批内，尽管上面没有显示这一点。


XML 中的分级 Recordsets

ADO 允许将分级的 Recordset 对象持久保留在 XML 中。使用分级的 Recordset 对象，父 Recordset 中的字段值是另一个 Recordset。这样的字段在 XML 流中表示为子元素而不是属性。以下范例演示了该事例：

Rs.Open "SHAPE {select stor_id, stor_name, state from stores} APPEND ({select stor_id, ord_num, ord_date, qty from sales} AS rsSales RELATE stor_id TO stor_id)", "Provider=MSDataShape;DSN=pubs;UID=MyUserId;PWD=MyPassword;"

下面是被持久保留的 Recordset 的 XML 格式：

<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"     xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"     xmlns:rs="urn:schemas-microsoft-com:rowset"
    xmlns:z="#RowsetSchema">
  <s:Schema id="RowsetSchema">
    <s:ElementType name="row" content="eltOnly" rs:updatable="true">
      <s:AttributeType name="stor_id" rs:number="1"
        rs:writeunknown="true">
        <s:datatype dt:type="string" dt:maxLength="4"
          rs:fixedlength="true" rs:maybenull="false"/>
      </s:AttributeType>
      <s:AttributeType name="stor_name" rs:number="2" rs:nullable="true"
        rs:writeunknown="true">
          <s:datatype dt:type="string" dt:maxLength="40"/>
      </s:AttributeType>
      <s:AttributeType name="state" rs:number="3" rs:nullable="true"
        rs:writeunknown="true">
        <s:datatype dt:type="string" dt:maxLength="2"
          rs:fixedlength="true"/>
      </s:AttributeType>
      <s:ElementType name="rsSales" content="eltOnly"
        rs:updatable="true" rs:relation="010000000100000000000000">
        <s:AttributeType name="stor_id" rs:number="1"
          rs:writeunknown="true">
          <s:datatype dt:type="string" dt:maxLength="4"
            rs:fixedlength="true" rs:maybenull="false"/>
        </s:AttributeType>
        <s:AttributeType name="ord_num" rs:number="2"
          rs:writeunknown="true">
          <s:datatype dt:type="string" dt:maxLength="20"
            rs:maybenull="false"/>
        </s:AttributeType>
        <s:AttributeType name="ord_date" rs:number="3"
          rs:writeunknown="true">
            <s:datatype dt:type="dateTime" dt:maxLength="16"
              rs:scale="3" rs:precision="23" rs:fixedlength="true"
              rs:maybenull="false"/>
        </s:AttributeType>
        <s:AttributeType name="qty" rs:number="4" rs:writeunknown="true">
          <s:datatype dt:type="i2" dt:maxLength="2" rs:precision="5"
            rs:fixedlength="true" rs:maybenull="false"/>
        </s:AttributeType>
        <s:extends type="rs:rowbase"/>
      </s:ElementType>
      <s:extends type="rs:rowbase"/>
    </s:ElementType>
  </s:Schema>
  <rs:data>
    <z:row stor_id="6380" stor_name="Eric the Read Books" state="WA">
      <rsSales stor_id="6380" ord_num="6871"
        ord_date="1994-09-14T00:00:00" qty="5"/>
      <rsSales stor_id="6380" ord_num="722a"
        ord_date="1994-09-13T00:00:00" qty="3"/>
    </z:row>
    <z:row stor_id="7066" stor_name="Barnum's" state="CA">
      <rsSales stor_id="7066" ord_num="A2976"
        ord_date="1993-05-24T00:00:00" qty="50"/>
      <rsSales stor_id="7066" ord_num="QA7442.3"
        ord_date="1994-09-13T00:00:00" qty="75"/>
    </z:row>
    <z:row stor_id="7067" stor_name="News & Brews" state="CA">
      <rsSales stor_id="7067" ord_num="D4482"
        ord_date="1994-09-14T00:00:00" qty="10"/>
      <rsSales stor_id="7067" ord_num="P2121"
        ord_date="1992-06-15T00:00:00" qty="40"/>
      <rsSales stor_id="7067" ord_num="P2121"
        ord_date="1992-06-15T00:00:00" qty="20"/>
      <rsSales stor_id="7067" ord_num="P2121"
        ord_date="1992-06-15T00:00:00" qty="20"/>
    </z:row>
...
  </rs:data>
</xml>

当 Recordset 以该方式进行持久保留时，在父 Recordset 对象中的列的准确顺序并不明显。父对象中的任何字段可能包含子 Recordset。Persistence Provider 首先将所有标量列作为属性进行持久保留，然后将所有子 Recordset“列”作为父行的子元素进行持久保留。字段在父 Recordset 中的序号位置可以通过查看 Recordset 的架构定义来获得。每个字段都有 OLE DB 属性 rs:number，在包含该字段序号数字的 Recordset 架构名称空间中定义了该属性。

在子 Recordset 中的所有字段的名称是以包含该子对象的父 Recordset 中的字段的名称串联而成的。这样可以确保一旦父和子 Recordsets 都包含从两个不同表获得的、但名称很特殊的字段时不会发生名称冲突。

将分级的 Recordsets 保存到 XML 中时，应当知道以下 ADO 限制：

  • 带有挂起更新的分级 Recordset 无法持久保留到 XML 中。
  • 无法持久保留以参数化构形命令创建的分级 Recordset（以 XML 或 ADTG 格式）。
  • 目前，ADO 将父和子 Recordsets 之间的关系另存为二进制大型对象 (BLOB)。在行集架构名称空间中还没有定义用于描述该关系的 XML 标记。
  • 保存分级 Recordset 时，所有子 Recordsets 都会和它一起保存。如果当前 Recordset 是另一个 Recordset 的子对象，则不会保存它的父对象。构成当前 Recordset 的子树的所有子 Recordsets 都将被保存。

从其 XML 持久保留格式重新打开分级 Recordset 时，必须知道以下限制：

  • 如果子记录所包含的记录没有相应的父记录，则这些行不会写入分级 Recordset 的 XML 表现形式中。因而，从其持久保留位置重新打开 Recordset 时，这些行将丢失。
  • 如果子记录引用了多个父记录，那么，重新打开 Recordset 时，子 Recordset 可能包含重复的记录。但是，只有当用户直接使用基本子行集时，这些重复的记录才是可见的。如果将子集用于定位子 Recordset（这是在 ADO 中执行定位操作的唯一方法），那么这些重复的记录就不可见。


XML 中的 Recordset 动态属性

下面的 Recordset 提供者特有的属性（来自客户端游标引擎）当前被持久保留到 XML 格式中：

  • Update Resync
  • Unique Table
  • Unique Schema
  • Unique Catalog
  • Resync Command
  • IRowsetChange
  • 24IRowsetUpdate
  • CommandTimeout
  • BatchSize
  • UpdateCriteria
  • Reshape Name
  • AutoRecalc

这些属性将作为正在持久保留的 Recordset 的元素定义的属性而保存在架构部分中。这些属性应当在行集架构名称空间中进行定义，并且必须有前缀“rs:”。


XSLT 转换

XSLT 可应用于已生成的 XML，把它转换为另一种格式。了解 ADO 中的 XML 格式有助于开发 XSLT 模板，用来将 XML 转换为对用户更加友好的形式。

例如，您知道 Recordset 的每一行都被保存为 rs:data 元素中的 z:row 元素。同样，Recordset 的每个字段也被保存为该元素的属性值对。

下面的 XSLT 脚本可用于在上一节所示的 XML 文件，目的是把此文件转换为要在浏览器中显示的 HTML 表：

<?xml version="1.0" encoding="ISO-8859-1"?>
<html xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<body STYLE="font-family:Arial, helvetica, sans-serif; font-size:12pt; background-color:white">
<table border="1" style="table-layout:fixed" width="600">
  <col width="200"></col>
  <tr bgcolor="teal">
    <th><font color="white">CustomerId</font></th>
    <th><font color="white">CompanyName</font></th>
    <th><font color="white">ContactName</font></th>
  </tr>
<xsl:for-each select="xml/rs:data/z:row">
  <tr bgcolor="navy">
    <td><font color="white"><xsl:value-of select="@CustomerID"/></font></td>
    <td><font color="white"><xsl:value-of select="@CompanyName"/></font></td>
    <td><font color="white"><xsl:value-of select="@ContactName"/></font></td>
  </tr>
</xsl:for-each>
</table>
</body>
</html>

XSLT 将由 ADO 的 Save 方法生成的 XML 流转换为一个 HTML 表，该表显示 Recordset 的每个字段，每个字段带有一个表头。表头和表行还被指定了不同的字体和颜色。


保存到 XML DOM 对象

可以用 XML 格式将 Recordset 保存到 MSXML DOM 对象的实例中，如下面的 Visual Basic 代码所示：

Dim xDOM As New MSXML.DOMDocument
Dim rsXML As New ADODB.Recordset
Dim sSQL As String, sConn As String

sSQL = "SELECT customerid, companyname, contactname FROM customers"
sConn="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Program Files" & _
        "\Common Files\System\msadc\samples\NWind.mdb"
rsXML.Open sSQL, sConn
rsXML.Save xDOM, adPersistADO   'Save Recordset directly into a DOM tree.
...


XML 安全性考虑

ADO 在 Recordset 对象上的 Save 和 Open 方法把看作是在 Internet Explorer 运行的不安全操作。因此，如果这些方法被用于在由浏览器托管的应用程序或控件中运行的脚本代码中，那么浏览器的安全性配置就会对其行为产生影响。

在默认情况下，Internet Explorer 5 在 Internet 区域提供对这类操作的安全性限制。在这样的配置下，Recordset 根本无法访问客户端的本地文件系统，也不能访问提供该页面的服务器域以外的任何数据源。需要特别指出的是，当在浏览器主机内部运行时，Recordset 只能保存回提供该页面的服务器上的某个文件。同样，只能从提供该页面的服务器上的文件加载 Recordset 将其打开。

有关 Internet Explorer 安全性的详细信息，请参阅技术文章“ADO and RDS Security Issues in Microsoft Internet Explorer”。


XML Recordset 持久性方案

在此方案中将创建 Active Server Pages (ASP) 应用程序，该程序将 Recordset 对象的内容直接保存到 ASP Response 对象中。

注意 此方案需要用户的服务器安装有 Internet Information Server 5.0 (IIS) 或更新版本。

使用 RDS.DataControl 在 Internet Explorer 中显示返回的 Recordset。

创建此方案需要执行下列步骤：

  1. 安装应用程序。
  2. 获取数据。
  3. 发送数据。
  4. 接收和显示数据。

下一步 步骤 1：安装应用程序

请参阅

Save 方法


步骤 1：安装应用程序

创建具有脚本权限的名为“XMLPersist”的 IIS 虚拟目录。在该虚拟目录指向的文件夹中 创建两个新文本文件，一个名为“XMLResponse.asp”，另一个名为“Default.htm”。

下一步 步骤 2：获取数据


步骤 2：获取数据

在此步骤中用户将编写代码来打开 ADO Recordset 并准备将其发送到客户端。用文本编辑器（如 Windows 记事本）打开 XMLResponse.asp 文件并插入下列代码。

<%@ language="VBScript" %>

<!-- #include file='adovbs.inc' -->

<%
  Dim strSQL, strCon
  Dim adoRec
  Dim adoCon
  Dim xmlDoc

  ' You will need to change "slqServer" below to the name of the SQL
  ' server machine to which you want to connect.
  strCon = "Provider=sqloledb;Data Source=sqlServer;Initial Catalog=Pubs;Integrated Security=SSPI;"
  Set adoCon = server.createObject("ADODB.Connection")
  adoCon.Open strCon

  strSQL = "SELECT Title, Price FROM Titles ORDER BY Price"
  Set adoRec = Server.CreateObject("ADODB.Recordset")
  adoRec.Open strSQL, adoCon, adOpenStatic, adLockOptimistic, adCmdText

确保将 strCon 中的 Data Source 参数值更改为用户的 Microsoft SQL Server 计算机的名称。

使文件保持打开，继续执行下一步。

下一步 步骤 3：发送数据


步骤 3：发送数据

既然有了 Recordset，就需要将其发送到客户端，方法是将该 Recordset 以 XML 格式保存到 ASP Response 对象。向 XMLResponse.asp 的底部添加下列代码。

  Response.ContentType = "text/xml"
  Response.Expires = 0
  Response.Buffer = False

  Response.Write "<?xml version='1.0'?>" & vbNewLine
  adoRec.save Response, adPersistXML
  adoRec.Close
  Set adoRec=Nothing
%>

请注意，ASP Response 对象被指定为 Recordset Save 方法的目标。Save 方法的目标可以是支持 IStream 接口的任何对象（如 ADO Stream 对象），或者是包含保存 Recordset 的完整路径的文件名。

执行下一个步骤之前，请先保存并关闭 XMLResponse.asp。还要将 adovbs.inc 文件从 C:\Program Files\Common Files\System\Ado 文件夹复制到包含 XMLResponse.asp 文件的同一文件夹中。

下一步 步骤 4：接收和显示数据


步骤 4：接收和显示数据

在此步骤中将使用指向 XMLResponse.asp 文件的嵌入的 RDS.DataControl 对象创建 HTML 文件，从而获得 Recordset。使用文本编辑器（如 Windows 记事本）打开 default.htm 并添加下面的代码。用服务器计算机名称替换 URL 中的“sqlserver”。

<HTML>
<HEAD><TITLE>ADO Recordset Persistence Sample</TITLE></HEAD>
<BODY>

<TABLE DATASRC="#RDC1" border="1">
  <TR>
<TD><SPAN DATAFLD="title"></SPAN></TD>
<TD><SPAN DATAFLD="price"></SPAN></TD>
  </TR>
</TABLE>
<OBJECT CLASSID="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" ID="RDC1">
   <PARAM NAME="URL" VALUE="XMLResponse.asp">
</OBJECT>

</BODY>
</HTML>

关闭 default.htm 文件并将其保存在保存 XMLResponse.asp 的同一文件夹中。使用 Internet Explorer 4.0 或更新版本打开 URL http://sqlserver/XMLPersist/default.htm 并观察结果。数据显示在绑定的 DHTML 表中。现在打开 URL http://sqlserver/XMLPersist/XMLResponse.asp 并观察结果。将显示 XML。


第 6 章：错误处理

ADO 使用几个不同的方法来通知应用程序发生了错误。本章讨论使用 ADO 时可能发生的错误类型，以及应用程序如何得到通知。最后提供了关于如何处理这些错误的建议。

ADO 如何报告错误？

ADO 以这几个途径发出错误通知：

  • ADO 错误将生成运行时错误。处理 ADO 错误的方式与处理其他任何运行时错误的方式相同，例如在 Visual Basic 中使用 OnError 语句。
  • 程序可以从 OLE DB 那里接收错误。OLE DB 错误也会生成运行时错误。
  • 如果错误是数据提供者特有的，那么，将把一个或多个 Error 对象放入当发生错误时用来访问数据存储的 Connection 对象的 Errors 集合中。
  • 如果引发事件的进程也产生了错误，则错误信息将放入 Error 对象中，并作为参数传递给事件。有关事件的详细信息，请参阅第 7 章：处理 ADO 事件。
  • 处理批更新或其他涉及 Recordset 的批量操作时所发生的问题可以由 Recordset 的 Status 属性进行指示。例如，可以由 RecordStatusEnum 值指定架构约束违反情况或权限不足。
  • 所发生的问题如果涉及当前记录中的特定 Field，那么，也将由 Record 或 Recordset 的 Fields 集合中的每个 Field 的 Status 属性来指示这些问题。例如，可以由 FieldStatusEnum 值来指定无法完成的更新，或者指定数据类型不可兼容的更新。

以下各节详细描述了每个通知方法。


ADO 错误

ADO 错误将作为运行时错误报告给程序。可以使用编程语言的错误陷阱捕获机制来捕获和处理这些错误。例如，在 Visual Basic 中，可以使用 OnError 语句捕获这些错误。在 Visual J++ 中，可以使用 try-catch 块。在 Visual C++ 中，则根据访问 ADO 库所用的方法的不同而不同。对于 #import，可以使用 try-catch 块。否则，C++ 程序员需要通过调用 GetErrorInfo 来显式地检索错误对象。以下 Visual Basic 子过程演示了捕获 ADO 错误的过程：

' BeginErrorHandlingVB01
Private Sub Form_Load()
    ' Turn on error handling
    On Error GoTo FormLoadError

    'Open the database and the recordset for processing.
    '
    Dim strCnn As String
    strCnn = "Provider='sqloledb';" & _
        "Data Source='MySqlServer';" & _
        "Initial Catalog='Northwind';Integrated Security='SSPI';"

    ' cnn is a Public Connection Object because
    ' it was defined WithEvents
    Set cnn = New ADODB.Connection
    cnn.Open strCnn

    ' The next line of code intentionally causes
    ' an error by trying to open a connection
    ' that has already been opened.
    cnn.Open strCnn

    ' rst is a Public Recordset because it
    ' was defined WithEvents
    Set rst = New ADODB.Recordset
    rst.Open "Customers", cnn

    Exit Sub

' Error handler
FormLoadError:
    Dim strErr As String
    Select Case Err
        Case adErrObjectOpen
            strErr = "Error #" & Err.Number & ": " & Err.Description & vbCrLf
            strErr = strErr & "Error reported by: " & Err.Source & vbCrLf
            strErr = strErr & "Help File: " & Err.HelpFile & vbCrLf
            strErr = strErr & "Topic ID: " & Err.HelpContext
            MsgBox strErr
            Debug.Print strErr
            Err.Clear
            Resume Next
        ' If some other error occurs that
        ' has nothing to do with ADO, show
        ' the number and description and exit.
        Case Else
            strErr = "Error #" & Err.Number & ": " & Err.Description & vbCrLf
            MsgBox strErr
            Debug.Print strErr
            Unload Me
    End Select
End Sub
' EndErrorHandlingVB01

该 Form_Load 事件过程通过试图两次打开同一个 Connection 对象来故意创建错误。第二次调用 Open 方法时，将激活错误处理程序。在这种情况下，错误类型为 adErrObjectOpen，因此，错误处理程序在继续执行程序之前先显示以下消息：

Error #3705: Operation is not allowed when the object is open.
Error reported by: ADODB.Connection
Help File: E:\WINNT\HELP\ADO260.CHM Topic ID: 1003705

错误消息包括了由 Visual Basic Err 对象提供的每条信息，但不包括 LastDLLError 值（该值在这里不适用）。错误号指示已发生的是哪个错误。如果需要由别人替您处理错误，则错误说明将是有用的。可以只把错误说明传递给用户。尽管通常需要使用为应用程序自定义的消息，但您无法预料每个错误；错误说明则为寻找错误原因提供了某些线索。在范例代码中，Connection 对象将报告错误。在这里，您将看到对象的类型或程序 ID，而不是变量名。

注意 Visual Basic Err 对象只包含有关最近错误的信息。对于由最近的 ADO 操作所引起的每个错误，Connection 对象的 ADO Errors 集合均包含一个相应的 Error 对象。使用 Errors 集合而不是 Err 对象可以处理多个错误。有关 Errors 集合的详细信息，请参阅提供者错误。但是，如果没有有效的 Connection 对象，则 Err 对象是 ADO 错误信息的唯一来源。

什么类型的操作有可能导致 ADO 错误呢? 普通 ADO 错误可能由这样一些操作引起：打开诸如 Connection 或 Recordset 这样的对象；试图更新数据；或调用不受提供者支持的方法或属性。

OLE DB 错误还可以作为 Errors 集合中的运行时错误传递给应用程序。有关 OLE DB 错误编号的详细信息，请参阅“OLE DB Programmer's Reference”的 Chapter 16。


ADO 错误参考

ErrorValueEnum 常量描述 ADO 错误值。有关这些枚举常量（包含值）的完整列表，请参阅附录 B：ADO 错误。本节将检查一些比较有趣的错误，并解释能够产生这些错误的特定原因，或解决问题的解决方案。此处列出了 ErrorValueEnum 常量和短的正（十进制）小数。

编号 | ErrorValueEnum 常量 | 说明/可能的原因
3000 | adErrProviderFailed | 提供者无法执行所请求的操作。
3001 | adErrInvalidArgument | 参数类型不正确，参数不在可接受的范围内，或者与其他数据冲突。此错误通常是由 SQL SELECT 语句中的输入错误引起的。例如，拼错的字段名或表名可以产生这一错误。当数据源中不存在 SELECT 语句中命名的字段或表名时，也会出现此错误。
3002 | adErrOpeningFile | 无法打开文件。指定的文件名有拼写错误，或文件已被移走、重命名或删除。在网络上，驱动器可能暂时不可用，或者网络拥挤可能阻碍连接。
3003 | adErrReadFile | 无法读取文件。指定的文件名不正确，文件可能已被移动或删除，或者文件可能已损坏。
3004 | adErrWriteFile | 写入文件失败。您可能已经关闭了文件，然后尝试写入文件，或者文件可能损坏。如果文件位于网络驱动器上，暂时性的网络状况可能会阻碍写入网络驱动器。
3021 | adErrNoCurrentRecord | BOF 或 EOF 中的一个为 True，或者当前记录已被删除。所请求的操作需要当前记录。 通过使用 Find 或 Seek 将记录指针移动到所需的记录来尝试更新记录。如果没有找到记录，EOF 将为 True。此错误还会在 AddNew 或 Delete 失败后出现，因为在这些方法失败时没有当前记录。
3219 | adErrIllegalOperation | 在此上下文中不允许此操作。
3220 | adErrCantChangeProvider | 所提供的提供者与已使用的不同。
3246 | adErrInTransaction | 在事务中 Connection 对象无法被显式关闭。当前参与事务的 Recordset 或 Connection 对象无法被关闭。关闭此对象之前，请调用 RollbackTrans 或 CommitTrans。
3251 | adErrFeatureNotAvailable | 对象或提供者不能执行所请求的操作。有些操作取决于特定的提供者版本。
3265 | adErrItemNotFound | 在集合中无法找到与请求的名称或序号相对应的项目。指定的字段名或表名不正确。
3367 | adErrObjectInCollection | 对象已经在集合中。无法追加。一个对象不能被两次添加到同一集合。
3420 | adErrObjectNotSet | 对象不再有效。
3421 | adErrDataConversion | 应用程序使用的值的类型对于当前操作不正确。例如对于某个操作，您可能提供了字符串，而此操作需要的是一个流。
3704 | adErrObjectClosed | 对象被关闭时，不允许执行操作。Connection 或 Recordset 已被关闭。例如，某些其他例程可能已经关闭了全局对象。在尝试操作之前检查 State 属性可以防止此错误。
3705 | adErrObjectOpen | 对象打开时，不允许执行操作。不能打开已打开的对象。字段不能被附加到打开的 Recordset。
3706 | adErrProviderNotFound | 无法找到提供者。可能没有正确安装提供者。 指定的提供者名称可能不正确，指定的提供者可能没有安装在代码执行的计算机上，或者安装已损坏。
3707 | adErrBoundToCommand | 无法更改以 Command 对象为源的 Recordset 对象的 ActiveConnection 属性。应用程序尝试将新的 Connection 对象指定给以 Command 对象为源的 Recordset。
3708 | adErrInvalidParamInfo | Parameter 对象定义不正确。所提供的信息不一致或不完整。
3709 | adErrInvalidConnection | 连接不能用于执行此操作。在此上下文中，连接可能被关闭或无效。
3710 | adErrNotReentrant | 处理事件时无法执行操作。不能在引起事件再次失败的事件处理程序中执行操作。例如，不应当从 WillMove 事件处理程序中调用 navigation 方法。
3711 | adErrStillExecuting | 异步运行时无法执行操作。
3712 | adErrOperationCancelled | 操作已被用户取消。应用程序已经调用了 CancelUpdate 或 CancelBatch 方法，且当前操作已被取消。
3713 | adErrStillConnecting | 异步连接时无法执行操作。
3714 | adErrInvalidTransaction | 相应的事务无效或尚未开始。
3715 | adErrNotExecuting | 在没有运行时，无法执行操作。
3716 | adErrUnsafeOperation | 本计算机上的安全设置禁止访问其他域上的数据源。
3717 | adWrnSecurityDialog | 仅在内部使用。请勿使用。（为了完全性包含条目。此错误不应当出现在代码中。）
3718 | adWrnSecurityDialogHeader | 仅在内部使用。请勿使用。（为了完全性包含条目。此错误不应当出现在代码中。）
3719 | adErrIntegrityViolation | 数据值与字段完整性限制相冲突。Field 的新值会引起复制键。形成两条记录之间关系的一方面的值可能不可更新。
3720 | adErrPermissionDenied | 没有足够的权限写入字段。连接字符串中命名的用户可能不具备写入 Field 所需的权限。
3721 | adErrDataOverflow | 数据值过大，无法以字段数据类型表示。指定了对于目的字段来说过大的数字值。例如，为短整数字段指定了长整数值。
3722 | adErrSchemaViolation | 数据值和字段的数据类型或限制相冲突。数据存储与 Field 值的有效限制不同。
3723 | adErrSignMismatch | 由于数据值带符号，而提供者使用的字段数据类型不带符号，因此转换失败。
3724 | adErrCantConvertvalue | 无法转换数据值，但不是因为符号不匹配或数据溢出。例如，转换截断了数据。
3725 | adErrCantCreate | 因为字段数据类型未知，或提供者没有足够的资源执行该操作，所以无法设置或检索数据值。
3726 | adErrColumnNotOnThisRow | 记录不包含此字段。指定的字段名不正确，或者所引用的字段在当前记录的 Fields 集合中不存在。
3727 | adErrURLDoesNotExist | 源 URL 或者目标 URL 的父不存在。在源或者目标 URL 中存在输入错误。当您实际上想输入 http://mysite/photos/myphoto.jpg 时，可能误输入为 http://mysite/photo/myphoto.jpg。父 URL（在上述情况下，是 photo 而不是 photos）中的输入错误引发错误。
3728 | adErrTreePermissionDenied | 没有足够的权限访问树或子树。连接字符串中命名的用户不具备适当的权限。
3729 | adErrInvalidURL | URL 包含无效字符。请确保键入的 URL 正确。URL 遵循注册到当前提供者的模式（例如，为 http 注册了 Internet Publishing Provider ）。
3730 | adErrResourceLocked | 由指定的 URL 所表示的对象被一个或多个其他进程锁定。等候至进程结束，然后再尝试此操作。您正在尝试访问的对象已被其他用户或应用程序中的其他进程锁定。这在多用户环境下最有可能发生。
3731 | adErrResourceExists | 复制操作无法执行。目标 URL 命名的对象已经存在。 指定 adCopyOverwrite 以替换该对象。复制某一目录中的文件时，如果没有指定 adCopyOverwrite，那么当试图复制一个目的位置中已经存在的项目时，复制失败。
3732 | adErrCannotComplete | 服务器无法完成此操作。这可能是由于服务器忙于其他操作或服务器资源不足引起的。
3733 | adErrVolumeNotFound | 提供者无法定位由 URL 指示的存储设备。请确保键入的 URL 正确。存储设备的 URL 可能不正确，但此错误还可能由于其他原因而出现。设备可能脱机或者大量的网络通讯阻碍了连接。
3734 | adErrOutOfSpace | 操作无法执行。提供者无法获取足够的存储空间。服务器上可能没有足够的 RAM 或硬件驱动空间存放临时文件。
3735 | adErrResourceOutOfScope | 源或目标 URL 超出了当前记录的范围。
3736 | adErrUnavailable | 操作无法完成，并且状态不可用。字段可能不可用或未尝试该操作。其他用户可能更改或删除了您试图访问的字段。
3737 | adErrURLNamedRowDoesNotExist | 由此 URL 命名的记录不存在。尝试使用 Record 对象打开文件时，拼错了文件名或文件路径。
3738 | adErrDelResOutOfScope | 要删除的对象的 URL 超出了当前记录的范围。
3747 | adErrCatalogNotSet | 操作需要一个有效的 ParentCatalog。
3748 | adErrCantChangeConnection | 连接被拒绝。请求的新连接与正在使用的连接具有不同的特性。
3749 | adErrFieldsUpdateFailed | 字段更新失败。有关详细信息，请检查单个字段对象的 Status 属性。此错误可能在两种情况下出现：在更改或向数据库中添加新记录的过程中更改 Field 对象的值时；以及更改 Field 对象本身属性时。 由于当前记录中的一个字段出现问题，导致 Record 或 Recordset 更新失败。枚举 Fields 集合并检查每个字段的 Status 属性以确定问题的原因。
3750 | adErrDenyNotSupported | 提供者不支持共享限制。尝试限制文件共享且提供者不支持这一概念。
3751 | adErrDenyTypeNotSupported | 提供者不支持所请求类型的共享限制。尝试建立提供者不支持的特定类型的文件共享限制。请参阅提供者的文档以确定是否支持文件共享限制。


提供者错误

发生提供者错误时，将返回运行时错误 -2147467259。收到该错误时，请检查活动 Connection 对象的 Errors 集合，该集合将包含一个或多个描述所发生情况的错误消息。

ADO Errors 集合

由于特殊的 ADO 操作可以产生多个提供者错误，所以，ADO 通过 Connection 对象显露了一个错误对象集合。如果操作成功完成，该集合不会包含任何对象；如果出现错误并且提供者引起一个或多个错误，该集合将包含一个或多个 Error 对象。请单独检查每个错误对象，确定错误的准确原因。

一旦已处理完已发生的任何错误，就可以通过调用 Clear 方法清除该集合。非常重要的是，在执行下列操作之前一定要显式地清除 Errors 集合：在调用 Recordset 对象的 Resync、UpdateBatch 或 CancelBatch 方法之前；执行 Connection 对象的 Open 方法之前；或设置 Recordset 对象的 Filter 属性之前。通过显式地清除集合，才能肯定集合中不会留下以前的操作所产生的任何 Error 对象。

某些操作会像生成错误一样生成警告。警告也是由 Errors 集合中的 Error 对象表示的。提供者将警告添加到集合中时，不会生成运行时错误。通过检查 Errors 集合的 Count 属性可以确定警告是否是由特殊的操作产生的。如果个数是一个或大于一个，则说明已经有 Error 对象添加到集合中。一旦已确定 Errors 集合包含错误或警告，就可以遍历集合的所有成员，并检索该集合所包含的每个 Error 对象的相关信息。以下的简短 Visual Basic 范例演示了这一过程：

' BeginErrorHandlingVB02
Private Function DeleteCustomer(ByVal CompanyName As String) As Long
    On Error GoTo DeleteCustomerError

    rst.Find "CompanyName='" & CompanyName & "'"

DeleteCustomerError:

    Dim objError As ADODB.Error
    Dim strError As String

    If cnn.Errors.Count > 0 Then
        For Each objError In cnn.Errors
            strError = strError & "Error #" & objError.Number & _
                " " & objError.Description & vbCrLf & _
                "NativeError: " & objError.NativeError & vbCrLf & _
                "SQLState: " & objError.SQLState & vbCrLf & _
                "Reported by: " & objError.Source & vbCrLf & _
                "Help file: " & objError.HelpFile & vbCrLf & _
                "Help Context ID: " & objError.HelpContext
        Next
        MsgBox strError
    End If
End Function
' EndErrorHandlingVB02

错误处理例程包括一个用于检查 Errors 集合中每个对象的 For Each 循环。在该范例中，它只累积了一条用于显示的消息。在工作程序中，可以编写针对每个错误执行适当任务的代码，例如，按顺序关闭所有打开的文件并关闭程序。

Error 对象

通过检查 Error 对象，可以确定发生了什么错误，以及更重要的、什么应用程序或对象导致了错误。Error 对象有以下属性：

属性名称 | 说明
Description | 说明所发生的错误的文本。
HelpContext, HelpFile | 指向帮助主题和帮助文件（其中包含对所发生错误的说明）。
NativeError | 提供者特有的错误编号。
Number | 长整型数字，表示所发生的错误数（在 ErrorValueEnum 中列出）。
Source | 指示产生错误的对象或应用程序的名称。
SQLState | 在执行 SQL 语句期间由提供者返回的、五个字符的错误代码。

ADO Error 对象很类似标准的 Visual Basic Err 对象。其属性描述了所发生的错误。除了错误编号以外，您还会收到两条相关的信息。NativeError 属性包含您使用的提供者所特有的错误编号。在前面的范例中，提供者是 Microsoft OLE DB Provider for SQL Server，因此 NativeError 将包含 SQL Server 特有的错误。SQLState 属性有五个字母的代码，用于描述 SQL 语句中的错误。

事件相关错误

发生与事件相关的错误时，还会使用 Error 对象。通过检查作为事件参数传递的 Error 对象，可以确定在 ADO 事件所引起的进程中是否发生了错误。

如果导致事件发生的操作成功结束，则事件处理程序的 adStatus 参数将设置为 adStatusOK。另一方面，如果引起事件的操作不成功，则 adStatus 参数将设置为 adStatusErrorsOccurred。在这种情况下，pError 参数将包含用于描述错误的 Error 对象。


与字段有关的错误信息

如果错误与字段直接相关（例如，如果数据丢失或字段的数据类型有错误），那么，可以通过检查 Field 对象的 Status 属性，来检索关于问题原因的详细信息。该属性已经进行了改进，能够提供关于问题的具体信息。因此，例如在调用 UpdateBatch 失败时，可以通过检查每个受影响的记录中的 Fields 的 Status 属性来确定问题原因。该属性将包含 FieldStatusEnum 常量中的一个值。下表包括了发生错误时那些有特殊意义的值。

常量 | 值 | 说明
adFieldCantConvertValue | 2 | 指示无法在不损失数据的情况下检索或存储该字段。
adFieldDataOverflow | 6 | 指示从提供者返回的数据超出了字段的数据类型。
adFieldDefault | 13 | 指示在设置数据时使用字段的默认值。
adFieldIgnore | 15 | 指示在设置源中的数据值时，此字段被跳过。提供者未设置任何值。
adFieldIntegrityViolation | 10 | 指示由于该字段是计算或派生的项目，因此无法对其进行修改。
adFieldIsNull | 3 | 指示提供者返回了 Null 值。
adFieldOutOfSpace | 22 | 指示提供者无法获取足够的存储空间来完成移动或复制操作。


与 Recordset 有关的错误信息

在批处理期间，Recordset 对象的 Status 属性提供 Recordset 中有关单个记录的信息。在批更新开始之前，Recordset 的 Status 属性反映要添加、更改和删除记录的相关信息。调用 UpdateBatch 之后，Status 属性则显示调用操作是否成功。随着从 Recordset 中的一个记录移动到另一个记录，Status 属性值也会更改，以描述当前记录的状态。


在其他语言中处理错误

到此为止，本章从 Microsoft Visual Basic 的角度对错误进行了讨论。这一节的其余内容将概述在 Visual Basic 以外的语言中如何进行错误处理。


在 VBScript 中处理错误

在 Visual Basic 中使用的错误处理方法与在 VBScript 中使用的方法有点不同。主要差异是 VBScript 不支持通过在标签位置继续执行代码从而进行错误处理这样的概念。换句话说，在 VBScript 中无法使用 On Error GoTo。而是使用 On Error Resume Next，然后检查 Err.Number 以及 Errors 集合的 Count 属性，以下范例演示了这种方法：

<!-- BeginErrorExampleVBS -->
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE>Error Handling Example (VBScript)</TITLE>
</HEAD>
<BODY>

<h1>Error Handling Example (VBScript)</h1>

<%
    Dim errLoop
    Dim strError

    On Error Resume Next

    ' Intentionally trigger an error.
    Set cnn1 = Server.CreateObject("ADODB.Connection")
    cnn1.Open "nothing"

    If cnn1.Errors.Count > 0 Then
        ' Enumerate Errors collection and display
        ' properties of each Error object.
        For Each errLoop In cnn1.Errors
            strError = "Error #" & errLoop.Number & "<br>" & _
                "   " & errLoop.Description & "<br>" & _
                "   (Source: " & errLoop.Source & ")" & "<br>" & _
                "   (SQL State: " & errLoop.SQLState & ")" & "<br>" & _
                "   (NativeError: " & errLoop.NativeError & ")" & "<br>"
            If errLoop.HelpFile = "" Then
                strError = strError & _
                    "   No Help file available" & _
                    "<br><br>"
            Else
                strError = strError & _
                    "   (HelpFile: " & errLoop.HelpFile & ")" & "<br>" & _
                    "   (HelpContext: " & errLoop.HelpContext & ")" & _
                    "<br><br>"
            End If
            Response.Write ("<p>" & strError & "</p>")
        Next
    End If
%>

</BODY>
</HTML>
<!-- EndErrorExampleVBS -->


在 Visual C++ 中处理错误

在 COM 中，许多操作均返回一个 HRESULT 返回代码，该代码指示某个功能是否顺利完成。#import 伪指令针对每种“原始”方法或属性生成封装代码，并检查返回的 HRESULT。如果 HRESULT 指示失败，封装代码将通过把 HRESULT 返回代码作为参数来调用 _com_issue_errorex() 的方式产生 COM 错误。可在“try-catch”代码块中捕获 COM 错误对象。（为提高效率，请引用 _com_error 对象。）

请记住，由于 ADO 操作失败而产生的错误才是 ADO 错误。由基本提供者返回的错误将作为 Error 对象出现在 Connection 对象的 Errors 集合中。

#import 伪指令只为在 ADO .dll 中声明过的属性和方法创建错误处理例程。但是，通过写入您自己的错误检查宏或内联函数，可以利用此错误处理机制。有关范例，请参阅 Visual C++ Extensions 主题。


在 Visual J++ 中处理错误

在 Microsoft Visual J++ 应用程序中，应当使用“try catch”代码块来处理 ADO 错误。一旦错误已经产生，则可以遍历集合所有成员，从而连续处理每个错误。以下 Visual J++ 范例演示了一个故意导致错误的控制台应用程序。

“catch”代码块激活时，它将调用 PrintProviderError 函数来显示错误。PrintProviderError 函数遍历 Errors 集合，并将一行消息发送给标准输出设备，以描述集合中的每个错误。

// BeginErrorExampleVJ
/**
 * This class can take a variable number of parameters on the command
 * line. Program execution begins with the main() method. The class
 * constructor is not invoked unless an object of type 'Class1'
 * created in the main() method.
 */

import com.ms.wfc.data.*;
import java.io.* ;

public class ErrorExample
{
    /**
     * The main entry point for the application.
     *
     * @param args Array of parameters passed to the application
     * via the command line.
     */
    public static void main (String[] args)
    {
        DescriptionX();
        System.exit(0);
    }

    static void DescriptionX()
    {
        BufferedReader in = new
        BufferedReader(new InputStreamReader(System.in));

        // Define ADO Objects.
        Connection cnConn1 = null;

        try
        {
            // Create an error by trying to
            // Open a database that doesn't exist.
            cnConn1 = new Connection();
            cnConn1.open("nothing");
        }
        catch( AdoException ae )
        {
            // Notify user of any errors that result from ADO.
            PrintProviderError(cnConn1);
        }

        try
        {
            System.out.println("\nPress <Enter> key to continue.");
            in.readLine();
        }
        // System read requires this catch.
        catch( java.io.IOException je)
        {
            PrintIOError(je);
        }
    }

    // PrintProviderError Function
    static void PrintProviderError( Connection Cnn1 )
    {
        // Print Provider errors from Connection object.
        // ErrItem is an item object in the Connections Errors collection.
        com.ms.wfc.data.Error  ErrItem = null;
        long nCount = 0;
        int  i      = 0;

        nCount = Cnn1.getErrors().getCount();

        // If there are any errors in the collection, print them.
        if( nCount > 0);
        {
            // Collection ranges from 0 to nCount - 1
            for (i = 0; i< nCount; i++)
            {
                ErrItem = Cnn1.getErrors().getItem(i);
                System.out.println("\t Error number: " + ErrItem.getNumber()
                   + "\t" + ErrItem.getDescription() );
            }
        }
    }

    // PrintIOError Function
    static void PrintIOError( java.io.IOException je)
    {
        System.out.println("Error \n");
        System.out.println("\tSource = " + je.getClass() + "\n");
        System.out.println("\tDescription = " + je.getMessage() + "\n");
    }
}
// EndErrorExampleVJ


在 JScript 中处理错误

Microsoft JScript 代码必须检查 Connection 对象的 Errors 集合的 Count 属性。如果值大于 0，则遍历集合内的所有错误，并像在其他任何语言中一样打印值。

<!-- BeginErrorExampleJS -->
<%@ Language=JScript %>
<HTML>
<HEAD>
<title>Error Handling Example (JScript)</title>
</HEAD>
<BODY>
<h1>Error Handling Example (JScript)</h1>
<%
    var cnn1 = Server.CreateObject("ADODB.Connection");
    var errLoop = Server.CreateObject("ADODB.Error");
    var strError = new String;

    try
    {
        // Intentionally trigger an error.
        cnn1.Open("nothing");
    }
    catch(e)
    {
        Response.Write(e.message);
    }
%>

</BODY>
</HTML>
<!-- EndErrorExampleJS -->


预料错误

防止错误与处理错误至少有同等的重要性。最后这一节包含了应用程序可以采纳的预防措施的简短列表，这些措施有助于尽可能减少错误。

在试图使用对象执行操作之前，通过检查 State 属性中的值来检查该对象的状态。例如，如果应用程序使用全局 Connection，则应当检查其 State 属性，以便在调用 Open 方法之前确定该 Connection 是否已经打开。

  • 任何从用户那里接受数据的程序都必须包括用于在将该数据发送到数据存储之前验证数据的代码。不能依靠数据存储、提供者、ADO、甚至编程语言来发出问题通知。必须检查由用户输入的每个字节，确保数据对于接收该数据的字段来说具有正确的类型，并确保必需字段不为空。

在试图将任何数据写入数据存储之前对数据进行检查。这样做的最容易方式是处理 WillMove 事件或 WillUpdateRecordset 事件。有关处理 ADO 事件的更详细的论述，请参阅第 7 章：处理 ADO 事件。

在试图移动记录指针之前，确保 Recordset 对象没有超过 Recordset 的边界。如果当 EOF 为 True 时试图执行 MoveNext，或者当 BOF 为 True 时试图执行 MovePrev，将发生错误。如果当 EOF 和 BOF 都为 True 时执行了任何 Move 方法，将生成错误。

如果试图对空 Recordset 执行诸如 Seek 和 Find 这样的操作，也将发生错误。


第 7 章：处理 ADO 事件

ADO 事件模型支持某些同步和异步 ADO 操作，这些操作在开始之前或完成之后发出“事件”（即通知）。事件实际上是对在应用程序中定义的事件处理程序例程的调用。

如果在操作开始之前为发生的一组事件提供处理程序函数或过程，那么您可以检查或修改传递到该操作的参数。因为它还未执行，所以您可以取消该操作或允许完成该操作。

如果使用 ADO 异步操作，则在操作完成之后发生的事件组尤其重要。例如，启动异步 Recordset.Open 操作的应用程序在操作结束时会接收到执行完成事件的通知。

虽然使用 ADO 事件模型增加了应用程序的一些开销，但是它提供了比其他异步操作处理方法（例如通过循环监视对象的 State 属性）更大的灵活性。

请参阅

ADO 事件处理程序汇总 | 不同语言的 ADO 事件实例 | ADO 事件 | 事件参数 | 事件类型


ADO 事件处理程序汇总

两个 ADO 对象可以产生事件：Connection 对象和 Recordset 对象。ConnectionEvent 类从属于 Connection 对象的操作，而 RecordsetEvent 类从属于 Recordset 对象的操作。

  • Connection 事件：在下列情况下将发出此类事件，在连接上的事务开始、提交或回卷时，在 Command 执行时，在 Connection Event 操作过程中出现警告时，或者在 Connection 开始或结束时。
  • Recordset 事件：在下列情况下将发出此类事件，当在 Recordset 对象行中定位、更改 Recordset 的行中的字段、更改 Recordset 中的行、通过服务器端游标打开 Recordset、关闭 Recordset 或是对 Recordset 做任何修改时，以及异步提取操作前后。

下表是这些事件及其说明的汇总。

ConnectionEvent | Description
BeginTransComplete、 CommitTransComplete 和 RollbackTransComplete | 事务管理 — 通知连接中的当前事务已开始、提交或回卷。
WillConnect、ConnectComplete 和 Disconnect | 连接管理 — 通知当前连接即将开始、已经开始、或者已经结束。
WillExecute 和 ExecuteComplete | 命令执行管理 — 通知连接中当前命令的执行即将开始或已经结束。
InfoMessage | 信息 — 通知存在与当前操作相关的附加信息。
RecordsetEvent | Description
FetchProgress 和 FetchComplete | 检索状态 — 通知数据检索操作的进度或检索操作已经完成。只有在使用客户端游标打开 Recordset 时，这些事件才可用。
WillChangeField 和 FieldChangeComplete | 字段更改管理 — 通知当前字段的值将要更改或已经更改。
WillMove、MoveComplete 和 EndOfRecordset | 定位管理 — 通知 Recordset 中的当前行位置将要更改、已经更改或已到达 Recordset 的结尾。
WillChangeRecord 和 RecordChangeComplete | 行更改管理 — 通知 Recordset 当前行中的某些内容将要更改或已经更改。
WillChangeRecordset 和 RecordsetChangeComplete | 记录集更改管理 — 通知当前 Recordset 中的某些内容将要更改或已经更改。

请参阅

不同语言的 ADO 事件实例 | ADO 事件 | 事件参数 | 事件处理程序如何协同工作 | 事件类型


事件类型

有两种基本的事件类型。“Will 事件”，在操作开始之前调用这类事件，通常在名称中包括“Will”。例如，WillChangeRecordset 或 WillConnect。完成一个事件之后调用的事件在名称中包括“Complete”。例如， RecordChangeComplete 或 ConnectComplete。存在诸如 InfoMessage 之类的例外，但这些例外是在完成相关联的操作之后才发生的。

Will 事件

在操作开始之前调用的事件处理程序使用户可以检查或修改操作参数，然后取消操作或允许完成操作。通常，这些事件处理程序名称的格式为 WillEvent。

Complete 事件

在操作完成之后调用的事件处理程序可以通知应用程序操作已经结束。当 Will 事件处理程序取消一个挂起的操作时，该事件处理程序也会收到通知。通常，这些事件处理程序名称的格式为 EventComplete。

Will 和 Complete 事件一般成对使用。

其他事件

其他事件处理程序，即事件名称不使用 WillEvent 或 EventComplete 格式的事件，仅在操作完成后调用。这些事件为 Disconnect、EndOfRecordset 和 InfoMessage。

请参阅

ADO 事件处理程序汇总 | 不同语言的 ADO 事件实例 | 事件参数 | 事件处理程序如何协同工作


事件参数

每个事件处理程序都有一个控制它的状态参数。对于 Complete 事件，该参数还用于指示生成事件的操作是成功还是失败。大部分 Complete 事件还有一个错误参数，用于提供有关可能发生错误的信息，还有一个或多个对象参数，这些参数引用用于执行操作的 ADO 对象。例如，ExecuteComplete 事件包含与该事件相关的 Command、Recordset 和 Connection 对象的对象参数。在以下 Microsoft Visual Basic 范例中，您可以看到 pCommand、pRecordset 和 pConnection 对象，这些对象表示 Execute 方法使用的 Command、Recordset 和 Connection 对象。

Private Sub connEvent_ExecuteComplete(ByVal RecordsAffected As Long, _
     ByVal pError As ADODB.Error, _
     adStatus As ADODB.EventStatusEnum, _
     ByVal pCommand As ADODB.Command, _
     ByVal pRecordset As ADODB.Recordset, _
     ByVal pConnection As ADODB.Connection)

除了 Error 对象以外，相同的参数还传递到 Will 事件。这使您能够检查要在挂起操作中的使用每个对象，并决定是否允许该操作完成。

某些事件处理程序有一个 Reason 参数，提供有关事件发生原因的其他信息。例如，由于调用任何一种定位方法（MoveNext、MovePrevious 等）或作为重新查询的结果，可能发生 WillMove 和 MoveComplete 事件。

状态参数

当调用事件处理程序例程时，Status 参数被设置为下列值之一。

值 | Description
adStatusOK | 传递到 Will 和 Complete 参数。该值意味着导致事件的操作成功完成。
adStatusErrorsOccurred | 只传递到 Complete 事件。该值意味着导致事件的操作未成功完成，或者 Will 事件取消了操作。有关详细信息，请参阅 Error 参数。
adStatusCantDeny | 只传递到 Will 事件。该值意味着不能由 Will 事件取消操作。必须执行它。

如果您决定操作在 Will 事件中继续，请保持 Status 参数不变。但是，只要传入状态参数未被设置为 adStatusCantDeny，您就可以通过将 Status 更改为 adStatusCancel 来取消挂起的操作。如果这样做，那么与该操作相关的 Complete 事件会将其 Status 参数设置为 adStatusErrorsOccurred。传递到 Complete 事件的 Error 对象将包含值 adErrOperationCancelled。

如果不想再处理某个事件，可以将 Status 设置为 adStatusUnwantedEvent，应用程序将不再接收该事件的通知。但是，请记住，某些事件可能是多个原因引起的。在这种情况下，您必须为每个可能的原因指定 adStatusUnwantedEvent。例如，为了停止接收挂起 RecordChange 事件的通知，必须在 adRsnAddNew、adRsnDelete、adRsnUpdate、adRsnUndoUpdate、adRsnUndoAddNew、adRsnUndoDelete 和 adRsnFirstChange 发生时，将其 Status 参数设置为 adStatusUnwantedEvent。

值 | Description
adStatusUnwantedEvent | 请求此事件处理程序不接收其他通知。
adStatusCancel | 请求取消即将开始的操作。

错误参数

Error 参数是对 ADO Error 对象的引用。如果将 Status 参数设置为 adStatusErrorsOccurred，则 Error 对象将包含有关操作失败原因的详细信息。如果与 Complete 事件相关联的 Will 事件已经通过将 Status 参数设置为 adStatusCancel 取消了操作，则通常将错误对象设置为 adErrOperationCancelled。

对象参数

每个事件将接收表示包含于操作中对象的一个或多个对象。例如，ExecuteComplete 事件将接收一个 Command 对象、一个 Recordset 对象和一个 Connection 对象。

原因参数

Reason 参数 adReason 提供有关事件发生原因的其他信息。即使对于同一操作，具有 adReason 参数的事件也可以由于不同的原因而被多次调用。例如，WillChangeRecord 事件处理程序被某些操作调用，这些操作即将执行或撤消记录的插入、删除或修改。如果希望只在某个特定原因发生时才处理事件，则可以使用 adReason 参数过滤出不感兴趣的事件。例如，如果希望只是在由于添加记录而发生记录更改事件时才对其进行处理，可以执行如下操作：

' BeginEventExampleVB01
Private Sub rsTest_WillChangeRecord(ByVal adReason As ADODB.EventReasonEnum, ByVal cRecords As Long, adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)
   If adReason = adRsnAddNew Then
       ' Process event
       '...
   Else
       ' Cancel event notification for all
       ' other possible adReason values.
       adStatus = adStatusUnwantedEvent
   End If
End Sub
' EndEventExampleVB01

在这种情况下，对于每个其他原因通知可能发生。但是对于每个原因只发生一次。在通知对每个原因发生过一次后，您将只收到有关其他新记录的通知。

相反，只需要将 adStatus 设置为 adStatusUnwantedEvent 一次来请求没有 adReason 参数的事件处理程序停止接收事件通知。

请参阅

ADO 事件处理程序概要 | 不同语言的 ADO 事件实例 | 事件处理程序如何协同工作 | 事件类型


事件处理程序如何协同工作

除非正在 Visual Basic 中编程，否则必须实现 Connection 和 Recordset 事件的所有事件处理程序，而不管实际上是否处理所有事件。实现所需的工作量取决于所使用的编程语言。有关详细信息，请参阅不同语言的 ADO 事件实例。

成对的事件处理程序

每个 Will 事件处理程序都有相关的 Complete 事件处理程序。例如，在应用程序更改字段的值时，将调用 WillChangeField 事件处理程序。如果该更改是可接受的，则应用程序将保持 adStatus 参数不变并且执行操作。操作完成后，FieldChangeComplete 事件将通知应用程序该操作已完成。如果操作成功地完成了，则 adStatus 将包含 adStatusOK；否则 adStatus 将包含 adStatusErrorsOccurred，必须检查 Error 对象以确定错误的原因。

调用 WillChangeField 时，您可以决定不进行更改。在这种情况下，请将 adStatus 设置为 adStatusCancel。操作将被取消并且 FieldChangeComplete 事件将接收 adStatusErrorsOccurred 的 adStatus 值。Error 对象包含 adErrOperationCancelled，以便 FieldChangeComplete 处理程序知道已取消了该操作。但是，在更改之前必须检查 adStatus 参数的值，因为如果将过程的项目中的参数设置为 adStatusCantDeny，则将 adStatus 设置为 adStatusCancel 无效。

有时，一个操作可以引起多个事件。例如 Recordset 对象对于 Field 更改和 Record 更改有成对的事件。在应用程序更改 Field 的值时，将调用 WillChangeField 事件处理程序。如果它确定操作可以继续，那么还会引起 WillChangeRecord 事件处理程序。如果该处理程序也允许事件继续，则将进行更改并且将调用 FieldChangeComplete 和 RecordChangeComplete 事件处理程序。调用特定操作的 Will 事件处理程序的顺序不会被定义，因此您应该避免编写依赖于以特定序列调用处理程序的代码。

在引起多个 Will 事件的实例中，其中一个事件可以取消挂起的操作。例如，当应用程序更改了 Field 的值时，正常情况下将调用 WillChangeField 和 WillChangeRecord 事件处理程序。但是，如果在第一个事件处理程序中取消了操作，就会使用 adStatusOperationCancelled 立即调用其关联的 Complete 处理程序。不会调用第二个处理程序。但是，如果第一个事件处理程序允许事件继续，则其他事件处理程序将被调用。如果取消了操作，则将像在较早范例中那样调用两个 Complete 事件。

不成对的事件处理程序

只要传递到事件的状态不是 adStatusCantDeny，就可以通过在 Status 参数中返回 adStatusUnwantedEvent 来关闭所有事件的事件通知。例如，当第一次调用 Complete 事件处理程序时，可以返回 adStatusUnwantedEvent。随后将只收到 Will 事件。但是，某些事件可能是由多个原因触发的。在这种情况下，事件将包含 Reason 参数。在返回 adStatusUnwantedEvent 时，将停止接收只是由于特定原因才发生的那些事件的通知。换句话说，您将可能接收可触发事件的每个可能原因的通知。

当需要检查操作中将要使用的参数时，单个 Will 事件处理程序会很有帮助。可以修改这些操作参数或取消操作。

也可以启用 Complete 事件通知。当调用第一个 Will 事件处理程序时，返回 adStatusUnwantedEvent。随后将只收到 Complete 事件。

单个 Complete 事件处理程序有助于管理异步操作。每个异步操作都有相应的 Complete 事件。

例如，预置大的 Recordset 对象要花很长时间。如果应用程序编写恰当，可以启动 Recordset.Open(...,adAsyncExecute) 操作并继续进行其他处理。最终您会在 Recordset 预置完成时收到 ExecuteComplete 事件的通知。

单个事件处理程序和多个对象

Microsoft Visual C++ 这类编程语言非常灵活，一个事件处理程序可以处理多个对象的事件。 例如，一个 Disconnect 事件处理程序可以处理多个 Connection 对象的事件。如果一个连接结束，Disconnect 事件处理程序便会被调用。因为事件处理程序的对象参数被设置为相应的 Connection 对象，所以可以判断出引起事件的连接。

注意 此技术不能用于 Visual Basic，因为该语言只能将一个对象与一个事件处理程序相关联。

请参阅

ADO 事件处理程序汇总 | 不同语言的 ADO 事件实例 | 事件参数 | 事件类型


不同语言的 ADO 事件实例

每种编程语言创建的 ADO 事件的实例都有差别。下面的所有范例均创建 ConnectComplete 事件处理程序。

  • Visual Basic
  • Visual C++
  • Visual J++
  • VBScript
  • JScript
  • ADO/WFC


Visual Basic

为了在 Microsoft Visual Basic 中处理 ADO 事件，必须使用 WithEvents 关键字声明模块级变量。变量可以只声明为类模块的一部分，并且必须在模块级进行声明。但是，这不是严格的限制，因为 Visual Basic Form 对象也是类。处理 ADO 事件的最简单方式是使用 WithEvents 来声明变量。以下范例将处理 Connection 对象的 ConnectComplete 事件：

' BeginEventExampleVB02
Dim WithEvents connEvent As Connection
Attribute connEvent.VB_VarHelpID = -1
Dim strMsg As String

Private Sub Form_Load()
    On Error GoTo ErrHandler:

    Dim strConn As String

    ' Create a new object with event
    ' handling enabled.
    strConn = "Provider='sqloledb';" & _
        "Data Source='MySqlServer';" & _
        "Initial Catalog='Northwind';" & _
        "Integrated Security='SSPI';"
    Set connEvent = New ADODB.Connection
    connEvent.Open strConn

    Exit Sub

ErrHandler:
    MsgBox strMsg
End Sub

Private Sub connEvent_ConnectComplete(ByVal pError As ADODB.Error, _
    adStatus As ADODB.EventStatusEnum, _
    ByVal pConnection As ADODB.Connection)

    If adStatus = adStatusErrorsOccurred Then
        If Not pError Is Nothing Then
            Select Case pError.Number
                Case adErrOperationCancelled
                    ' The operation was cancelled in the
                    ' Will event. Notify the user and exit.
                    strMsg = "I'm sorry you can't connect right now." & vbCrLf
                    strMsg = strMsg & " Click OK to exit."
                    Unload Me
                Case Else
                    strMsg = "Error " & Format(pError.Number) & vbCrLf
                    strMsg = strMsg & pError.Description
                    strMsg = strMsg & " Click OK to exit."
                    Unload Me
            End Select
        Else
            strMsg = "Error occured. Click OK to exit."
            Unload Me
        End If
    End If
    'frmWait.btnOK.Enabled = True
End Sub
' EndEventExampleVB02

Connection 对象在 Form 级进行声明，并使用 WithEvents 关键字来启用事件处理。Form_Load 事件处理程序通过将新的 Connection 对象赋给 connEvent 来实际地创建对象，然后打开连接。当然，在 Form_Load 事件处理程序中，真实的应用程序有比上面的范例更多的处理步骤。


Visual C++

这是关于如何在 Visual C++ 中实例化 ADO 事件的示意性说明。有关完整的说明，请参阅 ADO 事件模型范例 (Visual C++)。

创建由 ConnectionEventsVt 和 RecordsetEventsVt 接口（在 adoint.h 文件中）派生的类。

// BeginEventExampleVC01
class CConnEvent : public ConnectionEventsVt
{
    public:
    STDMETHODIMP InfoMessage(
            ADOError *pError,
            EventStatusEnum *adStatus,
            _ADOConnection *pConnection);
...
}

class CRstEvent : public RecordsetEventsVt
{
    public:
        STDMETHODIMP WillChangeField(
                LONG cFields,
                VARIANT Fields,
                EventStatusEnum *adStatus,
                _ADORecordset *pRecordset);
...
}
// EndEventExampleVC01

在两个类中实现每个事件处理程序方法。虽然每个方法只返回一个 S_OK（类型为 HRESULT）已经足够，但是，当您通告事件处理程序可用时，默认情况下，这些事件处理程序将被连续调用。而您可能想通过将 adStatus 设置为 adStatusUnwantedEvent 以便在第一次通知之后请求不发出进一步的通知。

// BeginEventExampleVC02
STDMETHODIMP CConnEvent::ConnectComplete(
            ADOError *pError,
            EventStatusEnum *adStatus,
            _ADOConnection *pConnection)
        {
        *adStatus = adStatusUnwantedEvent;
        return S_OK;
        }

// EndEventExampleVC02

事件类是从 Iunknown 继承的，所以必须实现 QueryInterface、AddRef 和 Release 方法。还必须实现类的构造函数和析构函数。通过选择您最熟练的 Visual C++ 工具可以简化这部分任务。

在 Recordset 和 Connection 对象上对 IConnectionPointContainer 和 IConnectionPoint 接口发出 QueryInterface 之后，事件处理程序即可以使用。然后对每个类发出 IConnectionPoint::Advise。

例如，假设您正在使用 Boolean 函数，此函数在成功地向 Recordset 对象发出可以使用事件处理程序的通知时返回 True 值。

// BeginEventExampleVC03
HRESULT    hr;
DWORD      dwEvtClass;
IConnectionPointContainer    *pCPC = NULL;
IConnectionPoint             *pCP = NULL;
CRstEvent                    *pRStEvent = NULL;
...
_RecordsetPtr                pRs;
pRs.CreateInstance(__uuidof(Recordset));
pRStEvent = new CRstEvent;
if (pRStEvent == NULL) return FALSE;
...
hr = pRs->QueryInterface(IID_IConnectionPointContainer, (LPVOID *)&pCPC);
if (FAILED(hr)) return FALSE;
hr = pCPC->FindConnectionPoint(RecordsetEvents, &pCP);
pCPC->Release();    // Always Release now, even before checking.
if (FAILED(hr)) return FALSE;
hr = pCP->Advise(pRstEvent, &dwEvtClass);   //Turn on event support.
pCP->Release();
if (FAILED(hr)) return FALSE;
...
return TRUE;
...
// EndEventExampleVC03

此时，将启用 RecordsetEvent 类事件，并且当 Recordset 事件发生时将调用这些方法。

此后，如果您想使事件处理程序无效，可以再次获取连接点并发出 IConnectionPoint::Unadvise 方法。

// BeginEventExampleVC04
...
hr = pCP->Unadvise(dwEvtClass);    //Turn off event support.
pCP->Release();
if (FAILED(hr)) return FALSE;
...
// EndEventExampleVC04

必须在合适的时候释放接口并销毁类对象。

以下代码显示了 Recordset 事件接收器类的完整范例。

// BeginEventExampleVC05
#include <adoint.h>

class CADORecordsetEvents : public RecordsetEventsVt
{
public :

   ULONG m_ulRefCount;
   CADORecordsetEvents():m_ulRefCount(1){}

   STDMETHOD(QueryInterface)(REFIID iid, LPVOID * ppvObject)
   {
      if (IsEqualIID(__uuidof(IUnknown), iid) ||
         IsEqualIID(__uuidof(RecordsetEventsVt), iid))
      {
         *ppvObject = this;
         return S_OK;
      }
      else
         return E_NOINTERFACE;
   }

   STDMETHOD_(ULONG, AddRef)()
   {
      return m_ulRefCount++;
   }

   STDMETHOD_(ULONG, Release)()
   {
      if (--m_ulRefCount == 0)
      {
         delete this;
         return 0;
      }
      else
         return m_ulRefCount;
   }

   STDMETHOD(WillChangeField)(
             LONG cFields,
          VARIANT Fields,
          EventStatusEnum *adStatus,
             _ADORecordset  *pRecordset)
   {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
   }

    STDMETHOD(FieldChangeComplete)(
             LONG cFields,
             VARIANT Fields,
             ADOError  *pError,
             EventStatusEnum  *adStatus,
             _ADORecordset  *pRecordset)
     {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
    }

    STDMETHOD(WillChangeRecord)(
            EventReasonEnum adReason,
            LONG cRecords,
            EventStatusEnum  *adStatus,
            _ADORecordset  *pRecordset)
   {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
   }

    STDMETHOD(RecordChangeComplete)(
            EventReasonEnum adReason,
            LONG cRecords,
            ADOError  *pError,
            EventStatusEnum  *adStatus,
         _ADORecordset  *pRecordset)
   {
      *adStatus = adStatusUnwantedEvent;
      return S_OK;
   }

    STDMETHOD(WillChangeRecordset)(
            EventReasonEnum adReason,
            EventStatusEnum  *adStatus,
            _ADORecordset  *pRecordset)
   {
      *adStatus = adStatusUnwantedEvent;
      return S_OK;
   }

    STDMETHOD(RecordsetChangeComplete)(
            EventReasonEnum adReason,
            ADOError *pError,
            EventStatusEnum  *adStatus,
            _ADORecordset  *pRecordset)
   {
      *adStatus = adStatusUnwantedEvent;
      return S_OK;
   }

    STDMETHOD(WillMove)(
            EventReasonEnum adReason,
            EventStatusEnum  *adStatus,
            _ADORecordset  *pRecordset)
   {
      *adStatus = adStatusUnwantedEvent;
      return S_OK;
   }

    STDMETHOD(MoveComplete)(
            EventReasonEnum adReason,
            ADOError  *pError,
            EventStatusEnum  *adStatus,
            _ADORecordset  *pRecordset)
    {
      *adStatus = adStatusUnwantedEvent;
      return S_OK;
   }

    STDMETHOD(EndOfRecordset)(
            VARIANT_BOOL  *fMoreData,
            EventStatusEnum  *adStatus,
            _ADORecordset  *pRecordset)
   {
      *adStatus = adStatusUnwantedEvent;
      return S_OK;
   }

    STDMETHOD(FetchProgress)(
            long Progress,
            long MaxProgress,
            EventStatusEnum  *adStatus,
            _ADORecordset  *pRecordset)
   {
      *adStatus = adStatusUnwantedEvent;
      return S_OK;
   }

    STDMETHOD(FetchComplete)(
            ADOError  *pError,
            EventStatusEnum  *adStatus,
            _ADORecordset  *pRecordset)
   {
      *adStatus = adStatusUnwantedEvent;
      return S_OK;
   }

};
// EndEventExampleVC05


Visual J++

这个简短的 Microsoft Visual J++ 范例演示了如何将自己的函数与特殊的事件关联起来。

// BeginEventExampleVJ
import com.ms.wfc.data.*;

public class EventExampleVJ
{
    ConnectionEventHandler handler = new ConnectionEventHandler(this,"onConnectComplete");

    public void onConnectComplete(Object sender,ConnectionEvent e)
    {
        if (e.adStatus == AdoEnums.EventStatus.ERRORSOCCURRED)
            System.out.println("Connection failed");
        else
            System.out.println("Connection completed");
        return;
    }

    public static void main (String[] args)
    {
        EventExampleVJ Class1 = new EventExampleVJ();
        Connection conn = new Connection();

        conn.addOnConnectComplete(Class1.handler);     // Enable event support.
        conn.open("DSN=Pubs");
        conn.close();
        conn.removeOnConnectComplete(Class1.handler);  // Disable event support.
    }
}
// EndEventExampleVJ

首先，通过创建新的 ConnectionEventHandler 对象并将 onConnectComplete 函数指派给该对象，使类方法 onConnectionComplete 与 ConnectionComplete 事件相关联。

然后，main 函数创建 Connection 对象并通过调用 addOnConnectComplete 方法以及将 handler 函数的地址传递给它来启用事件处理。


VBScript

Microsoft Visual Basic Scripting Edition 不支持 ADO 事件


JScript

Microsoft JScript 不支持 ADO 事件。


ADO/WFC

ADO for Windows Foundation Classes (ADO/WFC) 建立在 ADO 事件模型上，提供简化的应用程序编程接口。通常，ADO/WFC 截取 ADO 事件，并将事件参数固定到单个事件类中，然后调用事件处理程序。

使用 ADO/WFC 中的 ADO 事件的步骤

  1. 定义自己的事件处理程序来处理事件。例如，当您要处理 ConnectionEvent 类中的 ConnectComplete 事件时，可使用下列代码：
    public void onConnectComplete(Object sender,ConnectionEvent e)
{
    System.out.println("onConnectComplete:" + e);
}
  2. 定义“处理程序”对象来表示事件处理程序。对于 ConnectionEvent 类型的事件，处理程序对象的数据类型应该是 ConnectEventHandler，而对于 RecordsetEven 类型的事件，处理程序对象的数据类型应该是 RecordsetEventHandler。例如，可以为 ConnectComplete 事件处理程序编写如下代码：
        ConnectionEventHandler handler =
        new ConnectionEventHandler(this, "onConnectComplete");

    ConnectionEventHandler 构造函数的第一个参数是对类的引用，该类包含第二个参数中命名的事件处理程序。

    Microsoft Visual J++ 编译器也支持等价的语法：

        ConnectionEventHandler handler =
        new ConnectionEventHandler(this.onConnectComplete);

    单个参数是对所需类（即 this）及该类中的方法（即 onConnectComplete）的引用。

  3. 将您的事件处理程序添加到用于处理特定类型事件的处理程序列表中。使用带 addOn EventName(handler) 名称的方法。
  4. ADO/WFC 在内部实现了所有 ADO 事件处理程序。因此，由 Connection 或 Recordset 操作引发的事件将被 ADO/WFC 事件处理程序截取。

    ADO/WFC 事件处理程序在 ADO/WFC ConnectionEvent 类的实例中传递 ADO ConnectionEvent 参数，或者在 ADO/WFC RecordsetEvent 类的实例中传递 ADO RecordsetEvent 参数。这些 ADO/WFC 类固定 ADO 事件参数，也就是说，对于所有 ADO ConnectionEvent 或 RecordsetEvent 方法中的每个唯一的参数，每个 ADO/WFC 类都包含一个对应的数据成员。

  5. 然后，ADO/WFC 通过 ADO/WFC 事件对象调用事件处理程序。例如，onConnectComplete 处理程序的声明如下：
        public void onConnectComplete(Object sender,ConnectionEvent e)

    第一个参数是发送事件的对象类型（Connection 或 Recordset），而第二个参数是 ADO/WFC 事件对象（ConnectionEvent 或 RecordsetEvent）。

    事件处理程序的声明比 ADO 事件简单。但是，您仍旧需要了解 ADO 事件模型，才能知道适用于事件的参数以及如何响应。

  6. 从事件处理程序返回到 ADO 事件的 ADO/WFC 处理程序。ADO/WFC 将通过复制把相关的 ADO/WFC 事件数据成员返回给 ADO 事件参数，然后 ADO 事件处理程序返回。
  7. 当处理结束时，从 ADO/WFC 事件处理程序列表上删除您的处理程序。使用名为 removeOn EventName(handler) 的方法。

请参阅

ADO 事件处理程序概要 | ADO/WFC 编程 | ADO/WFC 语法索引 | 事件参数 | 事件处理程序如何在一起工作 | 事件类型


第 8 章：理解游标和锁定

一定要了解游标是如何工作的，这样才能针对应用程序的数据访问需求选择最好和最有效的游标类型。如果游标配置不是最理想的，则会使数据访问操作相当缓慢。

ADO Recordset 对象的很多功能是由游标的类型和位置以及锁定类型决定的。

这一章包括以下主题：

  • 什么是游标？
  • 游标的类型
  • 游标位置的重要性
  • Microsoft Cursor Service for OLE DB
  • 什么是锁定？
  • 使用 CacheSize
  • 游标和锁定特征


什么是游标？

关系数据库中的操作是在完整的行集合上执行的。由 SELECT 语句返回的行集合包括满足该语句的 WHERE 子句所列条件的所有行。由该语句返回完整的行集合叫做结果集。应用程序，尤其是互动和在线应用程序，把完整的结果集作为一个单元处理并不总是有效的。这些应用程序需要一种机制来一次处理一行或连续的几行。而游标是对提供这一机制的结果集的扩展。

游标是通过游标库来实现的。游标库是常常作为数据库系统或数据访问 API 的一部分而得以实现的软件，用来管理从数据源返回的数据的属性（结果集）。这些属性包括并发管理、在结果集中的位置、返回的行数，以及是否能够在结果集中向前和/或向后移动（可滚动性）。

游标跟踪结果集中的位置，并允许对结果集逐行执行多个操作，在这个过程中可能返回至原始表，也可能不返回至原始表。换句话说，游标从概念上讲基于数据库的表返回结果集。由于它指示结果集中的当前位置 ，就像计算机屏幕上的光标指示当前位置一样，“游标”由此得名。

在继续向下进行，了解游标在 ADO 中的具体使用之前，熟悉游标的概念是很重要的。

使用游标，您可以：

  • 指定结果集中特定行的位置。
  • 基于当前的结果集位置检索一行或连续的几行。
  • 在结果集的当前位置修改行中的数据。
  • 对其他用户所做的数据更改定义不同的敏感性级别。

例如，假设一个应用程序对一名潜在购买者显示可供的产品列表。这名购买者在列表中滚动以查看产品细节和定价，他最后选择购买了一款产品。他又在列表的剩余产品中滚动查看并加以选择。对购买者而言，这些产品只出现一次，但应用程序需要使用可滚动游标在结果集中上下浏览。

可以多种方式使用游标：

  • 根本就没有行。
  • 某些行或所有行存储在一个单个表中。
  • 某些行或所有行来自逻辑上联接的表。
  • 作为在游标或字段水平上的只读或可更新游标。
  • 作为仅向前或完全可滚动游标。
  • 游标键集位于服务器上。
  • 对其他应用程序对基本表所做的更改（例如成员、排序、插入、更新和删除）敏感。
  • 存在于服务器或客户端。

只读游标帮助用户浏览结果集，读/写游标能够实现单个行的更新。复杂的游标可以使用指回到基本表行的键集来定义。有些游标是只能向前移动的只读游标，而其他游标能够来回移动，并且基于其他应用程序对数据库的更改提供对结果集的动态刷新。

并不是所有的应用程序都需要使用游标来访问或更新数据。某些查询并不需要使用游标直接更新行。游标应当是用来检索数据的最后几项技术选择之一，然后就应当尽可能选择影响最小的游标。当使用存储过程创建结果集时，就不能使用游标编辑或更新方法来更新该结果集。

并发

在某些多用户应用程序中，尽量保持呈现给最终用户的数据是最新数据，这一点至关重要。飞机订票系统就是此类系统的一个经典范例：许多用户会争先预订某个给定航班的同一个座位（这就是一个单个记录）。在这样的情况下，应用程序设计必须处理对某个单个记录的并发操作。

而在另一些应用程序中，并发操作就不那么重要了。在这些情况下，为保持数据始终都是最新数据而产生的费用就不是合理费用。

位置

游标还跟踪结果集中的当前位置。可以把游标位置视为指向当前位置的指针，就像数组索引指向数组中该特定位置的值一样。

可滚动性

应用程序所使用的游标类型还影响着在结果集中向前向后移动行的能力；这种能力有时被称作“可滚动性”。在结果集中向前 and 向后移动的能力增加了游标的复杂性，所以实现起来更为昂贵。因此，只需在必要时才要求具有此功能的游标。


游标的类型

作为一般规则，应用程序应当使用能够提供所需数据访问能力的最简单游标。超越基本功能（仅向前、只读、静态、滚动、非缓冲）的每项额外的游标特征都需要在客户端内存、网络负载或性能等方面付出代价。在很多情况下，默认的游标选项会生成超过应用程序实际需要的更复杂的游标。

对游标类型的选择取决于应用程序如何使用结果集，还取决于几个设计考虑事项，包括：结果集的大小、可能要用到的数据所占的百分比、对数据更改的敏感性、应用程序性能要求。

最基本的一点是，对选择的游标取决于是否需要更改数据还是只想查看数据：

  • 如果只需要翻看一组结果，而不更改数据，请使用仅向前或静态游标。
  • 如果有大型结果集并且只需选择少量行，请使用键集游标。
  • 如果想要用所有并发用户所进行的最新添加、更改和删除结果来同步结果集，请使用动态游标。

尽管每个游标类型似乎是明显不同的，但请记住，这些游标类型并没有很大的差异，而只是重叠的特征和选项所产生的结果。

请参阅

仅向前游标 | 静态游标 | 键集游标 | 动态游标


仅向前游标

典型的默认游标类型称为仅向前（即非可滚动）游标，这种游标只能在结果集中向前移动。仅向前游标不支持滚动（在结果集中向前移动和向后移动的功能）；它只支持从结果集中从头到尾获取行。使用某些仅向前游标（例如 SQL Server 游标库），当前用户所进行的（或由其他用户提交的）、会影响到结果集中的行的所有插入、更新和删除语句都将在获取行时可见。但是，由于游标无法向后滚动，获取数据库中的行之后对这些行所做的更改将在游标操作过程中不可见。

处理完当前行的数据之后，仅向前游标将释放用于持有该数据的资源。默认情况下，仅向前游标是动态的，就是说，所有更改都是在处理当前行时检测到的。这可以使游标打开速度更快，并使结果集能够显示对基本表所做的更新。

虽然仅向前游标不支持向后滚动，但应用程序仍然可以通过关闭和重新打开游标返回到结果集的开头。这对于处理少量数据是有效方式。另一种方式是，应用程序可以一次性读取结果集，再将数据缓存在本地，然后浏览本地数据缓存。

如果应用程序不需要在结果集中滚动，则仅向前游标是以较快速度和最少开销检索数据的最好方式。使用 adOpenForwardOnlyCursorTypeEnum 可以指示想要在 ADO 中使用仅向前游标。

请参阅

静态游标 | 键集游标 | 动态游标


静态游标

静态游标总是显示第一次打开该游标时的结果集。根据实现的不同，静态游标可能是只读，也可能是读/写，而且提供向前向后滚动功能。静态游标在打开后，通常并不检测对结果集的成员、顺序或值所做的更改。静态游标可能会检测自身的更新、删除和插入情况，尽管并不要求它们执行这样的检测。

静态游标从不检测其他的更新、删除和插入情况。例如，假设一个静态游标提取了一行，然后另一个应用程序更新了这一行。如果应用程序从该静态游标再提取该行，它所看到的值并不发生改变，尽管另一个应用程序已经更改了这行的值。所有的滚动类型都得到支持，但提供者可能支持书签，也可能不对书签提供支持。

如果应用程序不需要检测数据变化但需要滚动功能，那么静态游标就是最佳的选择。请使用 adOpenStatic CursorTypeEnum 来指示需要在 ADO 中使用静态游标。

请参阅

仅向前游标 | 键集游标 | 动态游标


键集游标

在检测更改的能力方面，键集游标提供了介于静态游标和动态游标之间的功能性。像静态游标一样，它不会始终检测成员身份和结果集顺序是否发生更改。像动态游标一样，它会检测结果集中行的值是否发生更改。

键集驱动的游标受一组唯一的标识符（唯一的标识符是“键”，组合起来叫做“键集”）控制。键是从一组可以唯一地标识结果集中的行的列而产生的。键集是一组键值，这些键值是从查询语句所返回的所有行中产生的。

使用键集驱动的游标，将在游标中为每个行产生和保存一个键，然后将这个键存储在客户端工作站或服务器上。访问每个行时，将使用所存储的键从数据源获取当前数据值。在键集驱动的游标中，当键集被填满时，将冻结结果集成员身份。因此，影响成员身份的添加或更新操作不是结果集的一部分，直到将它重新打开。

当用户在结果集中滚动定位时，由键集所有者或其他进程对数据值所做的更改将是可见的。只有当游标关闭并重新打开时，由其他进程从游标以外执行的插入才是可见的。在结果集末尾，可以见到从游标内部执行的插入。

键集驱动的游标试图检索已删除的行时，该行将作为结果集中的一个“漏洞”出现。这个行的键存在于键集中，但该行不再存在于结果集中。如果行中的键值被更新，则该行将被视为被删除然后再插入，因此这样的行也会作为漏洞出现在结果集中。键集驱动的游标总是能够检测到由其他进程删除的行，同时，它可以选择将由它自己删除的行的键删除掉。执行该操作的键集驱动游标无法检测它们自己的删除，因为证据已删除。

更新键列的操作与删除旧键然后插入新键相似。如果更新不是通过游标进行的，则新键值不可见。如果更新是通过游标进行的，则在结果集的末尾可以见到新键值。

在键集驱动的游标（称为键集驱动的标准游标）上存在一种变化。在键集驱动的标准游标中，当游标打开时，行在结果集中的成员身份和行的顺序是固定的，但由游标所有者对值进行的更改以及由其他进程所产生的已提交更改则是可见的。如果更改导致某行的成员身份不合格或影响了行的顺序，那么，除非将游标关闭并重新打开，否则，该行不会消失或移动。插入的数据不会出现，但是，对现有的数据的更改将在获取行时出现。

键集驱动的游标很难正确使用，因为对数据更改的敏感性取决于很多种不同的环境，上面的内容描述了这一点。但是，如果应用程序不关心并发更新，而且可以通过程序处理坏键，并且必须直接访问某些带有键的行，那么，键集驱动的游标可能对您有用。在 ADO 中，使用 adOpenKeyset CursorTypeEnum 可以指示您想使用键集游标。

请参阅

仅向前游标 | 静态游标 | 动态游标


动态游标

动态游标用于检测在结果集中对行所作的所有更改，不管更改是否发生在游标内部，或者是由游标以外的其他用户所作的更改。所有用户所提交的所有插入、更新和删除语句都会通过游标可见。打开游标之后，动态游标可以检测对结果集中的行、顺序和值所作的任何更改。游标以外所作的更新将不可见，直到这些更新被提交（除非游标事务隔绝等级设置为“不提交”）。

例如，假设动态游标获取了两个行和另一个应用程序，然后更新这些行中的某一行，并删除另一行。如果动态游标随后获取这些行，它将没找不到已删除的行，但它将显示已更新行的新值。

如果应用程序必须检测由其他用户所作的所有并发更新，则动态游标是较好的选择。使用 adOpenDynamic CursorTypeEnum 可以指示想要在 ADO 中使用动态游标。

仅向前游标 | 静态游标 | 键集游标


游标位置的重要性

每个游标都使用临时资源来持有其数据。这些资源可以是内存、磁盘分页文件、临时磁盘文件，甚至是数据库中的临时存储区。当这些资源位于客户端计算机上时，游标称为“客户端”游标。当这些资源位于服务器上时，游标称为“服务器端”游标。

客户端游标

在 ADO 中，通过使用 adUseClient CursorLocationEnum 来调用客户端游标。利用非键集的客户端游标，服务器将整个结果集通过网络发送给客户端计算机。客户端计算机提供并管理游标和结果集所需要的临时资源。客户端应用程序可以浏览整个结果集，以确定它需要哪些行。

如果静态的和键集驱动的客户端游标包括的行数太多，那么，这些游标可能给工作站带来较沉重的负载。由于所有游标库都能够生成包含数千行的游标，所以，为获取大量行集而设计的应用程序有可能性能不佳。当然，也会有例外。对于某些应用程序来说，大型客户端游标可能完美好用，并且性能可能不成问题。

客户端游标的一个显然的好处是快速响应能力。结果集已下载到客户端计算机之后，浏览所有行的速度会非常快。一般来说，如果使用客户端游标，应用程序的可伸缩性更好，这是因为游标对资源的需求由每个单独的客户端而不是服务器来解决。

服务器端游标

在 ADO 中，通过使用 adUseServer CursorLocationEnum 来调用服务器端游标。通过服务器端游标，服务器使用由服务器计算机所提供的资源来管理结果集。服务器端游标只通过网络返回所请求的数据。该类型的游标有时可以提供比客户端游标更好的性能，尤其是存在过度拥挤的网络通信问题时。

但必须指出的是，对于每个活动客户端来说，服务器端游标很容易耗费宝贵的服务器资源（至少目前是这样）。因此，必须相应地进行计划，确保服务器硬件能够管理活动客户端所请求的所有服务器端游标。另外，服务器端游标速度缓慢，因为它只提供单行访问，就是说，没有批游标可用。

当插入、更新或删除记录时，服务器端游标是有用的。使用服务器端游标，在同一个连接上就可以有多个活动语句。


Microsoft Cursor Service for OLE DB

选择客户端游标时，或将 CursorLocation 属性设置为 adUseClient 时，即是在调用 Microsoft Cursor Service for OLE DB。您可能还会看到对“客户端游标引擎”的引用，在 ADO 上下文中，“客户端游标引擎”是本质上相同的事物。该服务补充了数据提供者的游标支持函数。因此，用户可以从所有数据提供者处获得相对统一的功能。

Cursor Service for OLE DB 使动态属性可用，并增强了某些方法的行为。例如，Optimize 动态属性允许创建临时索引以方便执行某些操作，如 Find 方法。

Cursor Service 允许支持各种情况的批更新。当数据提供者只能提供功能较少的游标（如静态游标）时，批更新可以模拟功能较多的游标类型（如动态游标）。

请参阅

Microsoft Cursor Service for OLE DB

© 1998-2003 Microsoft Corporation。保留所有权利。


什么是锁定？

锁定是一种进程，DBMS 通过该进程限制多用户环境中对行的访问。当一行或一列被独占锁定时，不允许其他用户在释放锁定之前访问锁定的数据。这确保了两个用户无法同时更新一行中的同一列。

从资源角度而言，锁定的成本可能非常高昂，只有在需要保持数据完整性的情况下才应当使用此功能。在每秒有数百或数千用户试图访问某个记录的数据库（例如连接到 Internet 的数据库）中，不必要的锁定将很快导致应用程序性能的下降。

可选择适当的锁定选项来控制数据源和 ADO 游标库管理并发性的方式。

打开 Recordset 之前先设置 LockType 属性，以指定提供者打开它时使用的锁定类型。读取该属性以返回打开的 Recordset 对象中使用的锁定类型。

提供者可能不支持所有锁定类型。如果提供者不支持请求的 LockType 设置，则替换为另一种锁定类型。若要确定 Recordset 对象中实际可用的锁定功能，请将 Supports 方法与 adUpdate 和 adUpdateBatch 一起使用。

如果 CursorLocation 属性设置为 adUseClient，则不支持 adLockPessimistic 设置。如果设置了不支持的值，将不产生错误，而使用所支持的最相近的 LockType。

LockType 属性在 Recordset 关闭时为读/写，而在 Recordset 打开时为只读。


锁定类型

adLockBatchOptimistic

指示开放式批更新。需要批更新模式。

许多应用程序都一次提取多行，然后需要进行相应的更新，这些更新包括所有需要插入、更新或删除的行的完整集合。使用批游标只需一次往返服务器，因而导致更新性能的提高和网络通信量的降低。使用批游标库可创建静态游标，然后断开到数据源的连接。这时就可以对行进行更改，然后重新连接到数据源并将更改以批的形式发布到数据源。

adLockOptimistic

提供者使用开放式锁定，仅在调用 Update 方法时锁定记录。这意味着另一个用户有可能会利用您编辑记录和调用 Update 的时间间隔更改数据，这就会引起冲突。而使用此锁定类型时发生冲突的几率很低，即使发生了冲突也会很快得到解决。

adLockPessimistic

指示逐个记录保守式锁定。提供者要确保记录编辑成功，通常在编辑之前立即在数据源锁定记录。当然，这意味着一旦您开始编辑记录，这些记录就会对其他用户不可用，知道您通过调用 Update 释放锁定。如果您的系统不提供对数据的并发更改，例如预定系统，那么可使用此锁定类型。

adLockReadOnly

指示只读记录。无法改变数据。只读锁定是速度“最快”的锁定类型，因为它不要求服务器保持对记录的锁定。

adLockUnspecified

未指定锁定类型。


使用 CacheSize

使用 CacheSize 属性可以控制一次要从提供者那里将多少个记录检索到本地内存中。例如，如果 CacheSize 为 10，首次打开 Recordset 对象后，提供者将把前 10 个记录检索到本地内存。在 Recordset 对象中移动时，提供者将从本地内存缓冲区返回数据。 一旦移动超过缓存中的最后一个记录，提供者便将数据源中随后的 10 个记录检索到缓存中。

注意 CacheSize 是基于提供者特有的 Maximum Open Rows 属性的（该属性在 Recordset 对象的 Properties 集合中）。不能将 CacheSize 设置为大于 Maximum Open Rows 的值。若要修改可以由提供者打开的行数，请设置 Maximum Open Rows。

可以在 Recordset 对象的存活期内调整 CacheSize 的值，但是更改该值只会影响随后从数据源检索到缓存的记录数。只更改属性值将不会更改缓存中的当前内容。

如果要检索的记录比 CacheSize 指定的少，提供者将返回剩余的记录而不会产生错误。

不允许将 CacheSize 设置为零，否则将返回错误。

从缓存检索到的记录并不反映其他用户对源数据所作的并发更改。若要强行更新所有缓存数据，请使用 Resync 方法。

如果将 CacheSize 设置为大于 1 的值，则定位方法（Move、MoveFirst、MoveLast、MoveNext 和 MovePrevious）可能导致导航操作删除记录（如果删除发生在检索到记录之后）。除非试图访问已删除的行中的数据值，当完成最初的提取后，随后的删除将不会反映到数据缓存中。但是，因为无法提取已删除的行，所以将 CacheSize 设置为 1 可解决此问题。


游标和锁定特征

虽然游标的特征取决于提供者的能力而各不相同，但以下优点和缺点通常适用于各种类型的游标和锁定。

游标或锁定类型 优点 缺点
adOpenForwardOnly
  • 资源需求较低
  • 无法向后滚动
  • 无数据并发
adOpenStatic
  • 可滚动
  • 无数据并发
adOpenKeyset
  • 部分数据并发
  • 可滚动
  • 资源需求较高
  • 在连接断开的情形下不可用
adOpenDynamic
  • 高数据并发
  • 可滚动
  • 资源需求较高
  • 在连接断开的情形下不可用
adLockReadOnly
  • 资源需求较低
  • 可伸缩性较高
  • 不能通过游标更新数据
adLockBatchOptimistic
  • 批更新
  • 允许连接断开情形
  • 其他用户能够访问数据
  • 数据可以由多个用户同时更改
adLockPessimistic
  • 数据锁定时，该数据无法被其他用户更改
  • 数据锁定时，其他用户无法访问该数据
adLockOptimistic
  • 其他用户能够访问数据
  • 数据可以被多个用户同时更改


第 9 章：数据构形

“数据构形”提供了一种查询数据源并返回 Recordset 的方法，该 Recordset 表示两个或多个逻辑项目之间的父子关系（一个分级结构）。分级关系的经典范例是客户和订单。数据库中的每位客户都可以有零或多张订单。常用的 SQL 提供了一种使用 JOIN 语法检索数据的方法，但是这种方法可能效率不高且不实用，因为对于给定的父子关系，每个返回的记录中都会重复父数据。数据构形可以使父 Recordset 中的单个父记录与子 Recordset 中的多个子记录建立联系，从而避免了 JOIN 的冗余度。大多数人查找父子多 Recordset 编程模型比使用单个 Recordset JOIN 模型更加自然和容易。

数据构形语法还提供了其他功能。通过使用 NEW 关键字描述父和子 Recordsets 的字段，开发人员可以创建没有基本数据源的新 Recordset 对象。新的 Recordset 对象可以用数据进行预置，并且可以持久存储。开发人员还可以在子字段上进行各种计算或合计（例如，SUM、AVG 或者 MAX）。数据构形还可以从子 Recordset 中创建父 Recordset，方法是分组子中的记录，然后将每组的父中的一行放置在子中。

有关数据构形的详细信息，请参阅下列主题：

  • 数据构形汇总
  • 数据构形所需的提供者
  • 常规构形命令
  • Shape APPEND 子句
  • Shape COMPUTE 子句
  • 虚构分级记录集
  • 访问分级 Recordset 中的行
  • 规范构形语法
  • Visual Basic for Applications 函数


数据构形汇总

下面的内容描述了数据构形、分级记录集、重构形、孙子合计、参数化构形，以及将构形保存到文件的概念。

  • 数据构形
  • 重构形
  • 孙子合计
  • 使用包含 COMPUTE 命令的参数化命令
  • 持久保留分级记录集


数据构形

数据构形使用户能够定义成形 Recordset 的列、由列表示的项目之间的关系以及用数据预置 Recordset 的方式。

成形 Recordset 的列可以包含来自数据提供者（如 Microsoft SQL Server）的数据、对另一个 Recordset 的引用、对 Recordset 的一行进行计算得到的值、对完整 Recordset 中的某列进行操作得到的值或者新虚构的空列。

当您检索引用另一个 Recordset 的列的值时，ADO 会自动返回引用所表示的实际 Recordset。包含另一个 Recordset 的 Recordset 被称为分级记录集。分级记录集展示了“父子”关系，其中“父”包含记录集，而“子”是被包含的记录集。对 Recordset 的引用实际是对子的子集合（称为“子集”）的引用。单个父可以引用多个子 Recordset。

构形命令语法使用户可以通过编程来创建成形的 Recordset。然后，可以通过程序或适当的可视控件来访问 Recordset 的组件。可以象发出任何其他 ADO 命令文本一样发出构形命令。

通过构形命令语法可以用两种方法创建分级 Recordset 对象。第一种方法是将子 Recordset 追加到父 Recordset 中。通常，父和子至少具有一个公用列：父的一行中的列值与子的所有行的列值相同。

第二种方法是从子 Recordset 生成父 Recordset。一般通过使用 BY 子句将子 Recordset 中的记录分组，并且将一行添加到子中每个结果组的父 Recordset 中。如果省略 BY 子句，则子 Recordset 将构成一个单独的组并且父 Recordset 将恰好包含一行。在计算整个子 Recordset 的“总计”计算时，这种方法十分有用。

不管父 Recordset 的构成方式如何，它都将包含用于将其与子 Recordset 相关联的子集列。如果您愿意的话，父 Recordset 还可以有在子行上包含合计（SUM、MIN、MAX 等）的列。父和子 Recordset 都可以拥有在 Recordset 的行上包含表达式的列，以及新的并初始为空的列。

可将分级 Recordset 对象嵌套到所需的任何深度（即创建子 Recordset 对象的子 Recordset 对象，依此类推）。

也可以通过编程或适当的可视控件访问成形 Recordset 的 Recordset 组件。

Microsoft 提供了一个能够生成构形命令的可视工具（请参阅 Visual Basic 文档中的“数据环境设计者”）和一个能够显示分级游标的可视工具（请参阅 Visual Basic 文档中的“使用 Microsoft Hierarchical Flexgrid Control”）。

有关构形命令及其结果分级的范例，请参阅“Using the Data Shaping Service for OLE DB: A Closer Look”。


重构形

可以为由构形命令的子句创建的 Recordset 分配一个“别名”（通常使用 AS 关键字）。成形的 Recordset 的别名可以在完全不同的命令中引用。这就是说，您可以在新的构形命令中重新使用（或“重构形”）以前的成形 Recordset。为了支持此功能，ADO 提供了 Reshape Name 属性。

重构形有两个主要功能。第一个功能是将现有 Recordset 与新的父 Recordset 相关联。

范例

. . .
rs1.Open "SHAPE {select * from Customers} " & _
         "APPEND ({select * from Orders} AS chapOrders " & _
         "RELATE CustomerID to CustomerID)", cn

rs2.Open "SHAPE {select * from Employees} " & _
         "APPEND (chapOrders RELATE EmployeeID to EmployeeID)", cn
. . .

第二个功能是用“SHAPE <记录集重构形名称>”语法启用对现有子 Recordset 对象的非子集访问。

注意 不能将列追加到现有的 Recordset中，也不能在任何内含的 COMPUTE 子句中对参数化 Recordset 或 Recordset 对象进行重构形，或者对从正在被重构形的 Recordset 中派生而来的任何 Recordset 进行合计操作。正在被重构形的 Recordset 和新的构形命令都必须使用相同的 Connection。

请参阅

数据构形


孙子合计

可以为在构形命令的子句中创建的子集列指定一个“子集别名”（通常使用 AS 关键字）。可以在任何子集中标识成形 Recordset 的任何列，方法是使用标识包含该列的子的完整名称。例如，如果父子集 chap1 包含子集 chap2，并且子集 chap2 具有数量列 amt，那么完整的名称是 chap1.chap2.amt。然后，完整名称可以用作某个合计函数（SUM、AVG、MAX、MIN、COUNT、STDEV 或 ANY）的参数。

请参阅

数据构形


使用包含

ADO 2.5

使用包含 COMPUTE 命令的参数化命令

典型的参数化构形 APPEND 命令有两个子句，一个子句通过查询命令创建父 Recordset，另一个子句通过参数化查询命令创建子 Recordset。参数化查询命令是指包含参数占位符（问号“?”）的命令。最终得到的成形 Recordset 具有两层，其中父占据上层，子占据下层。

现在，创建子 Recordset 的子句可以是任意数量的嵌套构形 COMPUTE 命令，其中嵌套最深的命令包含参数化查询。最终得到的成形 Recordset 具有多层，其中父占据最上层，子占据最下层。而由构形 COMPUTE 命令生成的任意数量的 Recordset 占据中间层。

此功能的典型用法是调用合计函数和构形 COMPUTE 命令的分组能力，创建带有子 Recordset 解析信息的中间 Recordset 对象。此外，由于这是一个参数化构形命令，因此每次访问父的一个子集列时，都会检索新的子 Recordset。因为中间层来源于子，所以它们也将被重新计算。

请参阅

数据构形


持久保留分级记录集

通过调用 Save 方法，可以将分级 Recordset 以 ADTG 或 XML 格式保存到文件中。但是，在以 XML 格式保存分级 Recordset 时有两个限制条件：如果分级 Recordset 包含挂起的更新，则不能以 XML 格式保存，也不能以此格式保存参数化的分级 Recordset。

有关数据构形提供者的详细信息，请参阅 Microsoft Data Shaping Service for OLE DB 和 Data Shaping Service for OLE DB。

请参阅

数据构形 | 规范构形语法 | 常规构形命令


数据构形所需的提供者

数据构形通常需要两个提供者。服务提供者 Data Shaping Service for OLE DB 和数据提供者（例如 OLE DB Provider for SQL Server），前者提供数据构形功能，后者提供数据行以预置成形的 Recordset。

服务提供者 (MSDataShape) 的名称可被指定为 Connection 对象的 Provider 属性或连接字符串关键字的值，“Provider=MSDataShape;”。

数据提供者的名称可被指定为 Data Provider 动态属性的值（该动态属性由 Data Shaping Service for OLE DB 添加到 Connection 对象的 Properties 集合）；或者是连接字符串关键字的值，“Data Provider=provider”。

如果没有预置 Recordset，则不需要数据提供者（例如，在虚构的 Recordset 中，列是通过使用 NEW 关键字创建的）。在这种情况下，请指定“Data Provider=none;”。

范例

Dim cnn As New ADODB.Connection
cnn.Provider = "MSDataShape"
cnn.Open "Data Provider=SQLOLEDB;Integrated Security=SSPI;Database=Northwind"

请参阅

数据构形 | 规范构形语法 | 常规构形命令


常规构形命令

数据构形定义了成形 Recordset 的列、由列表示的项目之间的关系以及用数据预置 Recordset 的方式。

成形 Recordset 可以由下列类型的列组成：

列的类型 | 说明
data | 字段，来自对数据提供者、表或以前的成形 Recordset 使用查询命令所返回的 Recordset。
chapter | 对另一个 Recordset 的引用，称为“子集”。子集列可以定义“父子”关系，其中“父”是包含子集列的 Recordset，“子”是由子集表示的 Recordset。
aggregate | 列的值，通过对子 Recordset 的所有行或者所有行的一列执行“合计函数”获得。（请参阅下列合计函数、CALC 函数和 NEW 关键字主题中的“合计函数”。）
calculated expression | 列的值，通过在 Recordset 同一行中的列上计算 Visual Basic for Applications 表达式而获得。此表达式是 CALC 函数的参数。（请参阅下列合计函数、CALC 函数和 NEW 关键字主题中的以及 Visual Basic for Applications 函数中的“计算表达式”。）
new | 虚构的空字段，可在以后预置数据。使用 NEW 关键字定义列。（请参阅下列合计函数、CALC 函数和 NEW 关键字主题中的“NEW 关键字”。）

构形命令可以包含子句，指定对将要返回 Recordset 对象的基本数据提供者执行的查询命令。查询的语法取决于基本数据提供者的要求。虽然 ADO 不需要使用任何特定的查询语言，但通常使用结构化查询语言 (SQL)。

可以用 SQL JOIN 子句关联两个表。但是，分级 Recordset 可以更有效地表示信息。由 JOIN 创建的每一行 Recordset 都会冗余地重复一个表中的信息。对于每一个多子 Recordset 对象，分级 Recordset 都只包含一个父 Recordset。

构形命令可以通过 Recordset 对象发出，也可以通过设置 Command 对象的 CommandText 属性，然后调用 Execute 方法来发出。

构形命令可以嵌套。即 parent-command 或 child-command 本身可以是另一个构形命令。

即使用户指定了 adUseServer 的游标位置，构形提供者总返回客户端游标。

有关定位分级 Recordset 的详细信息，请参阅访问分级 Recordset 中的行。

有关语法正确的构形命令的详细信息，请参阅规范构形语法。


合计函数、CALC 函数和 NEW 关键字

数据构形支持以下函数。分配给包含要操作的列的子集的名称是 chapter-alias（子集别名）。

子集别名可以是完全确定的，由指向包含 column-name 的子集的每个子集列名称组成，并且全部用句点分隔。例如，如果父子集 chap1 包含子集 chap2（具有数量列 amt），那么完整的名称将是 chap1.chap2.amt。

合计函数 | Description
SUM(chapter-alias.column-name) | 计算指定列中所有值的和。
AVG(chapter-alias.column-name) | 计算指定列中所有值的平均值。
MAX(chapter-alias.column-name) | 计算指定列中的最大值。
MIN(chapter-alias.column-name) | 计算指定列中的最小值。
COUNT(chapter-alias[.column-name]) | 计算指定别名的列中的行数。如果指定了列，则只在计算中包括其列非 Null 的行。
STDEV(chapter-alias.column-name) | 计算指定列中的标准偏差。
ANY(chapter-alias.column-name) 指定的列的值。只有当子集中所有行的列值相同时，ANY 才会有可预言的值。
注意 如果子集中所有行的列值不相同，则 SHAPE 命令将任意返回一个值作为 ANY 函数的值。
计算表达式 | 说明
CALC(expression) | 计算任意表达式，但是只针对包含 CALC 函数的 Recordset 的行。允许任何使用这些 Visual Basic for Applications (VBA) 函数的表达式。
NEW 关键字 | 说明
NEW field-type [(width | scale | precision | error [, scale | error])] | 向 Recordset 添加指定类型的空列。

通过 NEW 关键字传递的 field-type 可以是下列任何一种数据类型。

OLE DB 数据类型 | 等价于 ADO 数据类型
DBTYPE_BSTR | adBSTR
DBTYPE_BOOL | adBoolean
DBTYPE_DECIMAL | adDecimal
DBTYPE_UI1 | adUnsignedTinyInt
DBTYPE_I1 | adTinyInt
DBTYPE_UI2 | adUnsignedSmallInt
DBTYPE_UI4 | adUnsignedInt
DBTYPE_I8 | adBigInt
DBTYPE_UI8 | adUnsignedBigInt
DBTYPE_GUID | adGuid
DBTYPE_BYTES | adBinary, AdVarBinary, adLongVarBinary
DBTYPE_STR | adChar, adVarChar, adLongVarChar
DBTYPE_WSTR | adWChar, adVarWChar, adLongVarWChar
DBTYPE_NUMERIC | adNumeric
DBTYPE_DBDATE | adDBDate
DBTYPE_DBTIME | adDBTime
DBTYPE_DBTIMESTAMP | adDBTimeStamp
DBTYPE_VARNUMERIC | adVarNumeric
DBTYPE_FILETIME | adFileTime
DBTYPE_ERROR | adError

当新字段为十进制类型时（在 OLE DB 中为 DBTYPE_DECIMAL，或者在 ADO 中为 adDecimal），必须指定精度和范围值。

请参阅

数据构形 | 正式构形语法 | 常规构形命令


向基本数据提供者发出命令

任何不是以 SHAPE 开始的命令都会传递给数据提供者。这等价于以“SHAPE {provider command}”形式发出构形命令。这些命令不必产生 Recordset。例如，假定数据提供者支持 DROP TABLE，则“SHAPE {DROP TABLE MyTable}”将是完全有效的构形命令。

此功能允许普通提供者命令和构形命令共享相同的连接和事务。

请参阅

数据构形 | 规范构形语法 | 常规构形命令


Shape APPEND 子句

构形命令的 APPEND 子句向 Recordset 追加一个或多个列。通常，这些列是引用子 Recordset 的子集列。

语法

SHAPE [parent-command [[AS] parent-alias]] APPEND column-list

说明

该子句的组成部分如下：

parent-command
零或下列内容之一（可以完全忽略 parent-command）：
  • 花括号（“{}”）中的提供者命令，返回 Recordset 对象。此命令向基本数据提供者发出，其语法取决于该提供者的要求。虽然 ADO 不要求使用任何特定的查询语言，但通常使用 SQL 语言。
  • 嵌入括号中的另一个构形命令。
  • TABLE 关键字，后跟数据提供者中的表名。
parent-alias
引用父 Recordset 的可选别名。
column-list
可以是下列内容的一个或多个：
  • 合计列。
  • 已计算的列。
  • 用 NEW 子句创建的新列。
  • 子集列。子集列定义用括号（“()”）括起来。请参阅以下语法：
SHAPE [parent-command [[AS] parent-alias]]
   APPEND (child-recordset [ [[AS] child-alias]
      RELATE parent-column TO child-column | PARAMETER param-number, ... ])
   [[AS] chapter-alias]
   [, ... ]
child-recordset
  • 花括号（“{}”）中的提供者命令，返回 Recordset 对象。此命令向基本数据提供者发出，其语法取决于该提供者的要求。虽然 ADO 不要求使用任何特定的查询语言，但通常使用 SQL 语言。
  • 嵌入括号中的另一个构形命令。
  • 现有的成形 Recordset 的名称。
  • TABLE 关键字，后跟数据提供者中的表名。
child-alias
别名，引用子 Recordset。
parent-column
由 parent-command 返回的 Recordset 中的列。
child-column
由 child-command 返回的 Recordset 中的列。
param-number
请参阅参数化命令的操作
chapter-alias
别名，引用追加到父的子集列。
注意 “parent-column TO child-column”子句实际上是一个列表，其中定义的每个关系均用逗号分隔开。
注意 APPEND 关键字之后的子句实际上是一个列表，其中每个子句均用逗号分隔开并且定义追加到父的另一列。

说明

当将用户输入的提供者命令构造为 SHAPE 命令的一部分时，SHAPE 将把用户提供的提供者命令视作不透明字符串并将其如实地传递给提供者。例如，在以下 SHAPE 命令中，

SHAPE {select * from t1} APPEND ({select * from t2} RELATE k1 TO k2)

SHAPE 将执行两个命令：select * from t1 和 (select * from t2 RELATE k1 TO k2)。如果用户提供了复合命令（包含由分号分隔开的多个提供者命令），则 SHAPE 将无法辨别差异。因此在以下 SHAPE 命令中，

SHAPE {select * from t1; drop table t1} APPEND ({select * from t2} RELATE k1 TO k2)

SHAPE 执行 select * from t1; drop table t1 和 (select * from t2 RELATE k1 TO k2)，并没有意识到在这种情况下 drop table t1 是单独的危险的提供者命令。应用程序必须始终验证用户输入以阻止潜在的黑客攻击。

说明

当将用户输入的提供者命令构造为 SHAPE 命令的一部分时，SHAPE 将把用户提供的提供者命令视作不透明字符串并将其如实地传递给提供者。例如，在以下 SHAPE 命令中，

SHAPE {select * from t1} APPEND ({select * from t2} RELATE k1 TO k2)

SHAPE 将执行两个命令：select * from t1 和 (select * from t2 RELATE k1 TO k2)。如果用户提供了复合命令（包含由分号分隔开的多个提供者命令），则 SHAPE 将无法辨别差异。因此在以下 SHAPE 命令中，

SHAPE {select * from t1; drop table t1} APPEND ({select * from t2} RELATE k1 TO k2)

SHAPE 执行 select * from t1; drop table t1 和 (select * from t2 RELATE k1 TO k2)，并没有意识到在这种情况下 drop table t1 是单独的危险的提供者命令。应用程序必须始终验证用户输入以阻止潜在的黑客攻击。

请参阅

数据构形 | 规范构形语法 | 常规构形命令


非参数化命令的操作

对于非参数化命令来说，所有提供者命令都会执行并在命令执行期间创建 Recordsets。如果同步执行命令，则所有 Recordsets 将被填满。如果选择异步填充模式，则 Recordsets 的填充状态将取决于填充模式和 Recordsets 的大小。

例如，parent-command 可以从 Customers 表返回公司的客户 Recordset，而 child-command 可以从 Orders 表返回所有客户的定单 Recordset。

SHAPE {SELECT * FROM Customers}
   APPEND ({SELECT * FROM Orders} AS chapOrders
   RELATE customerID TO customerID)

对于非参数化的父子关系，每个父和子 Recordset 对象都必须有一个使它们彼此关联的公共列。列在 RELATE 子句中命名，先命名 parent-column 然后命名 child-column。在其各自的 Recordset 对象中，列可能有不同名称，但为了指定有意义的关系，列必须引用相同的信息。例如，Customers 和 Orders Recordset 对象都可以包含 customerID 字段。由于子 Recordset 的成员身份是由提供者命令确定的，所以子 Recordset 可能包含孤儿行。如果不进一步重新构形，这些孤儿行是不可访问的。

数据构形向父 Recordset 追加子集列。子集列中的值是对子 Recordset 中的行的引用，该子 Recordset 满足 RELATE 子句。就是说，在给定父行的 parent-column 中与在子集孩子的所有行的 child-column 中有相同的值。当在同一个 RELATE 子句中使用多个 TO 子句时，它们将通过 AND 操作符隐式组合。如果相关子句中的父列没有构成父 Recordset 的键，那么，一个子行可能有多个父行。

当访问子集列中的引用时，ADO 自动检索由该引用所表示的 Recordset。请注意在非参数化命令中，尽管已经检索了整个子 Recordset，但是 chapter 仍只表示行的子集。

如果追加的列没有 chapter-alias，将会自动为该列生成一个名称。将把列的 Field 对象追加大批 Recordset 对象的 Fields 集合，并且其数据类型将是 adChapter。

有关定位分级 Recordset 的详细信息，请参阅访问分级 Recordset 中的行。

请参阅

数据构形 | 规范构形语法 | 常规构形命令


参数化命令的操作

如果您正在处理大的子 Recordset（尤其是与父 Recordset 相比），但只需要访问几个子子集，那么，使用参数化命令将会更有效。

“非参数化命令”同时检索整个父和子 Recordsets，并将子集列追加到父，然后为每个父行分配相关子子集的引用。

参数化命令将检索整个父 Recordset，但在访问子集列时只检索子集 Recordset。这种检索策略的差异有助于显著提高性能。

例如，可以指定下列命令：

SHAPE {SELECT * FROM customer}
   APPEND ({SELECT * FROM orders WHERE cust_id = ?}
   RELATE cust_id TO PARAMETER 0)

父表和子表有一个共同的列名 cust_id。child-command 有一个“?”占位符，而 RELATE 子句将引用它（即 “...PARAMETER 0”）。

注意 PARAMETER 子句单独地属于构形命令语法。它与 ADO Parameter 对象或 Parameters 集合没有关联。

在执行参数化构形命令时，将发生如下情况：

  1. 执行 parent-command，并从 Customers 表返回一个父 Recordset。
  2. 子集列被追加到父 Recordset。
  3. 访问父行的子集列时，child-command 在执行时将使用 customer.cust_id 的值作为参数值。
  4. 将用在步骤 3 中所创建的数据提供者行集中的所有行来填充子 Recordset。在该范例中，这就是在 Orders 表中 cust_id 等于 customer.cust_id 值的所有行。默认情况下，子 Recordset 将缓存在客户端，直到对父 Recordset 的所有引用被释放。若要更改此行为，请将 Recordset 动态属性 Cache Child Rows 设置为 False。
  5. 对已检索的子行（即子 Recordset 的“子集”）的引用被放置在父 Recordset 的当前行的子集列中。
  6. 当访问另一行的子集列时，重复步骤 3-5。

默认情况下，Cache Child Rows 动态属性被设置为 True。缓存行为根据查询的参数值不同而有所变化。在使用单个参数的查询中，将在请求具有该值的子对象操作之间缓存给定参数值的子 Recordset。下列代码演示了这种情况：

...
SCmd = "SHAPE {select * from customer} " & _
         "APPEND({select * from orders where cust_id = ?} " & _
         "RELATE cust_id TO PARAMETER 0) AS chpCustOrder"
Rst1.Open sCmd, Cnn1
Set RstChild = Rst1("chpCustOrder").Value
Rst1.MoveNext      ' Next cust_id passed to Param 0, & new rs fetched
                   ' into RstChild.
Rst1.MovePrevious  ' RstChild now holds cached rs, saving round trip.
...

在具有两个或更多个参数的查询中，只有当所有参数值都与缓存值相匹配时才使用已缓存的子。

参数化命令和复杂的父子关系

除了使用参数化命令来提高 equi-join 类型层次结构的性能以外，参数化命令还可以用来支持更复杂的父子关系。例如，假设有一个小的联盟数据库，该数据库有两个表：一个由工作组组成（team_id、team_name）另一个由游戏组成（date、home_team、visiting_team）。

使用非参数化层次结构，将无法以每个工作组的子 Recordset 包含其完成计划的方式来使工作组和游戏表相关。可以创建一个子集，使之包含主计划或路线计划，但不同时包含这两者。这是因为 RELATE 子句将您限制于形式为 (pc1=cc1) AND (pc2=pc2) 的父子关系。因此，如果命令包括了“RELATE team_id TO home_team, team_id TO visiting_team”，则只会获得工作组自己正在玩的游戏。您想要的是“(team_id=home_team) OR (team_id=visiting_team)”，但构形提供者不支持 OR 子句。

若要获得希望的结果，可以使用参数化命令。例如：

SHAPE {SELECT * FROM teams}
APPEND ({SELECT * FROM games WHERE home_team = ? OR visiting_team = ?}
        RELATE team_id TO PARAMETER 0,
               team_id TO PARAMETER 1)

该范例利用 SQL WHERE 子句的更大灵活性来获得需要的结果。

请参阅

数据构形 | 规范构形语法 | 常规构形命令


混合命令

混合命令是部分参数化的命令。例如：

SHAPE {select * from plants}
   APPEND( {select * from customers where country = ?}
           RELATE PlantCountry TO PARAMETER 0,
             PlantRegion TO CustomerRegion )

混合命令的缓存行为与常规参数化命令的缓存行为相同。

请参阅

数据构形 | 规范构形语法 | 常规构形命令


插入 Shape COMPUTE 子句

在参数化构形命令中的父和子之间嵌入一个或多个 COMPUTE 子句是有效的，如以下范例所示：

SHAPE {select au_lname, state from authors} APPEND
   ((SHAPE
      (SHAPE
         {select * from authors where state = ?} rs
      COMPUTE rs, ANY(rs.state) state, ANY(rs.au_lname) au_lname
      BY au_id) rs2
   COMPUTE rs2, ANY(rs2.state) BY au_lname)
RELATE state TO PARAMETER 0)

请参阅

数据构形 | 规范构形语法 | 常规构形命令


Shape COMPUTE 子句

Shape COMPUTE 子句生成父 Recordset（其列由对子 Recordset 的引用组成）、可选的列（其内容是子集列、新列或计算列，或者是对子 Recordset 或以前的成形 Recordset 执行合计函数的结果）和在可选的 BY 子句中列出的子 Recordset 的任何列。

语法

SHAPE child-command [AS] child-alias
   COMPUTE child-alias [[AS] name], [appended-column-list]
   [BY grp-field-list]

说明

该子句的组成部分如下：

child-command
包含下列内容之一：
  • 花括号（“{}”）中的查询命令，返回子 Recordset 对象。此命令向基本数据提供者发出，其语法取决于该提供者的要求。虽然 ADO 不要求使用任何特定的查询语言，但通常使用 SQL 语言。
  • 现有的成形 Recordset 的名称。
  • 另一个构形命令。
  • TABLE 关键字，后跟数据提供者中的表名。
child-alias
别名，引用由 child-command 返回的 Recordset。在 COMPUTE 子句的列的列表中需要 child-alias，它定义了父和子 Recordset 对象之间的关系。
appended-column-list
列表，其中每个元素定义了所生成的父中的一个列。每个元素包含子集列、新列、计算列，或者由子 Recordset 上的合计函数产生的值。
grp-field-list
父和子 Recordset 对象中的列的列表，指定行在子中的分组方式。

对于 grp-field-list 中的每一列，在子和父 Recordset 对象中都有一个相对应的列。对于父 Recordset 中的每一行，grp-field-list 列具有唯一的值，而被父行引用的子 Recordset 只包含其 grp-field-list 列与父行具有相同值的子行。

如果包含 BY 子句，则子 Recordset 的行将基于 COMPUTE 子句中的列来分组。父 Recordset 将为每一子 Recordset 中的行组包含一行。

如果省略 BY 子句，则整个子 Recordset 将被视为单个组并且父 Recordset 将只包含一行。该行将引用整个子 Recordset。省略 BY 子句允许您计算整个子 Recordset 上的“总计”合计。

例如：

SHAPE {select * from Orders} AS orders
   COMPUTE orders, SUM(orders.OrderAmount) as TotalSales

无论父 Recordset 是如何形成的（使用 COMPUTE 或使用 APPEND），它将包含用于与子 Recordset 关联的子集列。如果愿意，父 Recordset 还可包含列，这些列包含子行上的合计（SUM、MIN、MAX 等）。父和子 Recordset 可能包含以下列：包含 Recordset 中行的表达式的列，以及新的并且最初为空的列。

操作

向返回子 Recordset 的提供者发出 child-command。

COMPUTE 子句指定父 Recordset 的列，这些列可以是对子 Recordset 的引用、一个或多个合计、计算表达式或者新列。如果有 BY 子句，则它定义的列也被追加到父 Recordset。BY 子句指定子 Recordset 的行的分组方式。

例如，假定有一个人口统计表，包括 State、City 和 Population 字段（人口数字单独说明）。

State | City | Population
WA | Seattle | 700,000
OR | Medford | 200,000
OR | Portland | 400,000
CA | Los Angeles | 800,000
CA | San Diego | 600,000
WA | Tacoma | 500,000
OR | Corvallis | 300,000

现在，发出此构形命令：

rst.Open  "SHAPE {select * from demographics} AS rs "  & _
          "COMPUTE rs, SUM(rs.population) BY state", _
           objConnection

这个命令打开包含两个层次的成形 Recordset。父层是生成的 Recordset，包含有合计列 (SUM(rs.population))、引用子 Recordset (rs) 的列和用于将子 Recordset (state) 分组的列。子层是由查询命令 (select * from demographics) 返回的 Recordset。

子 Recordset 的具体行将按 state 分组，但是不按照特定的顺序排序。即，分组不采用字母或数字顺序。如果要对父 Recordset 排序，则可以使用 Recordset Sort 方法对父 Recordset 排序。

现在，您可以定位打开的父 Recordset，并访问具体的子 Recordset 对象。有关详细信息，请参阅访问分级 Recordset 中的行。

所得到的父和具体的子 Recordset

父

SUM (rs.Population) | rs | State
1,300,000 | 引用子 1 | CA
1,200,000 | 引用子 2 | WA
1,100,000 | 引用子 3 | OR

子 1

State | City | Population
CA | Los Angeles | 800,000
CA | San Diego | 600,000

子 2

State | City | Population
WA | Seattle | 700,000
WA | Tacoma | 500,000

子 3

State | City | Population
OR | Medford | 200,000
OR | Portland | 400,000
OR | Corvallis | 300,000

请参阅

访问分级 Recordset 中的行 | 数据构形汇总 | Field 对象 | 规范构形语法 | Recordset 对象 | 数据构形所需的提供者 | Shape APPEND 子句 | 常规构形命令 | Value 属性 | Visual Basic for Applications 函数


虚构分级记录集

下面的范例显示了如何通过使用数据构形语法定义父、子和孙子 Recordset 的列，来虚构不包含基本数据源的分级 Recordset。

要虚构一个分级 Recordset，必须指定 Microsoft Data Shaping Service for OLE DB (MSDataShape)，并且可以在 Connection 对象的 Open 方法的连接字符串参数中将 Data Provider 的值指定为 NONE。有关详细信息，请参阅数据构形所需的提供者。

Dim cn As New ADODB.Connection
Dim rsCustomers As New ADODB.Recordset

cn.Open "Provider=MSDataShape;Data Provider=NONE;"

strShape = _
"SHAPE APPEND NEW adInteger AS CustID," & _
            " NEW adChar(25) AS FirstName," & _
            " NEW adChar(25) AS LastName," & _
            " NEW adChar(12) AS SSN," & _
            " NEW adChar(50) AS Address," & _
         " ((SHAPE APPEND NEW adChar(80) AS VIN_NO," & _
                        " NEW adInteger AS CustID," & _
                        " NEW adChar(20) AS BodyColor, " & _
                     " ((SHAPE APPEND NEW adChar(80) AS VIN_NO," & _
                                    " NEW adChar(20) AS Make, " & _
                                    " NEW adChar(20) AS Model," & _
                                    " NEW adChar(4) AS Year) " & _
                        " AS VINS RELATE VIN_NO TO VIN_NO))" & _
            " AS Vehicles RELATE CustID TO CustID) "

rsCustomers.Open strShape, cn, adOpenStatic, adLockOptimistic, -1

一旦虚构 Recordset 完成，便可以对它进行预置、操作或持久保留到文件中。

请参阅

访问分级 Recordset 中的行 | 规范构形语法 | 数据构形所需的提供者 | 构形 APPEND 子句 | 常规构形命令


访问分级 Recordset 中的行

以下范例说明了访问分级 Recordset 中的行所需的步骤：

  1. authors 和 titleauthor 表中的 Recordset 对象通过 author ID 进行关联。
  2. 外循环显示每个作者的姓名、州/省别和标识。
  3. 每行追加的 Recordset 都从 Fields 集合进行检索并指定为 rstTitleAuthor。
  4. 内循环显示追加的 Recordset 中每行的四个字段。

（StayInSync 属性为了达到说明的效果而设置为 FALSE，这样您可以在每次外循环中都看到子集的更改。但是，如果步骤 3 中的赋值被移动到步骤 2 的第一行之前，范例将会更有效，因此赋值只执行一次。然后将 StayInSync 属性设置为 TRUE，这样只要 rst 移动到新行，rstTitleAuthor 都将隐式和自动地更改为相应的子集。）

范例

Sub datashape()
   Dim cnn As New ADODB.Connection
   Dim rst As New ADODB.Recordset
   Dim rstTitleAuthor As New ADODB.Recordset

   cnn.Provider = "MSDataShape"
   cnn.Open    "Data Provider=MSDASQL;" & _
               "Data Source=SRV;" & _
               "User Id=MyUserName;Password=MyPassword;Database=Pubs"
' STEP 1
   rst.StayInSync = FALSE
   rst.Open    "SHAPE  {select * from authors} "  & _
               "APPEND ({select * from titleauthor} " & _
               "RELATE au_id TO au_id) AS chapTitleAuthor", _
               cnn
' STEP 2
   While Not rst.EOF
      Debug.Print    rst("au_fname"), rst("au_lname"), _
                     rst("state"), rst("au_id")
' STEP 3
      Set rstTitleAuthor = rst("chapTitleAuthor").Value
' STEP 4
      While Not rstTitleAuthor.EOF
         Debug.Print rstTitleAuthor(0), rstTitleAuthor(1), _
                     rstTitleAuthor(2), rstTitleAuthor(3)
         rstTitleAuthor.MoveNext
      Wend
      rst.MoveNext
   Wend
End Sub

请参阅

数据构形汇总 | Field 对象 | Fields 集合 | 规范构形语法 | Microsoft Data Shaping Service for OLE DB | Recordset 对象 | 数据构形所需的提供者 | Shape APPEND 子句 | 常规构形命令 | Shape COMPUTE 子句 | Visual Basic for Applications 函数


规范构形语法

以下是创建所有构形命令的规范语法：

  • 必需的语法项为尖括号 ("<>") 分隔的文本字符串。
  • 可选项由方括号 ("[ ]") 分隔。
  • 任选一项用竖线 ("|") 隔开。
  • 重复的可选项用省略号 ("...") 表示。
  • Alpha 表示字母字符串。
  • Digit 表示数字字符串。
  • Unicode-digit 表示由 Unicode 数字组成的字符串。

其他所有项均为文字。

项目 定义
<shape-command>

SHAPE [<table-exp> [[AS] <alias>]][<shape-action>]

<table-exp>

{<provider-command-text>} |

(<shape-command>) |
TABLE <quoted-name> |
<quoted-name>

<shape-action>

APPEND <aliased-field-list> |

COMPUTE <aliased-field-list> [BY <field-list>]

<aliased-field-list>

<aliased-field> [, <aliased-field...>]

<aliased-field>

<field-exp> [[AS] <alias>]

<field-exp>

(<relation-exp>) |

<calculated-exp> |
<aggregate-exp> |
<new-exp>

<relation_exp>

<table-exp> [[AS] <alias>]

   RELATE <relation-cond-list>

<relation-cond-list>

<relation-cond> [, <relation-cond>...]

<relation-cond>

<field-name> TO <child-ref>

<child-ref>

<field-name> |

PARAMETER <param-ref>

<param-ref>

<number>

<field-list>

<field-name> [, <field-name>]

<aggregate-exp>

SUM(<qualified-field-name>) |

AVG(<qualified-field-name>) |
MIN(<qualified-field-name>) |
MAX(<qualified-field-name>) |
COUNT(<qualified-alias> | <qualified-name>) |
STDEV(<qualified-field-name>) |
ANY(<qualified-field-name>)

<calculated-exp>

CALC(<expression>)

<qualified-field-name>

<alias>.[<alias>...]<field-name>

<alias>

<quoted-name>

<field-name>

<quoted-name> [[AS] <alias>]

<quoted-name>

"<string>" |

'<string>' |
[<string>] |
<name>

<qualified-name>

alias[.alias...]

<name>

alpha [ alpha | digit | _ | # | : | ...]

<number>

digit [digit...]

<new-exp>

NEW <field-type> [(<number> [, <number>])]

<field-type>
 OLE DB 或 ADO 数据类型。
<string>

unicode-char [unicode-char...]

<expression>
 Visual Basic for Applications 表达式，其操作数是同一行中的其他非 CALC 列。

请参阅

访问分级 Recordset 中的行 | 数据构形汇总 | 数据构形所需的提供者 | Shape APPEND 子句 | 常规构形命令 | Shape COMPUTE 子句 | Visual Basic for Applications 函数


Visual Basic for Applications 函数

下列 Visual Basic for Applications 函数可以在数据构形 CALC 表达式中使用：

Abs | Asc | Atn | CBool | CByte | CCur
CDate | CDbl | Chr | ChrB | ChrW | Chr$
ChrB$ | CInt | CLng | Cos | CSng | CStr
Cvar | CVDate | CVErr | Date | Date$ | DateAdd
DateDiff | DatePart | DateSerial | DateValue | Day | DDB
Error | Error$ | Exp | Fix | Format | Format$
FV | Hex | Hex$ | Hour | IIF | InStr
Int | IPmt | IRR | IsDate | IsEmpty | IsError
IsNull | IsNumeric | IsObject | LCase | LCase$ | Left
LeftB | Left$ | LeftB$ | Len | Log | LTrim
LTrim$ | Mid | Mid$ | Minute | MIRR | Month
Now | NPer | NPV | Oct | Oct$ | Pmt
PPmt | PV | QBColor | Rate | RGB | Right
RightB | Right$ | RightB$ | Rnd | RTrim | RTrim$
Second | Sgn | Sin | SLN | Space | Space$
Sqr | Str | Str$ | StrComp | StrConv | String
String$ | SYD | Tan | Time | Time$ | Timer
TimeSerial | TimeValue | Trim | Trim$ | TypeName | UCase
UCase$ | Val | VarType | Weekday | Year |

请参阅

访问分级 Recordset 中的行 | 数据构形汇总 | 规范构形语法 | 数据构形所需的提供者 | Shape APPEND 子句 | 常规构形命令 | Shape COMPUTE 子句


第 10 章：Record 和 Stream

现在，ADO 提供 Recordset 来作为访问数据源中信息（如关系数据库）的主要方式。但是，某些提供者支持 Record 和 Stream 对象作为可被操作的提供者中数据的可选或补充对象。有关 Record 行为的特定信息，请参阅提供者的文档。

Records

Record 对象本质上作为一行 Recordset 执行。但是，Records 比 Recordsets 的功能更加有限，并且它们具有不同的属性和方法。Record 对象中数据的源可以是从提供者返回一行数据的命令。使用 Record 对象（而不是 Recordset 对象）来接收某个返回一行数据的查询结果，可以消除实例化更加复杂 Recordset 对象的开销。

Record 可以提供其他用途，尤其是对于数据源而不是传统关系数据库的提供者，例如 Microsoft OLE DB Provider for Internet Publishing。必须被处理的大量信息不是以数据库表形式存在，而是以电子邮件系统中的邮件和现代文件系统中的文件形式存在。Record 和 Stream 对象为访问存储在非关系数据库的其他源中的信息提供了方便。

Record 对象可以表示和管理数据，例如文件系统中的目录和文件以及电子邮件系统中的文件夹和邮件。这样，Record 的源可以是打开的 Recordset 的当前行、绝对 URL 或者是与打开的 Connection 对象连接的相对 URL。

一般情况下，Recordset 可用来表示分级结构中的容器或父，例如一个文件夹或目的。可以使用 Record 来返回有关父容器中一个节点的特定信息，例如一个文件或文档。Records 用来表示这种信息的主要原因是这些数据的源是异类的。这意味着每个 Record 都可以有一个不同集合和数量的字段。包含数据库中行的传统 Recordsets 是同类的，这意味着每行都具有相同数量和类型的字段。

有关使用 Record 对象处理提供者（例如 Internet Publishing Provider）中该异类数据的详细信息，请参阅使用 ADO for Internet Publishing。

流

Stream 对象提供读取、写入以及管理字节流的手段。该字节流可以是文本或二进制数，并且在大小方面只受限于系统资源。一般情况下，ADO Stream 对象用于以下目的：

  • 若要包含由文件或邮件构成的文本或字节，一般情况下与提供程序（例如 Microsoft OLE DB Provider for Internet Publishing）一起使用。有关该 Stream 对象用法的详细信息，请参阅使用 ADO for Internet Publishing。

Stream 对象可以在下列目标上打开：

  • 通过 URL 指定的简单文件。
  • 包含 Stream 对象的 Record 或 Recordset 的字段。
  • 表示目录或复合文件的 Record 或 Recordset 对象的默认流。
  • 包含简单文件的 URL 的资源字段。
  • 没有特定源。在这种情况下，将在内存中打开一个 Stream 对象，可以将数据写入其中，然后再保存到另一个 Stream 或文件中。
  • Recordset 中的 BLOB 字段。

© 1998-2002 Microsoft Corporation。保留所有权利。


流和持久性

Recordset 对象的 Save 方法将 Recordset 保存或者持久保留到文件中，而 Open 方法则从该文件中恢复 Recordset。

使用 ADO 2.5，Save 和 Open 方法可将 Recordset 持久保留到 Stream 对象中。此功能尤其有助于使用远程数据服务 (RDS) 和 Active Server Pages (ASP)。

有关如何在 ASP 页上自动使用持久性的详细信息，请参阅当前 ASP 文档。

下列几种方案说明了如何使用 Stream 对象和持久性。

方案 1

本方案先简单地将 Recordset 保存到一个文件中，再将其保存到 Stream。然后将持久保留的流打开到另一个 Recordset 中。

Dim rs1 As ADODB.Recordset
Dim rs2 As ADODB.Recordset
Dim stm As ADODB.Stream

Set rs1 = New ADODB.Recordset
Set rs2 = New ADODB.Recordset
Set stm = New ADODB.Stream

rs1.Open   "SELECT * FROM Customers", "Provider=sqloledb;" & _
        "Data Source=MyServer;Initial Catalog=Northwind;" & _
        "Integrated Security=SSPI;""", adopenStatic, adLockReadOnly, adCmdText
rs1.Save "c:\myfolder\mysubfolder\myrs.xml", adPersistXML
rs1.Save stm, adPersistXML
rs2.Open stm

方案 2

本方案以 XML 格式将 Recordset 持久保留到 Stream 中。然后将 Stream 读取到可以进行检查、操作或显示的字符串中。

Dim rs As ADODB.Recordset
Dim stm As ADODB.Stream
Dim strRst As String

Set rs = New ADODB.Recordset
Set stm = New ADODB.Stream

' Open, save, and close the recordset.
rs.Open "SELECT * FROM Customers", "Provider=sqloledb;" & _
        "Data Source=MyServer;Initial Catalog=Northwind;" & _
        "Integrated Security=SSPI;"""
rs.Save stm, adPersistXML
rs.Close
Set rs = nothing

' Put saved Recordset into a string variable.
strRst = stm.ReadText(adReadAll)

' Examine, manipulate, or display the XML data.
...

方案 3

本范例代码显示了一段 ASP 代码，它将 Recordset 以 XML 格式直接持久保留到 Response 对象。

...
<%
response.ContentType = "text/xml"

' Create and open a Recordset.
Set rs = Server.CreateObject("ADODB.Recordset")
rs.Open "select * from Customers", "Provider=sqloledb;" & _
        "Data Source=MyServer;Initial Catalog=Northwind;" & _
        "Integrated Security=SSPI;"""

' Save Recordset directly into output stream.
rs.Save Response, adPersistXML

' Close Recordset.
rs.Close
Set rs = nothing
%>
...

方案 4

在本方案中，ASP 代码将 Recordset 的内容以 ADTG 格式写入客户端。Microsoft Cursor Service for OLE DB 可使用此数据创建断开连接的 Recordset。

RDS DataControl 的新属性 URL 指向生成 Recordset 的 .asp 页。这意味着获取 Recordset 对象不需要 RDS 使用服务器端 DataFactory 对象，也不需要用户编写业务对象。因此大大简化了 RDS 编程模型。

名为 http://server/directory/recordset.asp 的服务器端代码如下：

<%
Dim rs
Set rs = Server.CreateObject("ADODB.Recordset")
rs.Open "select au_fname, au_lname, phone from Authors", ""& _
        "Provider=sqloledb;Data Source=MyServer;" & _
        "Initial Catalog=Pubs;Integrated Security=SSPI;"
response.ContentType = "multipart/mixed"
rs.Save response, adPersistADTG
%>

客户端代码：

<HTML>
<HEAD>
<TITLE>RDS Query Page</TITLE>
</HEAD>
<body>
<CENTER>
<H1>Remote Data Service 2.5</H1>
<TABLE DATASRC="#DC1">
   <TR>
      <TD><SPAN DATAFLD="au_fname"></SPAN></TD>
      <TD><SPAN DATAFLD="au_lname"></SPAN></TD>
      <TD><SPAN DATAFLD="phone"></SPAN></TD>
   </TR>
</TABLE>
<BR>

<OBJECT classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33"
    ID=DC1 HEIGHT=1 WIDTH = 1>
    <PARAM NAME="URL" VALUE="http://server/directory/recordset.asp">
</OBJECT>

</SCRIPT>
</BODY>
</HTML>

开发人员还可以选择在客户端使用 Recordset 对象。

...
function GetRs()
    {
    rs = CreateObject("ADODB.Recordset");
    rs.Open "http://server/directory/recordset.asp"
    DC1.SourceRecordset = rs;
    }
...

请参阅

Open 方法 (ADO Recordset) | Record 对象 | Save 方法


使用 ADO for Internet Publishing

OLE DB Provider for Internet Publishing 显示使用 ADO 访问不同数据的特定范例。虽然本节中的范例专门用于 Internet Publishing Provider，但是当使用带有不同数据的其他提供者（如电子邮件存储的提供者）时，所演示的原理是相似的。

URL

统一资源定位符 (URL) 可以作为连接字符串和命令文本的替换方式，用于指定数据源以及文件和目录的位置。它还可以同现有的 Connection 和 Recordset 对象以及 Record 和 Stream 对象配合使用。

有关使用 URLs 的详细信息，请参阅绝对和相对 URL。

Record 字段

不同数据和相同数据之间的差别在于：对于不同数据，每行数据或记录可有不同的列或字段集。对于相同数据，每行具有相同的列集。有关 Internet Publishing Provider 特有字段的详细信息，请参阅记录和提供者提供的额外字段。

追加新字段

几种增强的 ADO 对象可以与 Record 和 Stream 对象结合使用。

  • Fields 集合的 Append 方法创建 Field 对象并将其添加到集合中，它还可以指定 Field 的值。
  • Update 方法完成集合中字段的添加或删除。
  • 作为 Append 方法的快捷方式和替换方式，您只需简单地把一个值赋给取消定义或以前删除的字段便可创建字段。

请参阅

Record 对象 | Stream 对象 | ADO 的新增内容


OLE DB Provider for Internet Publishing

可以将 ADO Record 和 Stream 对象与 Microsoft OLE DB Provider for Internet Publishing (Internet Publishing Provider) 配合使用来访问和操作资源，例如由 Microsoft FrontPage 提供的 Web 文件夹或文件。用 ADO 可以将 Record、Stream 或 Recordset 的源指定为 URL。然后，您就可以上载、下载、移动、复制和删除资源，或者直接操作资源属性。

有关将 Records 和 Streams 与 Internet Publishing Provider 配合使用的范例代码，请参阅 Internet 发布方案。

Internet Publishing Provider 是和 Microsoft Windows 2000 一起安装的。Internet Publishing Provider 的早期版本也可以通过 Microsoft Office 2000 和 Microsoft Internet Explorer 5.0 获得。

有三种方法可以将 ADO 连接到 Internet Publishing Provider：

  • 在连接字符串中指定“URL=”。例如：
    objConn.Open "URL=http://servername"
  • 将连接字符串的 Provider 关键字指定为 Msdaipp.dso。例如：
    objConn.Open "provider=MSDAIPP.DSO;data source=http://servername"
  • 将 Connection 对象的 Provider 属性指定为 Msdaipp.dso。例如：
    objConn.Provider = "MSDAIPP.DSO"
objConn.Open "http://servername"
注意 如果 Msdaipp.dso 被显式指定为提供者的值（使用 Provider 连接字符串关键字或 Provider 属性），您将不能在连接字符串中使用“URL=”。否则，将会出现错误。但可以如上所示指定 URL。

有关 Internet Publishing Provider 的特定信息，请参阅 Microsoft OLE DB Provider for Internet Publishing 或者参阅与源应用程序一起提供的提供者文档，OLE DB Provider for Internet Publishing 与该源应用程序一起安装，包括：Windows 2000、Office 2000 或者 Internet Explorer 5.0。


Internet 发布方案

本代码范例演示了如何将 ADO 与 Microsoft OLE DB Provider for Internet Publishing 配合使用。在本方案中，您将创建一个 Visual Basic 应用程序，该应用程序用 Recordset、Record 和 Stream 对象来显示通过 Internet Publishing Provider 发布的资源内容。

创建此方案需要执行下列步骤：

  • 步骤 1：设置 Visual Basic 工程
  • 步骤 2：初始化主列表框
  • 步骤 3：预置字段列表框
  • 步骤 4：预置详细文本框

请参阅

Microsoft OLE DB Provider for Internet Publishing | OLE DB Provider for Internet Publishing


步骤 1：设置 Visual Basic 工程

在此方案中，假定您的系统中已经安装了 Microsoft Visual Basic 6.0 或更新版本，ADO 2.5 或更新版本，以及 Microsoft OLE DB Provider for Internet Publishing。

创建 ADO 工程的步骤：

  1. 在 Microsoft Visual Basic 中创建一个新的“标准 EXE”工程。
  2. 从“工程”菜单中选择“引用”。
  3. 选择“Microsoft ActiveX Data Objects 2.5 Library”，然后单击“确定”。

在主窗体中插入控件的步骤：

  1. 将一个 ListBox 控件添加到 Form1。将其 Name 属性设置为 lstMain。
  2. 将另一个 ListBox 控件添加到 Form1。将其 Name 属性设置为 lstDetails。
  3. 将一个 TextBox 控件添加到 Form1。将其 Name 属性设置为 txtDetails。

请参阅

步骤 2：初始化主列表框


步骤 2：初始化主列表框

声明全局 Record 和 Recordset 对象的步骤

  • 将下列代码插入 Form1 的 (通用) (声明)：
    Option Explicit
Dim grec As Record
Dim grs As Recordset

    此代码声明了 Record 和 Recordset 对象的全局对象引用，这将在本方案的后面用到。

连接 URL 和预置 lstMain 的步骤

  • 将下列代码插入 Form1 的 Form Load 事件处理程序中：
    Private Sub Form_Load()
    Set grec = New Record
    Set grs = New Recordset
    grec.Open "", "URL=http://servername/foldername/", , _
        adOpenIfExists Or adCreateCollection
    Set grs = grec.GetChildren
    While Not grs.EOF
        lstMain.AddItem grs(0)
        grs.MoveNext
    Wend
End Sub

    此代码将全局 Record 和 Recordset 对象实例化。Record grec 通过指定为 ActiveConnection 的 URL 打开。如果该 URL 存在，则它将打开；如果不存在，则会创建一个。请注意，应该用自己环境下的有效 URL 替换“http://servername/foldername/”。

    Recordset grs 在 Record grec 的子上打开。然后使用发布到 URL 的资源的文件名来预置 lstMain。

请参阅

步骤 3：预置字段列表框


步骤 3：预置字段列表框

预置字段列表框的步骤：

将下列代码插入 lstMain 的 Click 事件处理程序中：

Private Sub lstMain_Click()
    Dim rec As Record
    Dim rs As Recordset
    Set rec = New Record
    Set rs = New Recordset
    grs.MoveFirst
    grs.Move lstMain.ListIndex
    lstDetails.Clear
    rec.Open grs
    Select Case rec.RecordType
        Case adCollectionRecord:
            Set rs = rec.GetChildren
            While Not rs.EOF
                lstDetails.AddItem rs(0)
                rs.MoveNext
            Wend
        Case adSimpleRecord:
            recFields rec, lstDetails, txtDetails

        Case adStructDoc:
    End Select

End Sub

此代码分别声明和实例化本地 Record 和 Recordset 对象：rec 和 rs。

与 lstMain 中选定的资源相对应的行成为 grs 的当前行。然后，“详细”列表框被清除，并将 rec 的当前行作为源来打开 grs。

如果该资源是集合记录（如由 RecordType 指定），本地 Recordset rs 将在 rec 的子上打开。然后，用 rs 行的值来预置 lstDetails。

如果资源是简单记录，则调用 recFields。有关 recFields 的信息，请参阅下一个步骤。

如果资源是结构化文档，则没有要实现的代码。

请参阅

步骤 4：预置详细文本框


步骤 4：预置详细文本框

预置详细文本框的步骤：

创建名为 recFields 的新的子例程并插入下列代码：

Sub recFields(r As Record, l As ListBox, t As TextBox)
    Dim f As Field
    Dim s As Stream
    Set s = New Stream
    Dim str As String

    For Each f In r.Fields
        l.AddItem f.Name & ": " & f.Value
    Next
    t.Text = ""
    If r!RESOURCE_CONTENTCLASS = "text/plain" Then
        s.Open r, adModeRead, adOpenStreamFromRecord
        str = s.ReadText(1)
        s.Position = 0
        If Asc(Mid(str, 1, 1)) = 63 Then '//63 = "?"
            s.Charset = "ascii"
            s.Type = adTypeText
        End If
        t.Text = s.ReadText(adReadAll)
    End If
End Sub

此代码用传递到 recFields 的简单记录的字段和值来预置 lstDetails。如果资源是一个文本文件，文本 Stream 将从资源记录打开。该代码判断字符集是否是 ASCII，并且将 Stream 内容复制到 txtDetails 中。


绝对和相对 URL

URL 指定了目标在本地或网络计算机上存储的位置，这个目标可以是文件、目录、HTML 页面、图像、程序等等。在本讨论中，“绝对 URL”的格式如下：

scheme://server/path/resource

其中：

scheme
指定访问 resource 的方式。
server
指定 resource 所在计算机的名称。
path
指定到达目标的目录序列。如果忽略 resource ，则目标是 path 中的最后一个目录。
resource
如果包括 resource，则它是目标，通常是文件名。它可能是包含字节的单个二进制流的“简单文件”，也可能是包含字节的一个或多个存储和二进制流的“结构化文档”。

“绝对 URL”包含定位资源所需的全部信息。

“相对 URL”以某个绝对 URL 为起点来定位资源。实际上，目标的“完整 URL”要通过连接绝对 URL 和相对 URL 来指定。相对 URL 通常只包括 path 和 resource（可选），而不包括 scheme 和 server。

URL 方案注册

如果提供者支持 URL，则它将注册一个或多个 URL 方案。这意味着使用该方案的所有 URL 都将自动调用已注册的提供者。例如，将 http 方案注册到 Microsoft OLE DB Provider for Internet Publishing。ADO 将假设带有“http”前缀（表示 Web 文件夹或文件）的所有 URL 都可通过 Internet Publishing Provider 使用。有关提供者注册的方案的信息，请参阅提供者文档。

用 URL 定义上下文

打开的连接（由 Connection 对象表示）的一项功能是限制对该连接所表示的数据源的后续操作。即，连接定义了后续操作的上下文。

使用 ADO 2.5，绝对 URL 也可以定义上下文。例如，当用绝对 URL 打开 Record 对象时，将隐式创建 Connection 对象来表示该 URL 所指定的资源。

可以在 Record 对象 Open 方法的 ActiveConnection 参数中指定定义上下文的绝对 URL。也可以在 Connection 对象 Open 方法 ConnectionString 参数中和 Recordset 对象 Open 方法 ActiveConnection 参数中，将绝对 URL 指定为新的“URL=”关键字的值。

还可以使用表示目录的打开的 Record 或 Recordset 对象来定义上下文，因为这些对象已经具有一个指定上下文的隐式或显式声明的 Connection 对象。

限定操作范围

上下文同时定义了一个“范围”，即可能参与后续操作的目录及其子目录。Record 对象有几种方法可以限定范围，包括 CopyRecord、MoveRecord 和 DeleteRecord，这些方法在目录及其所有子目录上进行操作。

用相对 URL 作命令文本

可以在 Connection 对象 Execute 方法的 CommandText 参数和 Recordset 对象 Open 方法的 Source 参数中指定一个字符串，该字符串用于指定要在数据源上执行的命令。

可以在 CommandText 或 Source 参数中指定相对 URL。相对 URL 实际上没有指定命令（例如 SQL 命令），而且它只能在那些参数中指定。另外，活动连接的上下文必须是绝对 URL，并且 Option 参数必须设置为 adCmdTableDirect。

例如，可以在 Winnt/system32 目录的 Readme25.txt 文件上以如下方式打开 Recordset：

recordset.Open "system32/Readme25.txt", "URL=http://YourServer/Winnt/",,,adCmdTableDirect

连接字符串中的绝对 URL 指定了服务器 (YourServer) 和路径 (Winnt)。此 URL 还定义了上下文。

命令文本中的相对 URL 以该绝对 URL 为起点，指定其余的路径 (system32) 和要打开的文件 (Readme25.txt)。

Option 字段 (adCmdTableDirect) 指示命令类型为相对 URL。

再举一个范例，如下代码将在 Winnt 目录的内容上打开 Recordset：

recordset.Open "", "URL=http://YourServer/Winnt/",,,adCmdTableDirect

OLE DB 提供者提供的 URL 方案

完全确定的 URL 的前导部分是 scheme，它用于访问由 URL 其余部分标识的资源。例如 HTTP（超文本传输协议）和 FTP（文件传输协议）。

ADO 支持能识别自身 URL 模式的 OLE DB 提供者。例如，Microsoft OLE DB Provider for Internet Publishing 用于访问“发布的”Windows 2000 文件，它能识别现有的 HTTP 模式。

请参阅

Connection 对象 | Record 对象 | Recordset 对象


记录和提供者提供的字段

打开 Record 对象时，它的源可以是打开的 Recordset 的当前行、绝对 URL 或者是与打开的 Connection 对象连接的相对 URL。

如果 Record 是从 Recordset 打开的，那么 Record 对象的 Fields 集合将包含 Recordset 的所有字段，再加上所有由基本提供者添加的字段。

提供者可以插入其他用来补充 Record 特性的字段。其结果是，Record 具有唯一的字段，这些字段都不在 Recordset 中，也不在由 Recordset 的另一行派生的任何 Record 中。

例如，从电子邮件数据源派生的 Recordset 的所有行都具有 From、To 和 Subject 等列。从该 Recordset 派生出来的 Record 将具有与其相同的字段。但是，Record 还可能具有其他由该 Record 表示的特定邮件的唯一字段，例如 Attachment 和 Cc（抄送）。

尽管 Record 对象和 Recordset 的当前行具有相同的字段，但它们是有区别的，因为 Record 和 Recordset 对象具有不同的方法和属性。

Record 和 Recordset 共有的字段在两个对象上都可以修改。但是，不能在 Record 对象上删除字段，尽管基本提供者可能支持将字段设置为 Null。

打开 Record 以后，可以通过编程来添加字段。也可以删除刚添加的字段，但是不能删除原 Recordset 的字段。

Record 对象还可以直接从 URL 打开。在这种情况下，添加到 Record 的字段取决于基本提供者。现在，大多数提供者都添加了一组字段，用于描述由 Record 表示的项目。如果该项目包含字节流（如简单文件），通常可以从 Record 打开 Stream 对象。

用于文档源提供者的特殊字段

一类称为文档源提供者的特殊提供者，用于管理文件夹和文档。当 Record 对象表示文档或者 Recordset 对象表示文档的文件夹时，文档源提供者使用唯一一组描述文档特性（而不是实际文档）的字段来预置这些对象。通常，一个字段包含对表示文档的 Stream 的引用。

这些字段组成资源记录或记录集，并且在附录 A：提供者中按支持这些字段的特定提供者分类列出。

有两个常量用于为资源 Record 或 Recordset 的 Fields 集合建立索引，以检索一对常用字段。Field 对象的 Value 属性返回需要的内容。

  • 通过 adDefaultStream 常量访问的字段包含与 Record 或 Recordset 对象相关联的默认流。提供者将默认流分配给对象。
  • 通过 adRecordURL 常量访问的字段包含标识文档的绝对 URL。

文档源提供者不支持 Record 和 Field 对象的 Properties 集合。这些对象的 Properties 集合的内容为空。

文档源提供者可以添加提供者特有的属性（如 Datasource Type）来标识它是否为文档源提供者。有关如何确定提供者类型的详细信息，请参阅提供者的文档。

资源记录集列

资源记录集包含下面的列：

列名 | 类型 | 说明
RESOURCE_PARSENAME | AdVarWChar | 只读。指示资源的 URL。
RESOURCE_PARENTNAME | AdVarWChar | 只读。指示父记录的绝对 URL。
RESOURCE_ABSOLUTEPARSENAME | AdVarWChar | 只读。指示资源的绝对 URL，它是 PARENTNAME 和 PARSENAME 的连接。
RESOURCE_ISHIDDEN | AdBoolean | 如果隐藏资源，则为 True。除了创建行集合的命令显式选择 RESOURCE_ISHIDDEN 为 TRUE 的行以外，将不返回行。
RESOURCE_ISREADONLY | AdBoolean | 如果资源是只读的，则为 True。试图通过 DBBINDFLAG_WRITE 打开此资源，并且通过 DB_E_READONLY 打开将会失败。即使以只读模式打开资源，仍然可以编辑此属性。
RESOURCE_CONTENTTYPE | AdVarWChar | 指示文档的可能用法，例如律师的摘要。这可以与用来创建文档的 Office 模板相对应。
RESOURCE_CONTENTCLASS | AdVarWChar | 指示文档的 MIME 类型，用于指示格式（如“text/html”）。
RESOURCE_CONTENTLANGUAGE | AdVarWChar | 指示用于存储内容的语言。
RESOURCE_CREATIONTIME | adFileTime | 只读。指示 FILETIME 结构，它包含资源的创建时间。以 Coordinated Universal Time (UTC) 格式报告时间。
RESOURCE_LASTACCESSTIME | AdFileTime | 只读。指示 FILETIME 结构，它包含最后一次访问资源的时间。时间采用 UTC 格式。如果提供者不支持这个时间成员，FILETIME 成员为零。
RESOURCE_LASTWRITETIME | AdFileTime | 只读。指示 FILETIME 结构，它包含最后一次写入资源的时间。时间采用 UTC 格式。如果提供者不支持这个时间成员，FILETIME 成员为零。
RESOURCE_STREAMSIZE | asUnsignedBigInt | 只读。指示资源的默认流的字节数。
RESOURCE_ISCOLLECTION | AdBoolean | 只读。如果资源是一个集合（如目录），则为 True。如果资源是简单文件，则为 False。
RESOURCE_ISSTRUCTUREDDOCUMENT | AdBoolean | 如果资源是结构化文档，则为 True。如果资源不是结构化文档，则为 False。它可以是集合或简单文件。
DEFAULT_DOCUMENT | AdVarWChar | 只读。指示此资源包含 URL，该 URL 指向文件夹的默认简单文档或结构化文档。此属性在从资源请求默认流时使用。对于简单文件，此属性为 Null。
CHAPTERED_CHILDREN | AdChapter | 只读。可选。指示行集合的子集，该行集合包含资源的子。（OLE DB Provider for Internet Publishing 不使用此列。）
RESOURCE_DISPLAYNAME | AdVarWChar | 只读。指示资源的显示名称。
RESOURCE_ISROOT | AdBoolean | 只读。如果资源是集合或结构化文档的根，则为 True。

请参阅

Record 对象 | 附录 A：提供者


第 2 节：远程数据服务 (RDS)

本节包含以下章节：

  • 第 11 章：RDS 基础
  • 第 12 章：RDS 教程
  • 第 13 章：RDS 用法和安全性


第 11 章：RDS 基础

本节包含一系列主题，用户可以按预定顺序阅读。包括下列主题：

  • 远程数据访问的解决方案
  • 基本 RDS 编程模型
  • RDS 编程模型详细信息
  • 使用对象的 RDS 编程模型
  • RDS 对象模型汇总

本节还包括演示如何访问和更新数据源的 RDS 教程和 RDS 方案，以及有关使用 RDS 的一系列主题，这些主题中讨论了更高级的 RDS 主题。

请参阅

远程数据访问的解决方案 | RDS 教程 | 使用 RDS


远程数据访问的解决方案

问题

ADO 使应用程序能够直接访问和修改数据源（有时称为双层系统）。例如，如果连接是到包含用户数据的数据源，则它是双层系统中的一个直接连接。

但是，有时也需要通过 Microsoft Internet Information Services (IIS) 这样的媒介间接访问数据源。这种方案有时称为三层系统。IIS 是客户端/服务器系统，可帮助本地或客户端应用程序通过 Internet 或 Intranet 高效地调用远程或服务器程序。服务器程序可以访问数据源，并有选择地处理所获得的数据。

例如，Intranet 网页包含连接到 IIS 的应用程序，该应用程序是用 Microsoft Visual Basic Scripting Edition (VBScript) 编写的。IIS 将依次连接到实际数据源，检索数据，以某种方式处理数据，然后将处理后的信息返回到应用程序。

在此范例中，应用程序并未直接连接到数据源，而是通过 IIS 连接到数据源。并且，IIS 通过 ADO 访问数据。

注意 客户端/服务器应用程序无须基于 Internet 或 Intranet（即基于 Web），它可以仅由局域网上的已编译程序组成。但通常是基于 Web 的应用程序。

因为某些可视控件（如网格、复选框或列表）可能会使用返回的信息，所以返回的信息必须易于被可视控件使用。

用户需要的是简单而有效的应用程序编程接口，该接口支持三层系统，并能够象在双层系统上检索一样易于返回信息。远程数据服务 (RDS) 便是这样的接口。

解决方案

RDS 定义编程模型（即访问和更新数据源所必需的活动的序列），以便通过 Internet Information Services (IIS) 这样的媒介访问数据。编程模型汇总了 RDS 的所有功能。

请参阅

基本 RDS 编程模型 | RDS 教程 | 使用 RDS


基本 RDS 编程模型

RDS 阐述了存在于下列环境中的应用程序：客户端应用程序指定将在服务器上执行的程序，并指定返回需要的信息所需的参数。在服务器上调用的程序访问指定的数据源，检索信息，有选择地处理数据，然后将得到的信息以客户端应用程序易于使用的格式返回客户端应用程序。RDS 提供执行以下操作序列的方式：

  • 指定服务器上要调用的程序，并获取从客户端引用该程序的方法。（这种引用有时称为“代理”。它表示远程服务器程序。客户端应用程序将像调用本地程序一样调用代理，但实际上是调用远程服务器程序。）
  • 调用服务器程序。将参数传递给标识数据源和要发出的命令的服务器程序。（实际上，服务器程序使用 ADO 访问数据源。ADO 与一个给定的参数相连接，然后发出在其他参数中指定的命令。）
  • 服务器程序从数据源获取 Recordset 对象。可选，也可在服务器上处理 Recordset 对象。
  • 服务器程序将最终的 Recordset 对象返回到客户端应用程序。
  • 在客户端，将 Recordset 对象转换为可视控件易于使用的格式。
  • 对 Recordset 对象所做的任何修改都将被发送回服务器程序，服务器程序用它们来更新数据源。

此编程模型包含某些简便功能。如果不需要复杂的服务器程序来访问数据源，而且提供了所需的连接和命令参数，RDS 将用简单的默认服务器程序来自动检索指定的数据。

如果需要更复杂的处理，可以指定自定义的服务器程序。例如，因为自定义服务器程序有足够的 ADO 处置能力，所以能连接几个不同的数据源，并把这些数据以某种复杂的方式结合起来，然后将经过处理的简单结果返回给客户端应用程序。

最后，如果在其间还需要别的方式，ADO 支持自定义默认服务器程序的行为。

请参阅

RDS 编程模型详细信息 | RDS 教程 | Recordset 对象 | 使用 RDS


RDS 编程模型详细信息

下面是 RDS 编程模型中的关键元素：

  • RDS.DataSpace
  • RDSServer.DataFactory
  • RDS.DataControl
  • Event

RDS.DataSpace

客户端应用程序必须指定服务器和要调用的服务器程序。反过来，应用程序接收对服务器程序的引用，并将此引用当作服务器程序本身来处理。

RDS 对象模型以 RDS.DataSpace 对象体现这种功能。

使用程序标识符（或 ProgID）指定服务器程序。服务器使用 ProgID 和服务器注册表来定位有关要启动的实际程序的信息。

根据服务器程序是在 Internet 或 Intranet 的远程服务器上、在局域网的服务器上、还是根本不在服务器而在本地动态链接库 (DLL) 上，RDS 可在内部进行划分。这种划分决定在客户端与服务器之间交换信息的方式，并且对于返回给客户端应用程序的引用类型中有着实际的区别。从用户的角度来看，这种划分没有特殊意义。重要的是用户能接收到可用的程序引用。

RDSServer.DataFactory

RDS 提供默认服务器程序，它可以执行对数据源的 SQL 查询并返回 Recordset 对象，或者获得一个 Recordset 对象并更新数据源。

RDS 对象模型以 RDSServer.DataFactory 对象体现这种功能。

另外，此对象具有创建空的 Recordset 对象的方法，可以通过编程填充这个空的 Recordset (CreateRecordset)。还有另一个方法可将 Recordset 对象转换为文本字符串以建立 Web 页 (ConvertToString)。

通过 ADO，您可以用 DataFactory 处理程序和包含连接、命令和安全性参数的自定义文件来覆盖 RDSServer.DataFactory 的某些标准连接和命令行为。

这种服务器程序有时可称为“业务对象”。您可以编写自己的自定义业务对象来进行复杂的数据访问、有效性检查等等。甚至在编写自定义业务对象时，您也可以创建 RDSServer.DataFactory 对象的实例，并用它的某些方法来完成自己的任务。

RDS.DataControl

RDS 提供了一种方法，可以把 RDS.DataSpace 和 RDSServer.DataFactory 的功能结合起来，并且还可以使可视控件很容易地使用从数据源查询返回的 Recordset 对象。大多数情况下，RDS 总是尽可能多地自动访问服务器上的信息，并将其显示在可视控件中。

RDS 对象模型以 RDS.DataControl 对象来体现这种功能。

RDS.DataControl 包括两个方面。一个方面涉及到数据源。如果使用 RDS.DataControl 的 Connect 和 SQL 属性设置命令和连接信息，则将自动使用 RDS.DataSpace 以创建一个到默认 RDSServer.DataFactory 对象的引用。RDSServer.DataFactory 将使用 Connect 属性值来连接到数据源，使用 SQL 属性值获取数据源的 Recordset 并将 Recordset 对象返回到 RDS.DataControl。

第二个方面涉及在可视控件中显示返回的 Recordset 信息。可以将可视控件与 RDS.DataControl 相关联（在进程中称为绑定），并且访问关联的 Recordset 对象中的信息，查询结果显示在 Microsoft Internet Explorer 中的网页上。每个 RDS.DataControl 对象将一个表示单个查询结果的 Recordset 对象绑定到一个或多个可视控件（如文本框、组合框和网格控件等等）。在每页上可以有多个 RDS.DataControl 对象。每个 RDS.DataControl 对象都可连接不同的数据源，并且包含独立的查询结果。

RDS.DataControl 对象还具有自己的定位、排序和过滤关联的 Recordset 对象行的方法。这些方法与 ADO Recordset 对象的方法相似，但又有所区别。

Event

RDS 支持两个自带的事件，它们不依赖于 ADO 事件模型。只要 RDS.DataControl ReadyState 属性发生变化，就将调用 onReadyStateChange 事件。这样，当异步操作成功地完成、中止或发生错误时，都可以通知您。只要发生错误（即使在异步操作过程中发生错误），便会调用 onError 事件。

注意 Microsoft Internet Explorer 提供给 RDS 两个附加事件：onDataSetChanged（Recordset 在起作用但还在检索行）和 onDataSetComplete（Recordset 已结束检索行）。

请参阅

使用对象的 RDS 编程模型 | DataControl 对象 (RDS) | DataFactory 对象 (RDSServer) | DataSpace 对象 (RDS) | RDS 教程 | 使用 RDS


使用对象的 RDS 编程模型

RDS 的目标是通过 IIS 这样的媒介访问和更新数据源。编程模型指定实现此目标所必需的一系列活动。对象模型指定了其方法和属性会影响编程模型的对象。

RDS 提供执行下列操作序列的方式：

  • 指定服务器上要调用的程序，并获取从客户端引用该程序的方法（代理）。(RDS.DataSpace)
  • 调用服务器程序。将参数传递给标识数据源和要发出的命令的服务器程序。（代理或 RDS.DataControl）
  • 通常，服务器程序通过使用 ADO 从数据源获取 Recordset 对象。此外，也可在服务器上处理 Recordset 对象。(RDSServer.DataFactory)
  • 服务器程序将最终的 Recordset 对象返回到客户端应用程序。（代理）
  • 在客户端，将 Recordset 对象转换为可视控件易于使用的格式。（可视控件和 RDS.DataControl）
  • 对 Recordset 对象所做的更改将被发送回服务器，并用于更新数据源。（RDS.DataControl 或 RDSServer.DataFactory）

请参阅

RDS 对象模型汇总 | DataControl 对象 (RDS) | DataFactory 对象 (RDSServer) | DataSpace 对象 (RDS) | RDS 教程 | Recordset 对象 | 使用 RDS


RDS 对象模型汇总

对象 | 说明
RDS.DataSpace | 此对象包含一个获取服务器代理的方法。代理可以是默认值，也可以是自定义服务器程序（业务对象）。 服务器程序可以在 Internet、Intranet、局域网或本地动态链接库上调用。
RDSServer.DataFactory | 此对象表示默认服务器程序。它执行默认的 RDS 数据检索和更新行为。
RDS.DataControl | 此对象可以自动调用 RDS.DataSpace 和 RDSServer.DataFactory 对象。 用此对象调用默认的 RDS 数据检索或更新行为。 此对象还提供了令可视控件访问返回的 Recordset 对象的方法。

请参阅

RDS 基础 | RDS 教程 | 使用 RDS


地址簿应用程序的系统需求

要安装地址簿范例应用程序，需要满足以下软件和数据库需求。

软件需求

运行此 Web 应用程序的服务器软件需求包括：

  • 安装了 Service Pack 3 或更新版本的 Microsoft Windows NT® Server 4.0 ，或者 Microsoft Windows® 2000 Server。
  • 安装了 Active Server Pages 的 Microsoft Internet Information Services (IIS) 版本 3.0 或更新版本。

运行此 Web 应用程序的客户端软件需求包括：

  • Microsoft Internet Explorer 4.0 或更新版本。
  • Microsoft Windows NT 4.0 Workstation 或 Server、Windows 2000 或 Microsoft Windows 98。

数据库需求

要使用本范例，必须有：

  • 可操作的 Microsoft® SQL Server 6.5 或更新版本的数据库服务器。
  • 创建数据库并用范例数据预置此数据库的特权。
  • 通过 Enterprise Manager 或 ISQL 工具（在 SQL Server 7.0 中称为“查询分析器”）验证预置的数据。

如果没有特权，则数据库管理员需要设置系统，并授予您数据库的访问权限，或为您设置数据库。

请参阅

DataControl 对象 (RDS) | 运行地址簿范例应用程序


运行地址簿范例应用程序

请按照下列过程运行地址簿应用程序。

运行此应用程序的步骤

  1. 确保正在运行 Microsoft SQL Server。 单击“开始”，指向“程序”，再指向“Microsoft SQL Server 7.0”，然后单击“服务管理器”。如果在白色圆环中有一个绿色箭头，则说明 SQL 服务器正在运行。如果没有（在白色圆环中有一个红色正方形）。请单击“开始/继续”。
  2. 在 Microsoft Internet Explorer 4.0 或更新版本中，键入如下地址：

    http://webserver/RDS/AddressBook/AddrBook.asp

    其中，webserver 是安装 RDS 服务器组件的 Web 服务器的名称。

  3. 可在地址簿范例应用程序中尝试各种应用方案，例如按电子邮件地址查找人员、列表显示职位为“Program Manager”的所有人，或编辑现有的记录。单击 Find，将所有可用名称填入数据网格。

请参阅

地址簿数据绑定对象


地址簿数据绑定对象

地址簿应用程序使用 RDS.DataControl 对象将 SQL 服务器数据库的数据绑定到应用程序的客户 HTML 页中的可视化对象（此处为 DHTML 表格）。事件驱动的 VBScript 程序逻辑将 RDS.DataControl 用于：

  • 查询数据库、将更新发送到数据库以及刷新数据网格。
  • 让用户移动到数据网格中的第一个、下一个、上一个或最后一个记录。

下列代码定义 RDS.DataControl 组件：

<OBJECT classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33"
   ID=DC1 Width=1 Height=1>
   <PARAM NAME="SERVER" VALUE="http://<%=Request.ServerVariables("SERVER_NAME")%>">
   <PARAM NAME="CONNECT" VALUE="Provider=sqloledb;
Initial Catalog=AddrBookDb;Integrated Security=SSPI;">
</OBJECT>

程序中的 OBJECT 标记定义 RDS.DataControl 组件。该标记包括两种类型的参数：

  • 与一般的 OBJCT 标记相关联的参数。
  • RDS.DataControl 对象特有的参数。

一般的 OBJECT 标记参数

下表描述与 OBJECT 标记相关联的参数。

参数 | 说明
CLASSID | 唯一的 128 位数，标识系统中嵌入对象的类型。此标识符保留在本地计算机的系统注册表中。（有关 RDS.DataControl 对象的类 ID，请参阅 RDS.DataControl 对象。）
ID | 定义嵌入对象在文档范围内的标识符，该标识符用于在代码中标识此嵌入对象。

RDS.DataControl 标记参数

下表描述了 RDS.DataControl 对象特有的参数。（有关 RDS.DataControl 对象参数的完整列表，以及何时实现这些参数，请参阅 RDS.DataControl 对象。）

参数 | 说明
SERVER | 如果使用 HTTP，该值是 http:// 后面所跟的服务器名称。
CONNECT | 提供 RDS.DataControl 连接到 SQL 服务器所必需的连接信息。
SQL | 设置或返回用于检索 Recordset 的查询字符串。

请参阅

地址簿命令按钮


地址簿命令按钮

地址簿应用程序包括下列命令按钮：

  • Find 按钮，用于向数据库提交查询。
  • “Clear”按钮，用于在开始新搜索前清除文本框。
  • Update Profile 按钮，用于保存对雇员记录的更改。
  • Cancel Changes 按钮，用于放弃更改。

“Find”按钮

单击“Find”按钮，激活 VBScript Find_OnClick Sub 过程，此过程将生成并发送 SQL 查询。单击此按钮，预置数据网格。

建立 SQL 查询

Find_OnClick Sub 过程的第一部分生成 SQL 查询（一次一个短语），方法是向全局 SQL SELECT 语句追加文本字符串。该字符串以将变量 myQuery 设置为 SQL SELECT 语句开始，SQL SELECT 语句从数据源表中请求所有数据行。然后，Sub 过程将扫描页面上的全部四个输入框。

因为程序在建立 SQL 语句时使用了单词“like”，所以查询采用子字符串搜索，而不是精确匹配。

例如，如果“Last Name”框包含项目“Berge”，并且“Title”框包含项目“Program Manager”，则 SQL 语句（myQuery 的值）如下：

Select FirstName, LastName, Title, Email, Building, Room, Phone from Employee where lastname like 'Berge%' and title like 'Program Manager%'

如果查询成功，则所有姓中包含“Berge”（如 Berge 和 Berger）而且职务包含“Program Manager”（如 Program Manager，Advanced Technologies）的人都将显示在 HTML 数据网格中。

准备和发送查询

Find_OnClick Sub 过程的最后一部分包括两条语句。第一条语句将 RDS.DataControl 对象的 SQL 属性指定为动态建立的 SQL 查询。第二条语句使 RDS.DataControl 对象 (DC1) 查询数据库，然后在网格中显示查询的新结果。

Sub Find_OnClick
   '...
   DC1.SQL = myQuery
   DC1.Refresh
End Sub

Update Profile 按钮

单击“Update Profile”按钮，激活 VBScript Update_OnClick Sub 过程，此过程执行 RDS.DataControl 对象 (DC1) 的 SubmitChanges 和 Refresh 方法。

Sub Update_OnClick
   DC1.SubmitChanges
   DC1.Refresh
End Sub

当执行 DC1.SubmitChanges 时，远程数据服务将所有更新信息打包，并通过 HTTP 发送到服务器。更新要么全部执行，要么全部不执行。如果更新的一部分不成功，将不做任何更改，并返回状态消息。在远程数据服务中，DC1.Refresh 不一定必须跟在 SubmitChanges 后面，但这样做可确保刷新数据。

“Cancel Changes”按钮

单击“Cancel Changes”，激活 VBScript Cancel_OnClick Sub 过程，此过程将执行 RDS.DataControl 对象 (DC1) 的 CancelUpdate 方法。

Sub Cancel_OnClick
   DC1.CancelUpdate
End Sub

执行 DC1.CancelUpdate 时，它将放弃自从上一次查询或更新以来用户对数据网格上的雇员记录所作的所有编辑。恢复原始值。

请参阅

地址簿定位按钮 | DataControl 对象 (RDS)


地址簿定位按钮

地址簿应用程序在 Web 页的底部显示定位按钮。使用定位按钮，可以通过选择数据的第一行或最后一行，或者通过选择与当前所选行相邻的行，在 HTML 网格显示中定位数据。

定位 Sub 过程

地址簿应用程序包含几个过程，允许用户单击 First、Next、Previous 和 Last 按钮以在数据之间移动。

例如，单击 First 按钮可以激活 VBScript First_OnClick Sub 过程。此过程执行 MoveFirst 方法，使数据的第一行成为当前所选行。单击 Last 按钮可以激活 Last_OnClick Sub 过程，此过程调用 MoveLast 方法，使数据的最后一行成为当前所选行。其余定位按钮的作用与此类似。

' Move to the first record in the bound Recordset.
Sub First_OnClick
   DC1.Recordset.MoveFirst
End Sub

' Move to the next record from the current position
' in the bound Recordset.
Sub Next_OnClick
   If Not DC1.Recordset.EOF Then    ' Cannot move beyond bottom record.
      DC1.Recordset.MoveNext
      Exit Sub
   End If
End Sub

' Move to the previous record from the current position in the bound
' Recordset.
Sub Prev_OnClick
   If Not DC1.Recordset.BOF Then    ' Cannot move beyond top record.
      DC1.Recordset.MovePrevious
      Exit Sub
   End If
End Sub

' Move to the last record in the bound Recordset.
Sub Last_OnClick
   DC1.Recordset.MoveLast
End Sub

请参阅

DataControl 对象 (RDS) | MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法 (RDS)


第 12 章：RDS 教程

本教程举例说明使用 RDS 编程模型查询和更新数据源。首先，它描述了完成此任务所需的步骤。本教程将在 Microsoft Visual Basic Scripting Edition 和具有 ADO for Windows Foundation Classes (ADO/WFC) 功能的 Microsoft Visual J++ 中重复出现。

基于以下两个原因，本教程使用不同的语言代码：

  • RDS 文档假定其读者使用 Visual Basic 进行编程。这对于 Visual Basic 的程序员非常方便，但对于使用其他语言的程序员用处不大。
  • 如果您不熟悉某个特定的 RDS 功能，但对于另一种语言有所了解，那么可以通过在另一种语言中查找相同的功能来解决问题。

关于教程的说明方法

本教程以 RDS 编程模型为基础。它分别讨论了编程模型的每个步骤。另外，它还用 Visual Basic 代码段举例说明每个步骤。

代码范例在其他编程语言中重复出现并有少量论述。给定编程语言教程中的每个步骤在编程模型和描述性教程中都标记有相应的步骤。请用步骤编号来引用描述性教程中的论述。

RDS 编程模型的说明如下。在使用教程时可将其作为参考路线图。

使用对象的 RDS 编程模型

  • 指定要在服务器上调用的程序，并获取从客户端引用该程序的方法（代理）。
  • 调用服务器程序。将参数传递给标识数据源和要发出的命令的服务器程序。
  • 通常，服务器程序通过使用 ADO 从数据源获取 Recordset 对象。也可在服务器上处理 Recordset 对象。
  • 服务器程序将最终的 Recordset 对象返回到客户端应用程序。
  • 在客户端，可选择将 Recordset 对象转换为易于被可视控件使用的格式。
  • 对 Recordset 对象所做的更改将被发送回服务器，并用于更新数据源。

请参阅

步骤 1：指定服务器程序（RDS 教程） | RDS 教程 (VBScript) | RDS 教程 (Visual J++)


步骤 1：指定服务器程序（RDS 教程）

在大多数情况下都可用 RDS.DataSpace 对象的 CreateObject 方法来指定默认服务器程序 RDSServer.DataFactory 或指定自定义的服务器程序（业务对象）。在服务器上将服务器程序实例化，并且返回对服务器程序（即“代理”）的引用。

本教程使用默认服务器程序：

Sub RDSTutorial1()
   Dim DS as New RDS.DataSpace
   Dim DF as Object
   Set DF = DS.CreateObject("RDSServer.DataFactory", "http://yourServer")
...

请参阅

步骤 2：调用服务器程序（RDS 教程） | RDS 教程 (VBScript) | RDS 教程 (Visual J++)


步骤 2：调用服务器程序（RDS 教程）

当调用客户端“代理”上的某种方法时，服务器上的实际程序将执行该方法。在此步骤中，您将在服务器上执行一个查询。

A 部分 如果未在本教程中使用 RDSServer.DataFactory，那么执行本步骤最方便的途径是使用 RDS.DataControl 对象。RDS.DataControl 将上一步（创建代理）和本步骤（发出查询）结合起来。

设置 RDS.DataControl 对象的 Server 属性以标识实例化服务器程序的位置；设置 Connect 属性以指定访问数据源的连接字符串；设置 SQL 属性以指定查询命令文本。然后发出 Refresh 方法，使服务器程序连接到数据源、检索查询指定的行以及将 Recordset 对象返回到客户端。

本教程不使用 RDS.DataControl，但如果使用的话，其形式如下：

Sub RDSTutorial2A()
   Dim DC as New RDS.DataControl
   DC.Server = "http://yourServer"
   DC.Connect = "DSN=Pubs"
   DC.SQL = "SELECT * FROM Authors"
   DC.Refresh
...

本教程也不通过 ADO 对象调用 RDS，但是如果调用 RDS，其形式如下：

Dim rs as New ADODB.Recordset
rs.Open "SELECT * FROM Authors","Provider=MS Remote;Data Source=Pubs;" & _
        "Remote Server=http://yourServer;Remote Provider=SQLOLEDB;"

B 部分 执行本步骤的常规方法是调用 RDSServer.DataFactory 对象的 Query 方法。该方法接受用于连接到数据源的连接字符串，还接受用于指定要从数据源返回的行的命令文本。

本教程使用 DataFactory 对象 Query 方法：

Sub RDSTutorial2B()
   Dim DS as New RDS.DataSpace
   Dim DF
   Dim RS as ADODB.Recordset
   Set DF = DS.CreateObject("RDSServer.DataFactory", "http://yourServer")
   Set RS = DF.Query ("DSN=Pubs", "SELECT * FROM Authors")
...

请参阅

步骤 3：服务器获取 Recordset（RDS 教程） | RDS 教程 (VBScript) | RDS 教程 (Visual J++)


步骤 3：服务器获取 Recordset（RDS 教程）

服务器程序用连接字符串和命令文本查询数据源，以获得所需要的行。尽管可以使用其他 Microsoft 数据访问接口（例如 OLE DB），但通常还是用 ADO 检索此 Recordset。

自定义服务器程序的形式如下：

Public Function ServerProgram(cn as String, qry as String) as Object
Dim rs as New ADODB.Recordset
   rs.CursorLocation = adUseClient
   rs.Open qry, cn
   rs.ActiveConnection = Nothing
   Set ServerProgram = rs
End Function

请参阅

步骤 4：服务器返回 Recordset（RDS 教程） | RDS 教程 (VBScript) | RDS 教程 (Visual J++)


步骤 4：服务器返回 Recordset（RDS 教程）

RDS 将检索到的 Recordset 对象转换为可以被发送回客户端的格式（即“调度”Recordset）。转换的确切格式及发送方式取决于服务器是在 Internet、Intranet 或局域网上，还是在动态链接库上。但细节并不重要，重要的是 RDS 将 Recordset 发送回客户端。

在客户端，返回 Recordset 对象并为其分配一个本地变量。

Sub RDSTutorial4()
   Dim DS as New RDS.DataSpace
   Dim RS as ADODB.Recordset
   Dim DF as Object
   Set DF = DS.CreateObject("RDSServer.DataFactory", "http://yourServer")
   Set RS = DF.Query("DSN=Pubs", "SELECT * FROM Authors")
...

请参阅

步骤 5：启用 DataControl（RDS 教程） | RDS 教程 (VBScript) | RDS 教程 (Visual J++)


步骤 5：启用 DataControl（RDS 教程）

可以使用返回的 Recordset 对象。可以像处理任何其他 Recordset 一样检查、定位或编辑该对象。用 Recordset 可以进行的操作取决于您所在的环境。Visual Basic 和 Visual C++ 包含可视控件。在启用数据控件时，这些可视控件可以直接或间接地使用 Recordset。

例如，在 Microsoft Internet Explorer 中显示 Web 页时，您可能想在可视控件中显示 Recordset 对象数据。Web 页上的可视控件不能直接访问 Recordset 对象。但是它们可以通过 RDS.DataControl 访问 Recordset 对象。当可视控件的 SourceRecordset 属性设置为 Recordset 对象时，便可以通过它使用 RDS.DataControl。

必须将可视控件对象的 DATASRC 参数设置为 RDS.DataControl，将其 DATAFLD 属性设置为 Recordset 对象字段（列）。

在本教程中设置 SourceRecordset 属性。

Sub RDSTutorial5()
   Dim DS as New RDS.DataSpace
   Dim RS as ADODB.Recordset
   Dim DC as New RDS.DataControl
   Dim DF as Object
   Set DF = DS.CreateObject("RDSServer.DataFactory", "http://yourServer")
   Set RS = DF.Query ("DSN=Pubs", "SELECT * FROM Authors")
   DC.SourceRecordset = RS         ' Visual controls can now bind to DC.
...

请参阅

步骤 6：将更改发送到服务器（RDS 教程） | RDS 教程 (VBScript) | RDS 教程 (Visual J++)


步骤 6：将更改发送到服务器（RDS 教程）

如果对 Recordset 对象进行了编辑，那么所有更改（即添加、更改或删除的行）都可以发送回服务器。

注意 通过 ADO 对象和 Microsoft OLE DB Remoting Provider 可以隐式调用 RDS 的默认行为。查询可以返回 Recordset，而编辑过的 Recordset 可以更新数据源。本教程不调用使用 ADO 对象的 RDS，但是如果调用，其形式如下：
Dim rs as New ADODB.Recordset
rs.Open "SELECT * FROM Authors","Provider=MS Remote;Data Source=Pubs;" & _
        "Remote Server=http://yourServer;Remote Provider=SQLOLEDB;"
...              ' Edit the Recordset.
rs.UpdateBatch   ' The equivalent of SubmitChanges.
...

A 部分 这种情况下，假定只使用了 RDS.DataControl，并且 Recordset 对象现在是与 RDS.DataControl 相关联的。如果仍设置了 Server 和 Connect 属性，那么 SubmitChanges 方法将使用对 Recordset 对象所作的所有更改来更新数据源。

Sub RDSTutorial6A()
Dim DC as New RDS.DataControl
Dim RS as ADODB.Recordset
DC.Server = "http://yourServer"
DC.Connect = "DSN=Pubs"
DC.SQL = "SELECT * FROM Authors"
DC.Refresh
...
Set RS = DC.Recordset
   ' Edit the Recordset.
...
DC.SubmitChanges
...

B 部分 另外，您可以用指定连接和 Recordset 对象的 RDSServer.DataFactory 对象更新服务器。

Sub RDSTutorial6B()
Dim DS As New RDS.DataSpace
Dim RS As ADODB.Recordset
Dim DC As New RDS.DataControl
Dim DF As Object
Dim blnStatus As Boolean
Set DF = DS.CreateObject("RDSServer.DataFactory", "http://yourServer")
Set RS = DF.Query ("DSN=Pubs", "SELECT * FROM Authors")
DC.SourceRecordset = RS    ' Visual controls can now bind to DC.
    ' Edit the Recordset.
blnStatus = DF.SubmitChanges "DSN=Pubs", RS
End Sub

本教程到此结束。

请参阅

Microsoft OLE DB Remoting Provider | RDS 教程 | RDS 教程 (VBScript) | RDS 教程 (Visual J++)


RDS 教程 (VBScript)

这是用 Microsoft Visual Basic Scripting Edition 编写的 RDS 教程。有关本教程的目的描述，请参阅 RDS 教程。

在本教程中，RDS.DataControl 和 RDS.DataSpace 是在设计时创建的，即用对象标记进行定义，如下所示：<OBJECT>...</OBJECT>。或者，也可以用 Server.CreateObject 方法在运行时创建。例如，可以将 RDS.DataControl 对象创建为如下形式：

Set DC = Server.CreateObject("RDS.DataControl")
   <!-- RDS.DataControl -->
   <OBJECT
      ID="DC1" CLASSID="CLSID:BD96C556-65A3-11D0-983A-00C04FC29E33">
   </OBJECT>

   <!-- RDS.DataSpace -->
   <OBJECT
      ID="DS1" WIDTH=1 HEIGHT=1
      CLASSID="CLSID:BD96C556-65A3-11D0-983A-00C04FC29E36">
   </OBJECT>

   <SCRIPT LANGUAGE="VBScript">

   Sub RDSTutorial()
   Dim DF1

步骤 1 — 指定服务器程序

通过访问对 Active Server Pages 有效的 VBScript Request.ServerVariables 方法，VBScript 可以找到它所在的 IIS Web 服务器的名称：

"http://<%=Request.ServerVariables("SERVER_NAME")%>"

但是，本教程将使用假想的服务器“yourServer”。

注意 请注意 ByRef 参数的数据类型。VBScript 不允许指定变量类型，所以必须始终传递 Variant。使用 HTTP 时，如果通过 RDS.DataSpace 对象 CreateObject 方法调用 Variant，RDS 将允许您把 Variant 传递给需要非 Variant 的方法。当使用 DCOM 或 In-process 服务器时，请匹配客户端和服务器端的参数类型，否则将收到“类型不匹配”的错误信息。
Set DF1 = DS1.CreateObject("RDSServer.DataFactory", "http://yourServer")

步骤 2a — 通过 RDS.DataControl 调用服务器程序

本范例只演示了 RDS.DataControl 的默认行为是执行指定查询。

<OBJECT CLASSID="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" ID="DC1">
   <PARAM NAME="SQL" VALUE="SELECT * FROM Authors">
   <PARAM NAME="Connect" VALUE="DSN=Pubs;">
   <PARAM NAME="Server" VALUE="http://yourServer/">
</OBJECT>
...
<SCRIPT LANGUAGE="VBScript">

Sub RDSTutorial2A()
   Dim RS
   DC1.Refresh
   Set RS = DC1.Recordset
...

步骤 2b — 通过 RDSServer.DataFactory 调用服务器程序

步骤 3 — 服务器获取 Recordset

步骤 4 — 服务器返回 Recordset

Set RS = DF1.Query("DSN=Pubs;", "SELECT * FROM Authors")

步骤 5 — 通过可视控件启用 DataControl

' Assign the returned recordset to the DataControl.

DC1.SourceRecordset = RS

步骤 6a — 通过 RDS.DataControl 将更改发送到服务器

本范例只是演示了 RDS.DataControl 执行更新的方法。

<OBJECT CLASSID="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" ID="DC1">
   <PARAM NAME="SQL" VALUE="SELECT * FROM Authors">
   <PARAM NAME="Connect" VALUE="DSN=Pubs;">
   <PARAM NAME="Server" VALUE="http://yourServer/">
</OBJECT>
...
<SCRIPT LANGUAGE="VBScript">

Sub RDSTutorial6A()
Dim RS
DC1.Refresh
...
Set RS = DC1.Recordset
' Edit the Recordset object...
' The SERVER and CONNECT properties are already set from Step 2A.
Set DC1.SourceRecordset = RS
...
DC1.SubmitChanges

步骤 6b — 通过 RDSServer.DataFactory 将更改发送到服务器

DF.SubmitChanges "DSN=Pubs", RS

End Sub
</SCRIPT>
</BODY>
</HTML>

本教程到此结束。

请参阅

RDS 教程 | RDS 教程 (Visual J++)


RDS 教程 (Visual J++)

ADO/WFC 不完全遵循 RDS 对象模型，因为它不实现 RDS.DataControl 对象。ADO/WFC 只实现客户端类 RDS.DataSpace。

DataSpace 类实现 CreateObject 方法，此方法返回 ObjectProxy 对象。DataSpace 类还实现 InternetTimeout 属性。

ObjectProxy 类实现 call 方法，此方法可以调用任何服务器端的业务对象。

这是本教程的开始部分。

import com.ms.wfc.data.*;
public class RDSTutorial
{
   public void tutorial()
   {
// Step 1: Specify a server program.
      ObjectProxy obj =
         DataSpace.createObject(
            "RDSServer.DataFactory",
            "http://YourServer");

// Step 2: Server returns a Recordset.
      Recordset rs = (Recordset) obj.call(
            "Query",
            new Object[] {"DSN=Pubs;", "SELECT * FROM Authors"});

// Step 3: Changes are sent to the server.
      ...                        // Edit Recordset.
      obj.call(
            "SubmitChanges",
            new Object[] {"DSN=Pubs;", rs});
      return;
   }
}

本教程到此结束。

请参阅

RDS 教程 | RDS 教程 (VBScript)


第 13 章：RDS 用法和安全性

使用本章中的信息可以快速安装服务器并使用 RDS。这些信息包括：实现 RDS 时可能需要的特定配置步骤，描述 RDS 与其他技术之间的一些关键关系，以及用户遇到安装 RDS 问题时的解决方案。

本节包含下列信息：

  • 配置 RDS
  • 使用 RDS 和相关技术
  • DataFactory 自定义
  • RDS 疑难解答

请参阅

RDS 基础 | RDS 教程


配置 RDS

要有效地实现 RDS，请确保熟悉各种可用的配置。本节包括实现 RDS 过程中有关安全性和可升级性的重要信息。有关配置计算机以使用 RDS 的信息，请参阅下列主题：

  • 授予 Web 服务器计算机客户特权
  • 注册自定义业务对象
  • 将业务对象标记为可安全执行脚本
  • 在客户端注册业务对象以便配合 DCOM 使用
  • 设置 DCOM 流调度格式
  • 启用 DLL 以在 DCOM 上运行
  • 在 IIS 上配置虚拟服务器
  • 在 IIS 上指定每个处理程序的线程数
  • 保护 RDS 应用程序
  • 将 DataFactory 配置为安全或无限制模式

请参阅

使用 RDS 和相关技术 | DataFactory 自定义 | RDS 疑难解答


授予 Web 服务器计算机客户特权：RDS 客户特权 [ADO]

RDS 2.5

授予 Web 服务器计算机客户特权

必须向 Web 服务器计算机上的 Guests 本地组添加匿名 Web 服务器帐户 (IUSR_ComputerName)，以使用 RDS。

授予 Web 服务器计算机客户特权的步骤

  1. 在 Microsoft Windows 2000 Server 计算机上，单击“开始”，指向“程序”，再指向“管理工具”，然后再单击“计算机管理”。
  2. 在控制台树中，单击“本地用户和组”中的“组”。
  3. 选择“Guests”本地组。从“操作”菜单中选择“属性”。
  4. 在“Guests 属性”对话框中单击“添加”。
  5. 如果“选择用户或组”对话框的列表中未显示匿名 Web 服务器帐户，请在底部的空白框中键入其名称 (IUSR_ComputerName)，然后单击“添加”。
  6. 单击“确定”。


注册自定义业务对象

要通过 Web 服务器成功地启动自定义业务对象（.dll 或 .exe），必须按本过程的说明在注册表中输入业务对象的 ProgID。本 RDS 功能只运行经过认可的可执行程序，以此保证 Web 服务器的安全。

注意 对于 MDAC 2.0 和更新版本，默认业务对象 RDSServer.DataFactory 在默认情况下未在安装 MDAC 过程中进行注册。但是，如果安装之前 RDSServer.DataFactory 就已在计算机上被注册为可安全执行，那么注册表项目将保留以用于新的安装。

注册自定义业务对象的步骤

  1. 单击“开始”，然后单击“运行”。
  2. 键入 RegEdit，然后单击“确定”。
  3. 在注册表编辑器中，请定位到：HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\W3SVC\Parameters\ADCLaunch 注册表项。
  4. 选择“ADCLaunch”项，指向“编辑”菜单上的“新建”，然后单击“项”。
  5. 键入自定义业务对象的 ProgID，然后单击 Enter。使“值”项保留为空白。


将业务对象标记为可安全执行脚本

为确保 Internet 环境的安全，需要将通过 RDS.DataSpace 对象 CreateObject 方法进行实例化的所有业务对象标记为“可安全执行脚本”。在能够在 DCOM 中使用之前，应确保在系统注册表的 License 区域中对这些业务对象作了上述标记。

要手动将业务对象标记为可安全执行脚本，请创建一个包含以下文本、扩展名为 .reg 的文本文件。用以下两个编号启用可安全执行脚本功能：

[HKEY_CLASSES_ROOT\CLSID\<MyActiveXGUID>\Implemented
Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}]
[HKEY_CLASSES_ROOT\CLSID\<MyActiveXGUID>\Implemented
Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}]

其中，<MyActiveXGUID> 是业务对象的十六进制 GUID 编号。将其保存，然后通过使用注册表编辑器或在 Windows 资源管理器中双击 .reg 文件将其合并到注册表中。

在 Microsoft Visual Basic 中创建的业务对象可通过 Package and Deployment Wizard 被自动标记为“可安全执行脚本”。如果向导要求指定安全设置，请选择 Safe for initialization 和 Safe for scripting。

在最后一个步骤中，Application Setup Wizard 将创建一个 .htm 和一个 .cab 文件。然后可以将这两个文件复制到目标计算机上，双击 .htm 文件以加载页面并正确注册服务器。

由于默认情况下业务对象将被安装在 Windows\System32\Occache 目录中，因此应将其移动到 Windows\System32 目录并更改 HKEY_CLASSES_ROOT\CLSID\<MyActiveXGUID>\InprocServer32 注册表项以与正确的路径相匹配。

注意 标记为可安全执行脚本和可安全初始化的业务对象可以由网络上的任何人进行实例化和初始化。不得任意地设计和执行自定义的业务对象。这是强制的，以便这种对象不存在黑克可以获得对宿主服务器敏感区域的访问并造成损害的安全威胁。


在客户端注册业务对象以便配合 DCOM 使用

自定义业务对象需要确保客户端能将其程序名称 (ProgId) 映射到可用于 DCOM 的标识符 (CLSID)。因此，DCOM 对象的 ProgID 必须在客户端注册表中，并且映射到服务器端业务对象的类 ID。其他受支持的协议（HTTP、HTTPS 和 In-process）则无此要求。

例如，如果要显露具有特定类 ID（如“{00112233-4455-6677-8899-00AABBCCDDEE}”）、名为 MyBObj 的服务器端业务对象，应确保以下项目已被添加到客户端注册表中：

[HKEY_CLASSES_ROOT]
\MyBObj
    \Clsid
    (Default) "{00112233-4455-6677-8899-00AABBCCDDEE}"


设置 DCOM 流调度格式

使用 RDS 1.5 或更早版本中组件的客户端计算机与使用 RDS 2.0 或更新版本中组件的服务器不兼容。将 DCOM 用作基本协议时，支持 RDS 2.0 或更新版本在传送 Recordset 对象时效率更高。如果客户端运行的是 RDS 1.5 或更早版本的组件，可以将服务器设置为使用以前的 RDS 支持（称为 RDS 1.0）或更新的 RDS 支持（称为 RDS 2.0 或更新版本）。请对下列注册表项目之一进行设置：

[HKEY_CLASSES_ROOT]
\CLSID
    \[58ECEE30-E715-11CF-B0E3-00AA003F000F}
        \ADTGOptions]"MarshalFormat"="RDS10"

-或-

[HKEY_CLASSES_ROOT]
\CLSID
    \[58ECEE30-E715-11CF-B0E3-00AA003F000F}
        \ADTGOptions]"MarshalFormat"="RDS20"


启用 DLL 以在 DCOM 上运行

以下步骤概括了如何通过 Component Services 启用业务对象 .dll，以便同时使用 DCOM 和 Microsoft Internet Information Services (HTTP)。

  1. 在 Component Services MMC 管理单元中创建一个新的空包。

    您将使用 Component Services MMC 管理单元创建包并将 DLL 添加到该包。这样便可通过 DCOM 访问 .dll，但不能通过 IIS 对其进行访问。（如果在注册表中检查 .dll，Inproc 键现在为空；设置 Activation 属性可在 Inproc 键中添加值。稍后本主题将对该属性进行解释。）

  2. 将业务对象安装到包中。

    -或-

    将 RDSServer.DataFactory 对象导入包。

  3. 将包的 Activation 属性设置为 In the creator's process（库应用程序）。

    要在同一台计算机上通过 DCOM 和 IIS 访问 .dll，必须在 Component Services MMC 管理单元中设置组件的 Activation 属性。在将属性设置为 In the creator's process 之后，您会发现注册表中已添加了 Inproc 服务器键，此键指向 Component Services，而不是 .dll。

有关 Component Services（如果使用 Windows NT，则为 Microsoft Transaction Service）以及如何执行这些步骤的详细信息，请参阅 Component Services 文档或访问 Transaction Server 网站：http://www.microsoft.com/com/tech/mts.asp。


在 IIS 上配置虚拟服务器

在 Internet Information Services 4.0 中创建虚拟服务器时，要将虚拟服务器配置为使用 RDS，需要执行以下两个额外步骤：

  1. 安装服务器时，请选择“Allow Execute Access”。
  2. 将 msadcs.dll 移到 vroot\msadc。其中，vroot 是虚拟服务器的主目录。

请参阅

RDS 基础


在 IIS 上指定每个处理程序的线程数

当在 Internet Information Services (IIS) 4.0 或更新版本中使用 RDS 时，可通过对 Web 服务器上的注册表进行操作来控制每个处理程序所创建的线程数。每个处理程序中的线程数在高流量情况或低流量但查询量大的情况下将影响性能。用户应进行试验以获得最佳结果。

用于确定和更改此设置默认值的方法取决于 IIS 4.0 服务器的配置。

通过安装在 IIS 服务器上的 MDAC 2.1.2.4202.3 (GA) 或更新版本，RDS 和 ASP 脚本使用相同的 Component Services（如果使用 Windows NT，则为 Microsoft Transaction Services）线程缓冲池。每个处理程序的线程数的默认值为 10。若要更改此默认值，必须向服务器注册表添加以下键：

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\InetInfo\Parameters\MaxPoolThreads

其中，MaxPoolThreads 为 REG_DWORD。如果没有专门添加，注册表中将不显示 MaxPoolThreads。有效值范围是从 5 到建议的最大值 20。如果由注册表键指定的值大于 PoolThreadLimit 键（位于相同的路径下）的值，将使用 PoolThreadLimit 值。

或者，如果 IIS 服务器上安装了 MDAC 2.1 2.1.1.3711.11 (GA) 或更早版本，那么每个处理程序的线程数的默认值为 6。若要更改此默认值，必须向 IIS 服务器的注册表添加以下键：

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC\Parameters\ADCThreads

其中，ADCThreads 为 REG_DWORD。如果没有专门添加，注册表中将不显示 ADCThreads。有效值范围是从 1 到 50。如果注册表键指定的值大于 50，将使用最大值 (50)。

请参阅

RDS 基础


保护 RDS 应用程序

Microsoft Internet Explorer 安全问题

由于向 Microsoft Internet Explorer 添加了新的安全增强功能，某些 ADO 和 RDS 对象 被限制为只能在“安全”模式环境下运行。这就需要用户了解这些问题，包括不同区域、安全级别、限制性行为、不安全操作和自定义安全设置。

有关这些问题的详细信息，请参阅 ActiveX Data Objects (ADO) Technical Articles 下的 ADO and RDS Security Issues in Microsoft Internet Explorer。

安全性和 Web 服务器

如果在 Internet Web 服务器上使用 RDSServer.DataFactory 对象，请记住这会引起潜在的安全问题。获取有效数据源名称 (DSN)、用户 ID 和密码信息的外部用户可以编写页面，将所有查询发送到该数据源。如果希望对数据源的访问有更多的限制，一种选择是取消注册并删除 RDSServer.DataFactory 对象 (msadcf.dll)，而代之以通过硬编码查询来使用自定义业务对象。

有关使用 RDSServer.DataFactory 对象隐含安全性的详细信息，请参阅 Microsoft Security 网站 http://www.microsoft.com/security/default.asp 上的 Microsoft Security Bulletin MS99-025。

客户端模拟和安全性

如果将 IIS Web 服务器的“密码验证”属性设置为 Windows NT 请求/响应验证（对于 Windows NT 4.0）或集成 Windows 验证（对于 Windows 2000），则将在客户端的安全上下文中调用业务对象。这是 RDS 1.5 中的新增功能，它允许通过 HTTP 进行客户端模拟。在这种模式下工作时，登录 Web 服务器 (IIS) 不是匿名的，而是使用客户端计算机运行时所使用的用户 ID 和密码。如果 ODBC DSN 设置为使用可靠连接，那么对诸如 SQL Server 的数据库的访问也是在客户端的安全性上下文中进行。但这种机制只有当数据库与 IIS 在同一台计算机上时才可行，客户凭据不能被转移到其他计算机上。

例如，userid="JohnD"、password="secret" 的客户 John Doe 登录到客户端计算机上。他运行基于浏览器的应用程序，该应用程序需要访问 RDSServer.DataFactory 对象，以通过在运行 IIS 的“MyServer”计算机上执行 SQL 查询来创建 Recordset。运行 Windows NT Server 4.0 的 MyServer 系统被设置为使用“Windows NT 请求/响应”验证，其 ODBC DSN 已选择“使用可靠连接”，服务器还包含 SQL Server 数据源。当 Web 服务器上接收到请求时，它要求客户端输入用户 ID 和密码。因此，请求被当作从 "JohnD"/"Secret" 而不是 IUSER_MyServer（“匿名密码验证”打开时的默认值）登录到 MyServer。与此类似，登录 SQL Server 时，也使用 "JohnD"/"Secret"。

因此，IIS Windows NT 请求/响应验证模式允许创建 HTML 页面，而无需显式提示用户输入登录到数据库所需的用户 ID 和密码信息。如果使用 IIS 基本验证，则需要输入用户 ID 和密码信息。

密码验证

RDS 能够与在下述三种密码验证模式之一下运行的 IIS Web 服务器进行通讯：匿名、基本或 NT 请求/响应验证（在 Windows 2000 中称为“集成 Windows”验证）。这些设置定义 Web 服务器如何控制通过它的访问，例如要求客户端计算机在 NT Web 服务器上有显式访问特权。


将 DataFactory 配置为安全和无限制模式

RDS 2.5

将 DataFactory 配置为安全或无限制模式

默认情况下，ADO 是用“安全的”RDSServer.DataFactory 配置安装的。RDS Server 组件的安全模式表明存在下列情况：

  1. RDSServer.DataFactory 需要处理程序（这是由注册表键设置控制的）。
  2. 默认处理程序 msdfmap.handler 被注册并显示在安全处理程序列表中，被标记为默认处理程序。
  3. Msdfmap.ini 文件安装在 Windows 目录中。在三层模式中使用 RDS 前，必须根据需要配置此文件。

可以有选择地配置无限制的 DataFactory 安装。DataFactory 可以直接使用，而无需自定义处理程序。用户仍然可以通过修改连接字符串来使用自定义处理程序，但这不是必须的。有关使用 RDSServer.DataFactory 对象的隐含的详细信息，请参阅保护 RDS 应用程序。

注册表文件 handsafe.reg 用于为安全配置设置处理程序的注册表项目。若要以安全模式运行，请运行 handsafe.reg。注册表文件 handunsf.reg 用于为无限制的配置设置处理程序注册表项。要以无限制模式运行，请运行 handunsf.reg。

在运行完 handsafe.reg 或 handunsf.reg 后，必须停止并重新启动 Web 服务器上的万维网发布服务，方法是在命令窗口中键入以下命令：NET STOP W3SVC 和 NET START W3SVC。

有关使用 RDS 的自定义处理程序功能的详细信息，请参阅技术文章“Using the Customization Handler Feature in RDS 2.1”

请参阅

DataFactory 自定义 | RDS 基础


使用 RDS 和相关技术

本节包含有关通过下列技术使用 RDS 的特定信息：

  • ODBC Connection Pooling
  • Microsoft Component Services

许多其他技术与远程数据服务相互作用或在远程数据服务的实现中使用。

Internet Information Services 有关 Microsoft Internet Information Services (IIS) 或 Active Server Pages (ASP) 的详细信息，请参阅 IIS Web 站点 http://www.microsoft.com/ntserver/web/exec/feature/Datasheet.asp。

Microsoft Component Services 有关 Component Services（在 Windows NT 中，则为 Microsoft Transaction Server）的详细信息，请参阅 Windows Web 页 http://www.microsoft.com/windows/default.asp。有关 Microsoft Transaction Server 的详细信息，请参阅 MTS Web 站点 http://www.microsoft.com/com/tech/mts.asp。

Microsoft SQL Server 有关 Microsoft SQL Server 的详细信息，请参阅 SQL Server 网站 http://www.microsoft.com/sql/。

Microsoft Internet Explorer 有关 Microsoft Internet Explorer 的详细信息，请参阅 Internet Explorer Web 页 http://www.microsoft.com/windows/ie/default.htm 和 MSDN Online Web Workshop 页 http://msdn.microsoft.com/workshop/default.asp。

Microsoft Windows NT Server/Windows 2000 Server 有关 Microsoft Windows NT Server 或 Windows 2000 Server 中安全性的详细信息，请参阅 Windows Web 页 http://www.microsoft.com/windows/default.asp。

请参阅

RDS 基础


将 RDS 与 ODBC Connection Pooling 配合使用

如果在使用 ODBC 数据源，可以使用 Internet Information Services (IIS) 中的连接缓冲池选项来提高处理客户端负载的性能。连接缓冲池是连接的资源管理器，它用于维护经常使用的连接的打开状态。

要启用连接缓冲池，请参阅 Internet Information Services 文档。

请注意，启用连接缓冲池可能使 Web 服务器受到其他限制，如 Microsoft Internet Information Services 文档中所述。

要确保连接缓冲池稳定并提供附加性能，必须对 Microsoft SQL Server 进行配置以使用 TCP/IP 套接字网络库。

要达到此目的，需要：

  • 配置 SQL Server 计算机以使用 TCP/IP 套接字。
  • 配置 Web 服务器以使用 TCP/IP 套接字。

配置 SQL Server 计算机以使用 TCP/IP 套接字

在 SQL Server 计算机上，运行 SQL Server Setup 程序以便与数据源的相互作用能够使用 TCP/IP Socket 网络库。

在 SQL Server 计算机上指定 TCP/IP 套接字网络库的步骤

在 Microsoft SQL Server 6.5 中：

  1. 在“开始”菜单上指向“程序”，再指向“Microsoft SQL Server 6.5”，然后单击“SQL 安装程序”。
  2. 单击“继续”两次。
  3. 在“Microsoft SQL Server — 选项”对话框中，选择“更改网络支持”，然后单击“继续”。
  4. 请确保选中了“TCP/IP 套接字”复选框，然后单击“确定”。
  5. 单击“继续”结束操作，并退出安装。

在 Microsoft SQL Server 7.0 中：

  1. 在“开始”菜单上指向“程序”，再指向“Microsoft SQL Server 7.0”，然后单击“服务器网络实用程序”。
  2. 在对话框的“常规”选项卡上单击“添加”。
  3. 在“添加网络库配置”对话框中单击“TCP/IP”。
  4. 在“端口号”和“代理地址”框中，输入网络管理员提供的端口号和代理地址。
  5. 单击“确定”结束操作，并退出安装。

配置 Web Server 以使用 TCP/IP 套接字

配置 Web 服务器以使用 TCP/IP 套接字有两种选择。用户所作的选择取决于是否所有 SQL Server 均从 Web 服务器进行访问，还是仅特定的 SQL Server 是从 Web 服务器访问。

如果所有 SQL Server 均是从 Web 服务器访问的，需要在 Web 服务器计算机上运行 SQL Server 客户端配置实用程序。以下步骤更改由该 IIS Web 服务器建立的所有 SQL Server 连接的默认网络库，以使用 TCP/IP 套接字网络库。

配置 Web 服务器（所有 SQL Server）的步骤

对于 Microsoft SQL Server 6.5：

  1. 在“开始”菜单上指向“程序”，再指向“Microsoft SQL Server 6.5”，然后单击“SQL 客户端配置实用程序”。
  2. 单击“网络库”选项卡。
  3. 在“默认网络”框中，选择“TCP/IP 套接字”。
  4. 单击“完成”，保存更改，然后退出实用程序。

对于 Microsoft SQL Server 7.0：

  1. 在“开始”菜单上指向“程序”，再指向“Microsoft SQL Server 7.0”，然后单击“客户端配置实用程序”。
  2. 单击“常规”选项卡。
  3. 在“默认网络库”框中单击“TCP/IP”。
  4. 单击“确定”，保存更改，然后退出实用程序。

如果特定的 SQL Server 是从 Web 服务器访问，需要在 Web 服务器计算机上运行 SQL Server 客户端配置实用程序。要更改特定 SQL Server 连接的网络库，请按照下列步骤在 Web 服务器计算机上配置 SQL Server 客户端软件。

配置 Web 服务器（特定 SQL Server）的步骤

对于 Microsoft SQL Server 6.5：

  1. 在“开始”菜单上指向“程序”，再指向“Microsoft SQL Server 6.5”，然后单击“SQL 客户端配置实用程序”。
  2. 单击“高级”选项卡。
  3. 在“服务器”框中，键入为使用 TCP/IP 套接字而连接的服务器名称。
  4. 在“DLL 名称”框中，选择“TCP/IP 套接字”。
  5. 单击“添加/修改”。指向此服务器的所有数据源现在都将使用 TCP/IP 套接字。
  6. 单击“完成”。

对于 Microsoft SQL Server 7.0：

  1. 在“开始”菜单上指向“程序”，再指向“Microsoft SQL Server 7.0”，然后单击“客户端配置实用程序”。
  2. 单击“常规”选项卡。
  3. 单击“添加”。
  4. 在“服务器别名”框中输入该服务器的别名。在“网络库”框中单击“TCP/IP”。在“计算机名称”框中，输入侦听 TCP/IP 套接字客户端的计算机名称。在“端口号”框中，输入 SQL Server 要侦听的端口。
  5. 单击“确定”，再单击“确定”以退出实用程序。

请参阅

RDS 基础


在 Component Services 中运行业务对象

业务对象可以是可执行文件 (.exe) 或动态链接库 (.dll)。用于运行业务对象的配置取决于该对象是 .dll 还是 .exe 文件：

  • 创建为 .exe 文件的业务对象可通过 DCOM 调用。如果通过 Internet Information Services (IIS) 使用这些业务对象，它们将受数据的附加调度的支配，这将降低客户端性能。
  • 创建为 .dll 文件的业务对象可通过 IIS（还有 HTTP）使用。它们只能通过 Component Services（如果使用 Windows NT，则为 Microsoft Transaction Server）在 DCOM 上使用。业务对象 DLL 需要在 IIS 服务器计算机上注册，开能通过 IIS 进行访问。（有关配置 DLL 以在 DCOM 上运行的步骤，请参阅“启用 DLL 以在 DCOM 上运行”一节。）
注意 当中间层上的业务对象被当作 Component Services 组件实现时（使用 GetObjectContext、SetComplete 和 SetAbort），它们可以使用 Component Services（如果使用 Windows NT，则为 MTS）上下文对象在多个客户端调用之间维护其状态。此方案对于 DCOM 是可能的，DCOM 通常在可靠客户端和服务器 (Intranet) 之间实现。在这种情况下，客户端的 RDS.DataSpace 对象和 CreateObject 方法被事务上下文对象和 CreateInstance 方法（由 ITransactionContext 接口提供）替换，并由 Component Services 实现。

请参阅

RDS 基础


DataFactory 自定义

远程数据服务 (RDS) 提供了一种在三层客户/服务器系统中执行数据访问的简便方法。客户端数据控制指定执行远程数据源查询的连接参数和命令字符串参数，或指定执行更新的连接字符串和 Recordset 对象参数。

将参数传递给服务器程序，该服务器程序执行远程数据源上的数据访问操作。RDS 提供称为 RDSServer.DataFactory 对象的默认服务器程序。RDSServer.DataFactory 对象将查询所产生的所有 Recordset 对象返回到客户端。

但是，RDSServer.DataFactory 仅限于执行查询和更新。它不能对连接和命令字符串执行任何确认或处理。

用 ADO 可以指定将 DataFactory 与另一种类型的服务器程序（称为“处理程序”）结合使用。处理程序可以修改客户端连接和命令字符串，然后用它们访问数据源。另外，处理程序强制实施访问权限，该权限决定客户端向数据源读取和写入数据的能力。

处理程序用来修改客户端参数和访问权限的参数在自定义文件的各节中指定。

有关自定义 DataFactory 对象的详细信息，请参阅如下主题：

  • 了解自定义文件
  • 自定义文件 Connect 节
  • 自定义文件 SQL 节
  • 自定义文件 UserList 节
  • 自定义文件 Logs 节
  • 所需的客户端设置
  • 编写自定义处理程序


了解自定义文件

自定义文件中的每个节标头均由包含类型和参数的方括号 ([]) 组成。四种节类型分别由文字字符串 connect、sql、userlist 或 logs 指示。参数可以是文字字符串、默认值、用户指定的标识符或无。

因此，每个节都用下列节标头之一进行标记：

[ connect   default      ]
[ connect   identifier   ]
[ sql       default      ]
[ sql       identifier   ]
[ userlist  identifier   ]
[ logs                   ]

节标头包含如下部分：

部分 | 说明
connect | 文字字符串，修改连接字符串。
sql | 文字字符串，修改命令字符串。
userlist | 文字字符串，修改特定用户的访问权限。
logs | 文字字符串，指定记录操作错误的日志文件。
default | 文字字符串，在未指定或未找到标识符时使用。
identifier 字符串，与 connect 中的字符串或 command 字符串相匹配。
  • 如果节标头包含 connect 并且在连接字符串中找到标识符字符串，使用此节。
  • 如果节标头包含 sql 并且在命令字符串中找到标识符字符串，使用此节。
  • 如果节标头包含 userlist 并且标识符字符串与 connect 节标识符相匹配，使用此节。

DataFactory 调用处理程序，传递客户端参数。处理程序在客户端参数中搜索与相应的节标头中的标识符相匹配的所有字符串。如果找到匹配，该节的内容将被应用到客户端参数。

下列情况将使用特殊的节：

  • 如果客户端连接字符串关键字“Data Source=value”的 value 部分与 connect 节标识符相匹配，请使用 connect 节。
  • 如果客户端命令字符串包含与 sql 节标识符相匹配的字符串，请使用 sql 节。
  • 如果没有匹配的标识符，请使用包含默认参数的 connect 或 sql 节。
  • 如果 userlist 节标识符与 connect 节标识符相匹配，请使用 userlist 节。如果发现匹配，userlist 节的内容将被应用到 connect 节控制的连接。
  • 如果连接或命令字符串中的字符串不与任何 connect 或 sql 节标头中的标识符相匹配，并且没有带默认参数的 connect 或 sql 节标头，那么将不作任何修改地使用客户端字符串。
  • 只要进行 DataFactory 操作，便会使用 logs 节。

请参阅

自定义文件 Connect 节 | 自定义文件 Logs 节 | 自定义文件 SQL 节 | 自定义文件 UserList 节 | DataFactory 自定义 | 所需的客户端设置 | 编写自定义处理程序


自定义文件 Connect 节

处理程序的默认行为是拒绝所有连接。connect 节指定该行为的例外形式。例如，如果所有 connect 节都不存在或者是空的，那么默认情况下将不进行连接。

connect 节可以包含：

  • 默认访问项目，指定该连接允许的默认读写操作。如果节中没有默认访问项目，此节将被忽略。
  • 新连接字符串，替换客户端连接字符串。

语法

默认访问项目的格式如下：

Access=accessRight

替换连接字符串项目的格式如下：

Connect=connectionString
部分 | Description
Connect | 文字字符串，指示这是连接字符串项目。
connectionString | 字符串，替换整个客户端连接字符串。
Access | 文字字符串，表示这是访问项目。
accessRight 可以是下列访问权限之一：
  • NoAccess — 用户不能访问数据源。
  • ReadOnly — 用户可以读取数据源。
  • ReadWrite — 用户可以读写数据源。

要允许所有连接（实际是禁用默认处理程序行为），请将 connect default 节中的访问项目设置为 Access=ReadWrite，并且删除或注释出任何其他 connect identifier 节。

请参阅

自定义文件 Logs 节 | 自定义文件 SQL 节 | 自定义文件 UserList 节 | DataFactory 自定义 | 所需的客户端设置 | 了解自定义文件 | 编写自定义处理程序


自定义文件 SQL 节

sql 节可以包含替换客户端命令字符串的新 SQL 字符串。如果节中没有 SQL 字符串，此节将被忽略。

新的 SQL 字符串可以进行“参数化”。即，sql 节 SQL 字符串中的参数（用“?”指定）可以用客户端命令字符串的 identifier 中相对应的参数（在括号中用逗号分隔的列表来指定）来替换。标识符和参数列表的行为与函数调用类似。

例如，假定客户端命令字符串为“CustomerByID(4)”，那么 SQL 节标头为 [SQL CustomerByID]，而新的 SQL 节字符串为“SELECT * FROM Customers WHERE CustomerID = ?”。处理程序将生成“SELECT * FROM Customers WHERE CustomerID = 4”，并使用该字符串来查询数据源。

如果新的 SQL 语句是空字符串 ("")，此节将被忽略。

如果新的 SQL 语句字符串无效，那么此语句的执行将会失败。客户端参数实际上被忽略。通过如下指定可有意“关闭”所有客户端 SQL 命令：

[SQL default]
SQL = " "

语法

替换 SQL 字符串项目的格式如下：

SQL=sqlString

部分 | Description
SQL | 文字字符串，指示这是 SQL 节项目。
sqlString | SQL 字符串，替换客户端字符串。

请参阅

自定义文件 Connect 节 | 自定义文件 Logs 节 | 自定义文件 UserList 节 | DataFactory 自定义 | 所需的客户端设置 | 了解自定义文件 | 编写自定义处理程序


自定义文件 UserList 节

userlist 节涉及到具有相同节 identifier 参数的 connect 节。

此节可以包含“用户访问项目”，它指定特定用户的访问权限并且覆盖匹配的 connect 节中的“默认访问项目”。

语法

用户访问项目的格式如下：

userName=accessRights

部分 | Description
userName | 使用此连接的用户的“用户名称”。有效的用户名称是通过 IIS Service Manager 对话框建立的。
accessRights 可以是下列访问权限之一：
  • NoAccess — 用户不能访问数据源。
  • ReadOnly — 用户可以读取数据源。
  • ReadWrite — 用户可以读写数据源。

请参阅

自定义文件 Connect 节 | 自定义文件 Logs 节 | 自定义文件 SQL 节 | DataFactory 自定义 | 所需的客户端设置 | 了解自定义文件 | 编写自定义处理程序


自定义文件 Logs 节

logs 节包含日志文件项目，该项目指定用于记录 DataFactory 的操作过程中发生的错误的文件名称。

语法

日志文件项目的格式如下：

err=FileName
部分 | Description
err | 文字字符串，指示这是日志文件项目。
FileName | 完整的路径和文件名称。典型的文件名称为 c:\msdfmap.log。

日志文件包含每次出错时的用户名称、HRESULT、日期和时间。

请参阅

自定义文件 Connect 节 | 自定义文件 SQL 节 | 自定义文件 UserList 节 | DataFactory 自定义 | 所需的客户端设置 | 了解自定义文件 | 编写自定义处理程序


所需的客户端设置

指定下列设置以使用自定义的 DataFactory 处理程序。

  • 在 Connection 对象的 Provider 属性或者 Connection 对象连接字符串“Provider=”关键字中，指定“Provider=MS Remote”。
  • 将 CursorLocation 属性设置为 adUseClient。
  • 指定处理程序的名称以便在 RDS.DataControl 对象的 Handler 属性或者 Recordset 对象的连接字符串“Handler=”关键字中使用。（不能在 Connection 对象连接字符串中设置处理程序。）
RDS 提供服务器的默认处理程序，名为 MSDFMAP.Handler。（默认自定义文件的名称为 MSDFMAP.INI。）

范例

假定 MSDFMAP.INI 中下列各节和数据源名称 AdvWorks 以前已经定义：

[connect CustomerDataBase]
Access=ReadWrite
Connect="DSN=AdvWorks"

[sql CustomerById]
SQL="SELECT * FROM Customers WHERE CustomerID = ?"

下列代码段用 Visual Basic 编写：

RDS.DataControl 版本

Dim dc as New RDS.DataControl
Set dc.Handler = "MSDFMAP.Handler"
Set dc.Server = "http://yourServer"
Set dc.Connect = "Data Source=CustomerDatabase"
Set dc.SQL = "CustomerById(4)"
dc.Refresh

Recordset 版本

Dim rs as New ADODB.Recordset
rs.CursorLocation = adUseClient

指定 Handler 属性或关键字、Provider 属性或关键字，以及 CustomerById 和 CustomerDatabase 标识符。然后打开 Recordset 对象。

rs.Open "CustomerById(4)", "Handler=MSDFMAP.Handler;" & _
   "Provider=MS Remote;Data Source=CustomerDatabase;" & _
   "Remote Server=http://yourServer"

请参阅

自定义文件 Connect 节 | 自定义文件 Logs 节 | 自定义文件 SQL 节 | 自定义文件 UserList 节 | DataFactory 自定义 | Microsoft OLE DB Remoting Provider | 了解自定义文件 | 编写自定义处理程序


编写自定义处理程序

如果您是一位 IIS 服务器管理员，需要默认 RDS 支持，而且想更多地控制用户请求和访问权限，您可能需要编写自己的处理程序。

MSDFMAP.Handler 实现 IDataFactoryHandler 接口。

IDataFactoryHandler 接口

此接口包含两种方法：GetRecordset 和 Reconnect。这两种方法都要求将 CursorLocation 属性设置为 adUseClient。

这两种方法都接受出现在“Handler=”关键字中第一个逗号后面的参数。例如，“Handler=progid,arg1,arg2;”将传递参数字符串“arg1,arg2”，而“Handler=progid”将传递一个 Null 参数。

GetRecordset 方法

这种方法用所提供的参数查询数据源并创建新的 Recordset 对象。必须用 adLockBatchOptimistic 打开 Recordset，而不能异步打开。

参数

conn 连接字符串。

args 处理程序的参数。

query 用于生成查询的命令文本。

ppRS 返回 Recordset 的指针。

Reconnect 方法

这种方法可以更新数据源。它创建新的 Connection 对象并附加在给定的 Recordset 上。

参数

conn 连接字符串。

args 处理程序的参数。

pRS Recordset 对象。

msdfhdl.idl

这是出现在 msdfhdl.idl 文件中的 IDataFactoryHandler 的接口定义。

[
  uuid(D80DE8B3-0001-11d1-91E6-00C04FBBBFB3),
  version(1.0)
]
library MSDFHDL
{
    importlib("stdole32.tlb");
    importlib("stdole2.tlb");

    // TLib : Microsoft ActiveX Data Objects 2.0 Library
    // {00000200-0000-0010-8000-00AA006D2EA4}
    #ifdef IMPLIB
    importlib("implib\\x86\\release\\ado\\msado15.dll");
    #else
    importlib("msado20.dll");
    #endif

    [
      odl,
      uuid(D80DE8B5-0001-11d1-91E6-00C04FBBBFB3),
      version(1.0)
    ]
    interface IDataFactoryHandler : IUnknown
    {
HRESULT _stdcall GetRecordset(
      [in] BSTR conn,
      [in] BSTR args,
      [in] BSTR query,
      [out, retval] _Recordset **ppRS);

// DataFactory will use the ActiveConnection property
// on the Recordset after calling Reconnect.
   HRESULT _stdcall Reconnect(
      [in] BSTR conn,
      [in] BSTR args,
      [in] _Recordset *pRS);
    };
};

请参阅

自定义文件 Connect 节 | 自定义文件 Logs 节 | 自定义文件 SQL 节 | 自定义文件 UserList 节 | DataFactory 自定义 | 所需的客户端设置 | 了解自定义文件


RDS 疑难解答

有关使用 RDS 时的特定错误或问题的解决方法，请参阅本节。本节讨论以下问题：

  • 在 Windows 2000 上配置 RDS
  • “Internet 服务器错误：访问被拒绝”
  • RDS 返回“未读取流”错误
  • 可重复读取隔离级出现死锁
  • 确保足够的 TempDB 空间
  • 最小化日志文件空间的使用

请参阅

RDS 基础


在 Windows 2000 上配置 RDS

如果在升级到 Windows 2000 后，您在正确执行 RDS 功能时遇到困难，请按照下列步骤解决这些问题。

  1. 确保首先通过使用 Internet Explorer 定位到 http://server 来运行万维网发布服务。如果无法通过此方式访问 Web 服务器，请转到命令提示符并输入如下命令：NET START W3SVC。
  2. 从“开始”菜单中选择“运行”。
    键入 msdfmap.ini，然后单击“确定”以在记事本中打开 msdfmap.ini 文件。请检查 [CONNECT DEFAULT] 部分，如果 ACCESS 参数被设置为 NOACCESS，请将其更改为 READONLY。
  3. 使用 RegEdit 实用程序，定位到“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DataFactory\HandlerInfo” 并确保将 HandlerRequired 设置为 0，将 DefaultHandler 设置为 "" （空字符串）。
    注意 如果对此部分注册表进行了更改，则必须停止并重新启动万维网发布服务，方法是在命令提示符下输入以下命令：NET STOP W3SVC 和 NET START W3SVC。
  4. 使用 RegEdit 实用工具，定位到注册表中的“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC\Parameters\ADCLaunch”并验证存在名为 RDSServer.Datafactory 的项。如果没有该项，请创建。
  5. 使用 Internet 服务管理程序，转到默认网站，然后查看 MSADC 虚拟根的属性。请检查“目录安全性/IP 地址及域名限制”。如果选中了“拒绝访问”，则请选择“已授权”。

如果最初没有显示可以解决问题的更改，请确保尝试重新启动服务器。

请参阅

RDS 基础


“Internet 服务器错误：访问被拒绝”

如果获得此错误信息，通常表明 Microsoft Internet Information Services (IIS) 返回以下状态：

HTTP_STATUS_DENIED 401

请确保 IIS 对所访问的目录有适当的权限。RDS 能够与在下述三种密码验证模式之一下运行的 IIS Web 服务器进行通讯：匿名、基本或 NT 请求/响应（在 Windows 2000 中称为“集成 Windows”验证）。而且，如果 Web 服务器是 Windows NT/Windows 2000 计算机，那么它必须具有对数据源计算机的访问权限。

请参阅

RDS 教程


RDS 返回“未读取流”错误

“不能读取 Stream 对象，原因是该对象是空的，或者当前位于 Stream 的末尾。对于非空的 Stream，可以使用 Position 属性设置当前位置。若要确定 Stream 是否为空，请检查 Size 属性”。

如果得到以上错误，则可能是尝试通过 http 使用参数化的分级查询。RDS 不允许您远程使用参数化的分级。

请参阅

RDS 基础


可重复读取隔离级出现死锁

如果自定义业务对象使用可重复读取隔离级访问 SQL Server，并且在同一事务中发送查询和更新的两个客户端同时调用该业务对象，那么将可能发生死锁。远程数据服务允许其中一个进程超时以释放死锁，但是客户端的更新将失败。

使用 Cursor Service Command Time Out 动态属性修改超时的长度。

请参阅

RDS 基础


确保足够的 TempDB 空间

如果处理在 Microsoft SQL Server 6.5 上需要处理空间的 Recordset 对象时出现错误，可能需要增加 TempDB 的大小。（某些查询需要临时处理空间。例如，带 ORDER BY 子句的查询就需要一种要求部分临时空间的 Recordset。）

重要信息 请在执行操作之前阅读此过程，因为设备一旦展开就难以压缩。
注意 在 Microsoft SQL Server 7.0 及更新版本中，默认将 TempDB 设置为根据需要自动增长。因此，此过程可能只对运行早于 7.0 版本的服务器有必要。

增加 SQL Server 6.5 上 TempDB 空间的步骤

  1. 启动 Microsoft SQL Server Enterprise Manager，打开“服务器”树，然后打开“数据库设备”树。
  2. 选定要扩展的（物理）设备（如 Master），然后双击该设备，打开“编辑数据库设备”对话框。

    此对话框显示当前数据库使用的空间大小。

  3. 在“大小”框中，将设备增加到所需量。例如，50 兆字节 (MB) 硬盘空间。
  4. 单击“立即更改”，增加（逻辑）TempDB 可以扩展的空间量。
  5. 打开服务器上的“数据库”树，然后双击“TempDB”，打开“编辑数据库”对话框。“数据库”选项卡列出当前分配给 TempDB 的空间量（“数据大小” ）。默认情况下为 2 MB。
  6. 在“大小”组下，单击“扩展”。图形显示每个物理设备上的可用空间和已分配空间。栗色的条表示可用的空间。
  7. 选择“日志设备”（如 Master）， 在“大小 (MB)”框中显示可用的大小。
  8. 单击“立即扩展”以将空间分配给 TempDB 数据库。

    “编辑数据库”对话框显示新分配给 TempDB 的大小。

有关本主题的详细信息，请参阅 Mcirosoft SQL Server Enterprise Manager 帮助文件中的“扩展数据库对话框”。

请参阅

RDS 基础


最小化日志文件空间的使用

如果在 SQL Server 数据库中有大量的活动，那么日志文件很快就会填满（从而中断服务器）。可以将日志文件设置为“在检查点截断”，从而显著延长数据库日志文件的寿命。

在 Microsoft SQL Server 6.5 中启用“在检查点截断”的步骤

  1. 启动 Microsoft SQL Server Enterprise Manager，打开“服务器”树，然后打开“数据库设备”树。
  2. 双击要在其上启用此功能的数据库名称。
  3. 在“数据库”选项卡上选择“截断”。
  4. 在“选项”选项卡上选择“在检查点截断日志”，然后单击“确定”。

在 Microsoft SQL Server 7.0 中启用“在检查点截断”的步骤

  1. 启动 Microsoft SQL Server Enterprise Manager，打开“服务器”树，然后打开“数据库”树。
  2. 用鼠标右键单击要在其上启用此功能的数据库名称，然后选择“属性”。
  3. 在“选项”选项卡上选择“在检查点截断日志”，然后单击“确定”。

有关“在检查点截断”功能的详细信息，请参阅 Microsoft SQL Server 文档。

请参阅

RDS 基础


第 3 节：ADO (Multidimensional) (ADO MD)

本届包含下列章节：

  • 第 14 章：ADO MD 基础


第 14 章：ADO MD 基础

Microsoft ActiveX Data Objects (Multidimensional) (ADO MD) 提供通过多种语言（如 Microsoft Visual Basic、Microsoft Visual C++ 和 Microsoft Visual J++）访问多维数据的便捷方式。ADO MD 扩展了 Microsoft ActiveX Data Objects (ADO)，使之包括特定于多维数据的对象，如 CubeDef 和 Cellset 对象。用 ADO MD 可以浏览多维模式、查询立方和检索结果。

同 ADO 一样，ADO MD 用基本的 OLE DB 提供者来访问数据。要使用 ADO MD，提供者必须是由 OLE DB for OLAP 规范定义的多维数据提供者 (MDP)。与用表格视图方式显示数据的表格数据提供者 (TDP) 相反，MDP 以多维视图方式显示数据。有关提供者支持的特定语法和行为的详细信息，请参阅 OLAP OLE DB 提供者的文档。

本文档假定用户具有 Visual Basic 编程语言的应用知识，并基本了解 ADO 和 OLAP。有关详细信息，请参阅 ADO 程序员指南 和《OLE DB for OLAP 程序员参考》。有关 ADO MD 的详细概述信息，请参阅下列主题：

  • 多维模式和数据概述
  • 使用多维数据
  • 将 ADO MD 与 ADO 配合使用
  • ADO MD 编程
  • ADO MD 对象模型

请参阅

ADO MD 对象模型 | Microsoft ADO 程序员指南 | Microsoft ADOX 程序员参考 | 多维模式和数据概述 | ADO MD 编程 | 将 ADO MD 与 ADO 配合使用 | 使用多维数据


多维模式和数据概述

了解多维模式

ADO MD 中的中心元数据对象是 cube，它由相关的维、分级结构、级别和成员的结构化集合组成。

“维”是多维数据库中数据的独立目录，由业务项产生。维通常包含用作数据库度量的查询条件的项目。

hierarchy 是维的合计的路径。维可以包含具有父子关系的多个间隔级别。分级结构定义这些级别间的关系。

“级别”是分级结构中合计的一个步骤。对于具有多层信息的维，每一层即为一个级别。

“成员”是维中的数据项。通常，用成员来创建数据库的标题或者描述数据库的度量。

在 ADO MD 中，立方由 CubeDef 对象表示。维、分级结构、级别和成员也由其对应的 ADO MD 对象表示：Dimension、Hierarchy、Level 和 Member。

维

立方的维取决于要在数据库中进行模型化的业务项和数据类型。通常，每个维都是一个用于选择数据的独立的项目点或机制。

例如，包含销售数据的立方具有以下五个维：Salesperson、Geography、Time、Products 和 Measures。Measures 维包含实际的销售数据值，而其他维表示对销售数据进行分类和分组的方法。

Geography 维具有以下成员集：

{All, North America, Europe, Canada, USA, UK, Germany, Canada-West,
Canada-East, USA-NW, USA-SW, USA-NE, USA-SE, England, Scotland,
Wales,Ireland, Germany-North, Germany-South, Ottawa, Toronto,
Vancouver, Calgary, Seattle, Boise, Los Angeles, Houston,
Shreveport, Miami, Boston, New York, London, Dover, Glasgow,
Edinburgh, Cardiff, Pembroke, Belfast, Berlin,
Hamburg, Munich, Stuttgart}

分级结构

分级结构定义将维的级别“卷起”或进行分组的方法。一维可具有多个分级结构。Geography 维中存在天然分级结构：

级别

在上述图表的 Geography 维范例中，每个方框均表示分级结构中的一个级别。

每个级别均有一组成员，如下所示：

  • The World = {All}
  • Continents = {North America, Europe}
  • Countries = {Canada, USA, UK, Germany}
  • Regions = {Canada-East, Canada-West, USA-NE, USA-NW, USA-SE, USA-SW, England, Ireland, Scotland, Wales, Germany-North, Germany-South}
  • Cities = {Ottawa, Toronto, Vancouver, Calgary, Seattle, Boise, Los Angeles, Houston, Shreveport, Miami, Boston, New York, London, Dover, Glasgow, Edinburgh, Cardiff, Pembroke, Belfast, Berlin, Hamburg, Munich, Stuttgart}

成员

位于分级结构叶级别处的成员没有子，而位于根级别的成员没有父。所有其他成员均至少有一个父和一个子。例如，部分遍历 Geography 维中的分级结构树将产生如下父子关系：

  • {All} (parent of) {Europe, North America}
  • {North America} (parent of) {Canada, USA}
  • {USA} (parent of) {USA-NE, USA-NW, USA-SE, USA-SW}
  • {USA-NW} (parent of) {Boise, Seattle}

可沿每个维的一个或多个分级结构固定成员。假设有一个 Time 维，可通过两种方法从 Days 级别卷起到 Year 级别：

本范例还说明了另一个特性：Year-Week 分级结构的 Week 级别上的某些成员不在 Year-Quarter 分级结构的任何级别中出现。因此，分级结构不必包括维的所有成员。

请参阅

ADO MD 对象模型 | Microsoft ADO MD 程序员参考 | ADO MD 编程 | 将 ADO MD 与 ADO 配合使用 | 使用多维数据


使用多维数据

“单元集”是多维数据的查询结果。它由轴的集合组成，通常不超过四个轴，一般只有两个或三个。“轴”是来自一个或多个维的成员的集合，用于定位或过滤立方中的特定值。

“位置”是轴上的点。对于由单个维组成的轴，这些位置是维成员的子集。如果轴由多个维组成，那么每个位置都是一个包含 n 个部分的复合项目，n 是在该轴方向上的维的数量。位置的每个部分均是组成维中的一个成员。

例如，如果包含销售数据的立方中的 Geography 和 Product 维位于单元集的 X 轴方向上，那么此轴上的位置可能包含“USA”成员和“Computers”成员。在此范例中，要确定 X 轴上的位置，需要每个维的成员均朝向此轴。

“单元”是位于轴坐标交叉位置的对象。每个单元均包含与之相关联的多条信息，包括数据本身、格式化字符串（单元数据的可显示格式）和单元序号值。（每个单元均为单元集中唯一的序号值。单元集中第一个单元的序号值是零，而包含八个列的单元集的第二行最左边的单元的序号值为八。）

例如，一个立方有以下六个维（注意，本立方模式与多维模式和数据概述中给定的范例略有不同）：

  • Salesperson
  • Geography（天然分级结构）—Continents、Countries 和 States 等
  • Quarters—Quarters、Months 和 Days
  • Years
  • Measures—Sales、PercentChange 和 BudgetedSales
  • Products

下列单元集表示 1991 年所有产品的销售情况：

注意 范例中的单元值可以被看作是排序后的轴位置的序号对，其中，第一个数字表示 X 轴位置，第二个数字表示 Y 轴位置。

本单元集的特性如下：

  • 轴的维：Quarters、Salesperson 和 Geography
  • 过滤维：Measures、Years 和 Products
  • 两个轴：COLUMN（X 或轴 0）和 ROW（Y 或轴 1）
  • X 轴：两个嵌套维，Salesperson 和 Geography
  • Y 轴：Quarters 维

X 轴包含两个嵌套维：Salesperson 和 Geography。从 Geography 中选择四个成员：Seattle、Boston、USA-South 和 Japan。从 Salesperson 中选择两个成员：Valentine 和 Nash。这样，在此轴上共产生八个位置 (8 = 4*2)。

每个坐标均用两个成员表示位置—一个成员来自 Salesperson 维，另一个成员来自 Geography 维：

(Valentine, Seattle), (Valentine, Boston), (Valentine, USA_North),
(Valentine, Japan), (Nash, Seattle), (Nash, Boston), (Nash, USA_North),
(Nash, Japan)

Y 轴仅有一个维，包含以下八个位置：

Jan, Feb, Mar, Qtr2, Qtr3, Oct, Nov, Dec

在 ADO MD 中，单元集、单元、轴和位置均由对应的对象表示：Cellset、Cell、Axis 和 Position。

请参阅

ADO MD 对象模型 | Microsoft ADO MD 程序员参考 | 多维模式和数据概述 | ADO MD 编程 | 将 ADO MD 与 ADO 配合使用


将 ADO MD 与 ADO 配合使用

ADO 和 ADO MD 是相互关联但又各自独立的对象模型。ADO 提供的对象用于连接到数据源、执行命令、检索表格数据和表格格式的模式元数据，以及查看提供者错误信息。ADO MD 提供的对象用于检索多维数据和查看多维模式的元数据。

使用 MDP 时，可在应用程序中选择使用 ADO 或 ADO MD，或者两者都选择。如果在工程中引用两个库，用户将对由 MDP 提供的功能具有完全访问权限。

通常情况下，获得一个多维数据集的平整的表格式视图对于用户来说是很有用的。使用 ADO Recordset 对象即可实现此操作。请将 Cellset 的源指定为 Recordset Open 方法的 Source 参数，而不是 ADO MD Cellset 的源。

以表格视图方式查看模式元数据而不将其当作对象分级结构来查看，也将大有帮助。Connection 对象的 ADO OpenSchema 方法允许用户打开包含模式信息的 Recordset。OpenSchema 方法的 QueryType 参数包含若干与 MDP 有特定关联的 SchemaEnum 值。这些值是：

  • adSchemaCubes
  • adSchemaDimensions
  • adSchemaHierarchies
  • adSchemaLevels
  • adSchemaMeasures
  • adSchemaMembers

要将 ADO 枚举值与 ADO MD 属性或方法配合使用，工程中必须既引用 ADO 库，也引用 ADO MD 库。例如，可以通过 ADO MD State 属性使用 ADO adState 枚举值。有关建立库引用的详细信息，请参阅开发工具的文档。

有关 ADO 对象和方法的详细信息，请参阅 ADO API 参考。

请参阅

ADO MD 对象模型 | Microsoft ADO MD 程序员参考 | 多维模式和数据概述 | ADO MD 编程 | 使用多维数据


ADO MD 编程

要将 ADO MD 与开发工具配合使用，则应建立对 ADO MD 类型库的引用。ADO MD 库的说明是 Microsoft ActiveX Data Objects (Multi-dimensional) Library。ADO MD 库文件名为 msadomd.dll，程序 ID (ProgID) 为“ADOMD”。有关建立库引用的详细信息，请参阅开发工具的文档。

请参阅

Microsoft ADO MD 程序员参考 | 多维模式和数据概述 | 将 ADO MD 与 ADO 配合使用 | 使用多维数据


第 4 节：ADO Extensions for Data Definition Language and Security (ADOX)

本节包含以下章节：

  • 第 15 章：ADOX 基础


第 15 章：ADOX 基础

Microsoft® ActiveX® Data Objects Extensions for Data Definition Language and Security (ADOX) 是对 ADO 对象和编程模型的扩展。ADOX 包括用于安全性以及创建和修改模式的对象。因为它是基于对象的模式操作方法，所以用户可以编写在各种数据源上都能运行的代码，而不必考虑它们原生语法的差异。

ADOX 是核心 ADO 对象的扩展库。它提供的附加对象可用于创建、修改和删除模式对象，如表和过程。它还包括安全对象，可用于维护用户和组，以及授予和取消对对象具有的权限。

要结合开发工具使用 ADOX，则应建立对 ADOX 类型库的引用。ADOX 库的说明是“Microsoft ADO Ext. for DDL and Security”。ADOX 库文件名为 Msadox.dll，程序 ID (ProgID) 为“ADOX”。有关建立库引用的详细信息，请参阅开发工具的文档。

用于 Microsoft Jet Database Engine 的 Microsoft OLE DB Provider 完全支持 ADOX。根据数据提供者的不同，某些提供者可能不支持 ADOX 的某些功能。有关 Microsoft OLE DB Provider for ODBC、Microsoft OLE DB Provider for Oracle 或 Microsoft SQL Server OLE DB Provider 的支持功能的详细信息，请参阅 MDAC 自述文件。

本文档假定用户具有 Microsoft® Visual Basic® 编程语言的使用经验并掌握 ADO 的基本知识。有关 ADO 的详细信息，请参阅 ADO 程序员指南。有关 ADOX 的详细概述信息，请参阅下列主题：

  • ADOX 对象模型
  • ADOX 对象
  • ADOX 集合
  • ADOX 属性
  • ADOX 方法
  • ADOX 范例

请参阅

ADOX API 参考 | ADOX 代码范例 | ADOX 集合 | ADOX 枚举常量 | ADOX 方法 | ADOX 对象模型 | ADOX 对象 | ADOX 属性 | Microsoft ADO MD 程序员参考 | ADO 程序员指南


ADOX 的提供者支持

ADOX 2.5

ADOX 提供者支持

根据 OLE DB 数据提供者的不同，某些提供者可能不支持 ADOX 的某些功能。OLE DB Provider for Microsoft Jet 完全支持 ADOX。以下列出了 Microsoft OLE DB Provider for SQL Server、Microsoft OLE DB Provider for ODBC 或 Microsoft OLE DB Provider for Oracle 不支持的功能。其他 Microsoft OLE DB 提供者也不支持 ADOX。

Microsoft OLE DB Provider for SQL Server

对象或集合 | 使用限制
Catalog 对象 | 不支持 Create 方法。
Tables 集合 | 属性在对象创建之前为读/写，在引用现有对象时为只读。
Views 集合 | 不支持 Views。
Procedures 集合 | 不支持 Append 和 Delete 方法。
Procedure 对象 | 不支持 Command 属性。
Keys 集合 | 不支持 Append 和 Delete 方法。
Users 集合 | 不支持 Users。
Groups 集合 | 不支持 Groups。

Microsoft OLE DB Provider for ODBC

对象或集合 | 使用限制
Catalog 对象 | 不支持 Create 方法。
Tables 集合 | 不支持 Append 和 Delete 方法。 属性在对象创建之前为读/写，在引用现有对象时为只读。
Procedures 集合 | 不支持 Append 和 Delete 方法。
Procedure 对象 | 不支持 Command 属性。
Indexes 集合 | 不支持 Append 和 Delete 方法。
Keys 集合 | 不支持 Append 和 Delete 方法。
Users 集合 | 不支持 Users。
Groups 集合 | 不支持 Groups。

Microsoft OLE DB Provider for Oracle

对象或集合 | 使用限制
Catalog 对象 | 不支持 Create 方法。
Tables 集合 | 不支持 Append 和 Delete 方法。 属性在对象创建之前为读/写，在引用现有对象时为只读。
Views 集合 | 不支持 Append 和 Delete 方法。
View 对象 | 不支持 Command 属性。
Procedures 对象 | 不支持 Append 和 Delete 方法。
Procedure 对象 | 不支持 Command 属性。
Indexes 集合 | 不支持 Append 和 Delete 方法。
Keys 集合 | 不支持 Append 和 Delete 方法。
Users 集合 | 不支持 Users。
Groups 集合 | 不支持 Group。


第 5 节：附录

ADO 程序员指南包含以下附录：

  • 附录 A：提供者
  • 附录 B：ADO 错误
  • 附录 C：ADO 编程
  • 附录 D：ADO 范例


附录 A：提供者

本节内容介绍三种提供者：数据提供者、服务提供者和服务组件。提供者分为两类：提供数据的提供者和提供服务的提供者。“数据提供者”拥有自己的数据，并将数据以表格格式显露给应用程序。“服务提供者”通过产生和消费数据来封装服务，以增加 ADO 应用程序中的功能。也可以将服务提供者进一步定义为“服务组件”，服务组件必须与其他服务提供者或组件结合使用。

数据提供者

ADO 之所以具有强大的功能和灵活性，是因为它可以连接几种不同的数据提供者，同时仍使用同一个编程模型，而不考虑给定提供者的特定功能。

但是，因为每个数据提供者都有各自的特性，所以应用程序与 ADO 的相互作用方式将根据数据提供者的不同而稍有变化。这些区别通常可以分为三类：

  • ConnectionString 属性中的连接参数。
  • Command 对象的用法。
  • 提供者特有的 Recordset 行为。

下面列出了当前可从 Microsoft 获得的每个数据提供者的详细信息。

区域 | 主题
ODBC 数据库 | Microsoft OLE DB Provider for ODBC
Microsoft Indexing Service | Microsoft OLE DB Provider for Microsoft Indexing Service
Microsoft Active Directory Service | Microsoft OLE DB Provider for Microsoft Active Directory Service
Microsoft Jet 数据库 | OLE DB Provider for Microsoft Jet
Microsoft SQL Server | Microsoft OLE DB Provider for SQL Server
Oracle 数据库 | Microsoft OLE DB Provider for Oracle
Internet 发布 | Microsoft OLE DB Provider for Internet Publishing

提供者特有的动态属性

Connection、Command 和 Recordset 对象的 Properties 集合包含提供者特有的动态属性。这些属性提供了针对特定提供者、超出 ADO 支持的内置属性以外的功能信息。

建立连接和创建这些对象后，请使用对象 Properties 集合的 Refresh 方法来获取提供者特有的属性。有关这些动态属性的详细信息，请参阅提供者的文档和 OLE DB Programmer's Reference。

服务提供者

要使用服务提供者，必须提供关键字。同时还应该了解与每个服务提供者相关联的、提供者特有的动态属性。下面列出了有关当前可从 Microsoft 获得的每个服务提供者的提供者特有的详细信息。

  • Microsoft Data Shaping Service for OLE DB
  • Microsoft OLE DB Persistence Provider
  • Microsoft OLE DB Remoting Provider

服务组件

Cursor Service for OLE DB 服务组件补充了数据提供者的游标支持功能。它也需要关键字，并具有动态属性。

有关提供者的详细信息，请参阅 Microsoft Data Access Components SDK 中的 Microsoft OLE DB 文档或访问 Microsoft Universal Data Access Web 站点。

提供者命令

对于此处列出的每个提供者，如果应用程序允许用户输入 SQL 语句作为提供者命令，则必须始终验证用户输入，并使用具有潜在危险的 SQL 语句（如 DROP TABLE t1）作为用户输入的一部分来防止可能的黑客攻击。

请参阅

Command 对象 | Connection 对象 | Microsoft OLE DB Provider for Internet Publishing | Microsoft OLE DB Provider for Microsoft Active Directory Service | Microsoft OLE DB Provider for Microsoft Indexing Service | Microsoft OLE DB Provider for ODBC | Microsoft OLE DB Provider for Oracle | Microsoft OLE DB Provider for SQL Server | OLE DB Provider for Microsoft Jet | Properties 集合 | Recordset 对象 | Refresh 方法 (RDS)


Microsoft OLE DB Provider for ODBC

对于 ADO 或 RDS 程序员来说，理想的环境是每个数据源都具有一个 OLE DB 接口，这样 ADO 便可以直接调用到数据源中。虽然越来越多的数据库厂商实现了 OLE DB 接口，但某些数据源仍无法以这种方式提供。然而，目前所用的所有 DBMS 系统实际上都可以通过 ODBC 进行访问。

ODBC 驱动程序对于目前所使用的各种主要 DBMS 都有效，包括 Microsoft SQL Server、Microsoft Access（Microsoft Jet 数据库引擎）和 Microsoft FoxPro 以及 Oracle 等非 Microsoft 数据库产品。

但是，Microsoft ODBC Provider 允许 ADO 连接到任何 ODBC 数据源。提供者将不受线程控制并允许使用 Unicode。

尽管不同的 DBMS 引擎支持不同类型的事务，但提供者会对事务提供支持。例如，Microsoft Access 支持多达五级的嵌套事务。

这是 ADO 的默认提供者，支持所有依赖于提供者的 ADO 属性和方法。

连接字符串参数

要连接到此提供者，请将 ConnectionString 属性的 Provider= 参数设置为：

MSDASQL

读取 Provider 属性也将返回此字符串。

典型连接字符串

此提供者的典型连接字符串是：

"Provider=MSDASQL;DSN=dsnName;UID=userName;PWD=userPassword;"

该字符串包含下列关键字：

关键字 | 说明
Provider | 指定 OLE DB Provider for ODBC。
DSN | 指定数据源名称。
UID | 指定用户名称。
PWD | 指定用户密码。
URL | 指定在 Web 文件夹中发布的文件或目录的 URL。

因为这是 ADO 的默认提供者，所以如果从连接字符串中省略 Provider= 参数，ADO 将试图与此提供者建立连接。

除了 ADO 定义的连接参数以外，该提供者不支持任何特定的连接参数。但是，该提供者将把所有非 ADO 连接参数传递给 ODBC 驱动程序管理器。

由于可以省略 Provider 参数，因此，对于同一数据源，可以填写与 ODBC 连接字符串相同的 ADO 连接字符串。在填写 ODBC 连接字符串时，可以使用相同的参数名（DRIVER=、DATABASE=、DSN= 等等）、值和语法。进行连接时，可以使用预定义的数据源名称 (DSN) 或 FileDSN，也可以不使用它们。

带 DSN 或 FileDSN 的语法：

"[Provider=MSDASQL;] { DSN=name | FileDSN=filename } ;
[DATABASE=database;] UID=user; PWD=password"

不带 DSN（非 DSN 连接）的语法：

"[Provider=MSDASQL;] DRIVER=driver; SERVER=server;
DATABASE=database; UID=user; PWD=password"

如果使用 DSN 或 FileDSN，必须通过 Windows 控制面板中的“ODBC 数据源管理器”进行定义。在 Microsoft Windows 2000 中，“ODBC 管理器”位于“管理工具”下面。在以前的 Windows 版本中，“ODBC 管理器”图标的名称为 32-bit ODBC 或仅为 ODBC。

设置 DSN 的另一种方法是，指定 ODBC 驱动程序 (DRIVER=)（如“SQL Server”）、服务器名称 (SERVER=) 和数据库名称 (DATABASE=)。

也可以在 ODBC 特有的参数或标准 ADO 定义的 user 和 password 参数中指定用户帐号名称 (UID=) 和用户帐号密码 (PWD=)。

即使 DSN 定义已经指定了数据库，仍然可以指定除 DSN 之外的 database 参数，以便连接到不同的数据库。有一个好办法：在使用 DSN 时始终包括 database 参数。这样做可以确保从上一次检查 DSN 定义后，如果有其他用户更改了默认数据库参数，您还能连接到正确的数据库。

提供者特有的连接属性

ODBC 的 OLE DB 提供者将多个属性添加到 Connection 对象的 Properties 集合。下表列出了这些属性，括号中为相应的 OLE DB 属性名称。

属性名称 | 说明
Accessible Procedures (KAGPROP_ACCESSIBLEPROCEDURES) | 指示用户是否具有访问存储过程的权限。
Accessible Tables (KAGPROP_ACCESSIBLETABLES) | 指示用户是否具有对数据库表执行 SELECT 语句的权限。
Active Statements (KAGPROP_ACTIVESTATEMENTS) | 指示 ODBC 驱动程序在一个连接上所能支持的句柄数目。
Driver Name (KAGPROP_DRIVERNAME) | 指示 ODBC 驱动程序的文件名。
Driver ODBC Version (KAGPROP_DRIVERODBCVER) | 指示此驱动程序支持的 ODBC 的版本。
File Usage (KAGPROP_FILEUSAGE) | 指示驱动程序处理数据源中的文件的方式（作为表还是作为目录）。
Like Escape Clause (KAGPROP_LIKEESCAPECLAUSE) | 指示驱动程序是否支持在 WHERE 子句的 LIKE 谓词中定义和使用百分比字符 (%) 和下划线字符 (_) 的转义字符。
Max Columns in Group By (KAGPROP_MAXCOLUMNSINGROUPBY) | 指示 SELECT 语句的 GROUP BY 子句中可以列出的最大列数。
Max Columns in Index (KAGPROP_MAXCOLUMNSININDEX) | 指示索引可包括的最大列数。
Max Columns in Order By (KAGPROP_MAXCOLUMNSINORDERBY) | 指示 SELECT 语句的 ORDER BY 子句中可以列出的最大列数。
Max Columns in Select (KAGPROP_MAXCOLUMNSINSELECT) | 指示 SELECT 语句的 SELECT 部分中可以列出的最大列数。
Max Columns in Table (KAGPROP_MAXCOLUMNSINTABLE) | 指示表中允许的最大列数。
Numeric Functions (KAGPROP_NUMERICFUNCTIONS) | 指示 ODBC 驱动程序所支持的数字型函数。有关在此位掩码中使用的函数名称和相关值的列表，请参阅 ODBC 文档中的 Appendix E: Scalar Functions。
Outer Join Capabilities (KAGPROP_OJCAPABILITY) | 指示提供者支持的 OUTER JOIN 的类型。
Outer Joins (KAGPROP_OUTERJOINS) | 指示提供者是否支持 OUTER JOIN。
Special Characters (KAGPROP_SPECIALCHARACTERS) | 指示在 ODBC 驱动程序中具有特殊意义的字符。
Stored Procedure (KAGPROP_PROCEDURES) | 指示在使用此 ODBC 驱动程序时存储过程是否可用。
String Functions (KAGPROP_STRINGFUNCTIONS) | 指示 ODBC 驱动程序所支持的字符串函数。有关在此位掩码中使用的函数名称和相关值的列表，请参阅 ODBC 文档中的 Appendix E: Scalar Functions。
System Functions (KAGPROP_SYSTEMFUNCTIONS) | 指示 ODBC 驱动程序所支持的系统函数。有关在此位掩码中使用的函数名称和相关值的列表，请参阅 ODBC 文档中的 Appendix E: Scalar Functions。
Time/Date Functions (KAGPROP_TIMEDATEFUNCTIONS) | 指示 ODBC 驱动程序所支持的时间和日期函数。有关在此位掩码中使用的函数名称和相关值的列表，请参阅 ODBC 文档中的 Appendix E: Scalar Functions。
SQL Grammar Support (KAGPROP_ODBCSQLCONFORMANCE) | 指示 ODBC 驱动程序所支持的 SQL 语法。

提供者特有的 Recordset 和 Command 属性

ODBC 的 OLE DB 提供者向 Recordset 和 Command 对象的 Properties 集合中添加了多个属性。下表列出了这些属性，括号中为相应的 OLE DB 属性名称。

属性名称 | 说明
Query Based Updates/Deletes/Inserts (KAGPROP_QUERYBASEDUPDATES) | 指示是否可以用 SQL 查询执行更新、删除和插入。
ODBC Concurrency Type (KAGPROP_CONCURRENCY) | 指示用于减少由于两个用户同时试图访问数据源中的相同数据而产生的问题的方法。
BLOB accessibility on Forward-Only cursor (KAGPROP_BLOBSONFOCURSOR) | 指示使用仅向前游标时是否可以访问 BLOB Fields。
Include SQL_FLOAT,SQL_DOUBLE,and SQL_REAL in QBU WHERE clauses (KAGPROP_INCLUDENONEXACT) | 指示 QBU WHERE 子句中是否可以包括 SQL_FLOAT、SQL_DOUBLE 和 SQL_REAL 值。
Position on the last row after insert (KAGPROP_POSITIONONNEWROW) | 指示在表中插入一个新记录后，表的最后一行将成为当前行。
IRowsetChangeExtInfo (KAGPROP_IROWSETCHANGEEXTINFO) | 指示 IRowsetChange 接口是否提供扩展信息支持。
ODBC Cursor Type (KAGPROP_CURSOR) | 指示 Recordset 使用的游标类型。
Generate a Rowset that can be marshaled (KAGPROP_MARSHALLABLE) | 指示 ODBC 驱动程序生成可被调度的记录集。

命令文本

如何使用 Command 对象在很大程度上取决于数据源及它所接受的查询或命令语句的类型。

ODBC 提供了一种调用存储过程的特定语法。对于 Command 对象的 CommandText 属性，将以下列语法在字符串中传递 Connection 对象的 Execute 方法的 CommandText 参数，或 Recordset 对象的 Open 方法的 Source 参数：

"{ [ ? = ] call procedure [ ( ? [, ? [ ,  ]] ) ] }"

每个 ? 引用 Parameters 集合中的一个对象。第一个 ? 引用 Parameters(0)，第二个 ? 引用 Parameters(1)，依此类推。

参数引用是可选的，它取决于存储过程的结构。如果要调用未定义参数的存储过程，则字符串如下：

"{ call procedure }"

如果有两个查询参数，则字符串如下：

"{ call procedure ( ?, ? ) }"

如果存储过程要返回一个值，那么该返回值将被当作另一个参数。如果无查询参数而有返回值，则字符串如下：

"{ ? = call procedure }"

最后，如果有一个返回值和两个查询参数，则字符串如下：

"{ ? = call procedure ( ?, ? ) }"

Recordset 行为

下表列出了由此提供者打开的 Recordset 对象上可用的标准 ADO 方法和属性。

有关提供者配置的 Recordset 行为的详细信息，请运行 Supports 方法并枚举 Recordset 的 Properties 集合，以确定提供者特有的动态属性是否存在。

标准 ADO Recordset 属性的可用性：

属性 | 仅向前 | 动态 | 键集 | 静态
AbsolutePage | 不可用 | 不可用 | 读/写 | 读/写
AbsolutePosition | 不可用 | 不可用 | 读/写 | 读/写
ActiveConnection | 读/写 | 读/写 | 读/写 | 读/写
BOF | 只读 | 只读 | 只读 | 只读
Bookmark | 不可用 | 不可用 | 读/写 | 读/写
CacheSize | 读/写 | 读/写 | 读/写 | 读/写
CursorLocation | 读/写 | 读/写 | 读/写 | 读/写
CursorType | 读/写 | 读/写 | 读/写 | 读/写
EditMode | 只读 | 只读 | 只读 | 只读
Filter | 读/写 | 读/写 | 读/写 | 读/写
LockType | 读/写 | 读/写 | 读/写 | 读/写
MarshalOptions | 读/写 | 读/写 | 读/写 | 读/写
MaxRecords | 读/写 | 读/写 | 读/写 | 读/写
PageCount | 读/写 | 不可用 | 只读 | 只读
PageSize | 读/写 | 读/写 | 读/写 | 读/写
RecordCount | 读/写 | 不可用 | 只读 | 只读
Source | 读/写 | 读/写 | 读/写 | 读/写
State | 只读 | 只读 | 只读 | 只读
Status | 只读 | 只读 | 只读 | 只读

当 ADO 与 Microsoft OLE DB Provider for ODBC 1.0 版本配合使用时，AbsolutePosition 和 AbsolutePage 属性是只写的。

标准 ADO Recordset 方法的可用性：

方法 | 仅向前 | 动态 | 键集 | 静态
AddNew | 是 | 是 | 是 | 是
Cancel | 是 | 是 | 是 | 是
CancelBatch | 是 | 是 | 是 | 是
CancelUpdate | 是 | 是 | 是 | 是
Clone | 否 | 否 | 是 | 是
Close | 是 | 是 | 是 | 是
Delete | 是 | 是 | 是 | 是
GetRows | 是 | 是 | 是 | 是
Move | 是 | 是 | 是 | 是
MoveFirst | 是 | 是 | 是 | 是
MoveLast | 否 | 是 | 是 | 是
MoveNext | 是 | 是 | 是 | 是
MovePrevious | 否 | 是 | 是 | 是
NextRecordset* | 是 | 是 | 是 | 是
Open | 是 | 是 | 是 | 是
Requery | 是 | 是 | 是 | 是
Resync | 否 | 否 | 是 | 是
Supports | 是 | 是 | 是 | 是
Update | 是 | 是 | 是 | 是
UpdateBatch | 是 | 是 | 是 | 是

*Microsoft Access 数据库不支持此方法。

动态属性

Microsoft OLE DB Provider for ODBC 向未打开的 Connection、Recordset 和 Command 对象的 Properties 集合中插入多个动态属性。

下表是每个动态属性的 ADO 和 OLE DB 名称的交叉索引。OLE DB Programmer's Reference 使用“Description”项 引用 ADO 属性名称。有关这些属性的详细信息，请参阅 OLE DB Programmer's Reference。请在“索引”中搜索 OLE DB 属性名称或参阅 Appendix C:OLE DB Properties。

Connection 动态属性

下列属性被添加到 Connection 对象的 Properties 集合中。

ADO 属性名称 | OLE DB 属性名称
Active Sessions | DBPROP_ACTIVESESSIONS
Asynchable Abort | DBPROP_ASYNCTXNABORT
Asynchable Commit | DBPROP_ASYNCTNXCOMMIT
Autocommit Isolation Levels | DBPROP_SESS_AUTOCOMMITISOLEVELS
Catalog Location | DBPROP_CATALOGLOCATION
Catalog Term | DBPROP_CATALOGTERM
Column Definition | DBPROP_COLUMNDEFINITION
Connect Timeout | DBPROP_INIT_TIMEOUT
Current Catalog | DBPROP_CURRENTCATALOG
Data Source | DBPROP_INIT_DATASOURCE
Data Source Name | DBPROP_DATASOURCENAME
Data Source Object Threading Model | DBPROP_DSOTHREADMODEL
DBMS Name | DBPROP_DBMSNAME
DBMS Version | DBPROP_DBMSVER
Extended Properties | DBPROP_INIT_PROVIDERSTRING
GROUP BY Support | DBPROP_GROUPBY
Heterogeneous Table Support | DBPROP_HETEROGENEOUSTABLES
Identifier Case Sensitivity | DBPROP_IDENTIFIERCASE
Initial Catalog | DBPROP_INIT_CATALOG
Isolation Levels | DBPROP_SUPPORTEDTXNISOLEVELS
Isolation Retention | DBPROP_SUPPORTEDTXNISORETAIN
Locale Identifier | DBPROP_INIT_LCID
Location | DBPROP_INIT_LOCATION
Maximum Index Size | DBPROP_MAXINDEXSIZE
Maximum Row Size | DBPROP_MAXROWSIZE
Maximum Row Size Includes BLOB | DBPROP_MAXROWSIZEINCLUDESBLOB
Maximum Tables in SELECT | DBPROP_MAXTABLESINSELECT
Mode | DBPROP_INIT_MODE
Multiple Parameter Sets | DBPROP_MULTIPLEPARAMSETS
Multiple Results | DBPROP_MULTIPLERESULTS
Multiple Storage Objects | DBPROP_MULTIPLESTORAGEOBJECTS
Multi-Table Update | DBPROP_MULTITABLEUPDATE
NULL Collation Order | DBPROP_NULLCOLLATION
NULL Concatenation Behavior | DBPROP_CONCATNULLBEHAVIOR
OLE DB Services | DBPROP_INIT_OLEDBSERVICES
OLE DB Version | DBPROP_PROVIDEROLEDBVER
OLE Object Support | DBPROP_OLEOBJECTS
Open Rowset Support | DBPROP_OPENROWSETSUPPORT
ORDER BY Columns in Select List | DBPROP_ORDERBYCOLUMNSINSELECT
Output Parameter Availability | DBPROP_OUTPUTPARAMETERAVAILABILITY
Password | DBPROP_AUTH_PASSWORD
Pass By Ref Accessors | DBPROP_BYREFACCESSORS
Persist Security Info | DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO
Persistent ID Type | DBPROP_PERSISTENTIDTYPE
Prepare Abort Behavior | DBPROP_PREPAREABORTBEHAVIOR
Prepare Commit Behavior | DBPROP_PREPARECOMMITBEHAVIOR
Procedure Term | DBPROP_PROCEDURETERM
Prompt | DBPROP_INIT_PROMPT
Provider Friendly Name | DBPROP_PROVIDERFRIENDLYNAME
Provider Name | DBPROP_PROVIDERFILENAME
Provider Version | DBPROP_PROVIDERVER
Read-Only Data Source | DBPROP_DATASOURCEREADONLY
Rowset Conversions on Command | DBPROP_ROWSETCONVERSIONSONCOMMAND
Schema Term | DBPROP_SCHEMATERM
Schema Usage | DBPROP_SCHEMAUSAGE
SQL Support | DBPROP_SQLSUPPORT
Structured Storage | DBPROP_STRUCTUREDSTORAGE
Subquery Support | DBPROP_SUBQUERIES
Table Term | DBPROP_TABLETERM
Transaction DDL | DBPROP_SUPPORTEDTXNDDL
User ID | DBPROP_AUTH_USERID
User Name | DBPROP_USERNAME
Window Handle | DBPROP_INIT_HWND

Recordset 动态属性

下列属性被添加到 Recordset 对象的 Properties 集合中。

ADO 属性名称 | OLE DB 属性名称
Access Order | DBPROP_ACCESSORDER
Blocking Storage Objects | DBPROP_BLOCKINGSTORAGEOBJECTS
Bookmark Type | DBPROP_BOOKMARKTYPE
Bookmarkable | DBPROP_IROWSETLOCATE
Change Inserted Rows | DBPROP_CHANGEINSERTEDROWS
Column Privileges | DBPROP_COLUMNRESTRICT
Column Set Notification | DBPROP_NOTIFYCOLUMNSET
Delay Storage Object Updates | DBPROP_DELAYSTORAGEOBJECTS
Fetch Backwards | DBPROP_CANFETCHBACKWARDS
Hold Rows | DBPROP_CANHOLDROWS
IAccessor | DBPROP_IAccessor
IColumnsInfo | DBPROP_IColumnsInfo
IColumnsRowset | DBPROP_IColumnsRowset
IConnectionPointContainer | DBPROP_IConnectionPointContainer
IConvertType | DBPROP_IConvertType
Immobile Rows | DBPROP_IMMOBILEROWS
IRowset | DBPROP_IRowset
IRowsetChange | DBPROP_IRowsetChange
IRowsetIdentity | DBPROP_IRowsetIdentity
IRowsetInfo | DBPROP_IRowsetInfo
IRowsetLocate | DBPROP_IRowsetLocate
IRowsetResynch |
IRowsetUpdate | DBPROP_IRowsetUpdate
ISequentialStream | DBPROP_ISequentialStream
ISupportErrorInfo | DBPROP_ISupportErrorInfo
Literal Bookmarks | DBPROP_LITERALBOOKMARKS
Literal Row Identity | DBPROP_LITERALIDENTITY
Maximum Open Rows | DBPROP_MAXOPENROWS
Maximum Pending Rows | DBPROP_MAXPENDINGROWS
Maximum Rows | DBPROP_MAXROWS
Notification Granularity | DBPROP_NOTIFICATIONGRANULARITY
Notification Phases | DBPROP_NOTIFICATIONPHASES
Objects Transacted | DBPROP_TRANSACTEDOBJECT
Own Changes Visible | DBPROP_OWNUPDATEDELETE
Own Inserts Visible | DBPROP_OWNINSERT
Preserve on Abort | DBPROP_ABORTPRESERVE
Preserve on Commit | DBPROP_COMMITPRESERVE
Quick Restart | DBPROP_QUICKRESTART
Reentrant Events | DBPROP_REENTRANTEVENTS
Remove Deleted Rows | DBPROP_REMOVEDELETED
Report Multiple Changes | DBPROP_REPORTMULTIPLECHANGES
Return Pending Inserts | DBPROP_RETURNPENDINGINSERTS
Row Delete Notification | DBPROP_NOTIFYROWDELETE
Row First Change Notification | DBPROP_NOTIFYROWFIRSTCHANGE
Row Insert Notification | DBPROP_NOTIFYROWINSERT
Row Privileges | DBPROP_ROWRESTRICT
Row Resynchronization Notification | DBPROP_NOTIFYROWRESYNCH
Row Threading Model | DBPROP_ROWTHREADMODEL
Row Undo Change Notification | DBPROP_NOTIFYROWUNDOCHANGE
Row Undo Delete Notification | DBPROP_NOTIFYROWUNDODELETE
Row Undo Insert Notification | DBPROP_NOTIFYROWUNDOINSERT
Row Update Notification | DBPROP_NOTIFYROWUPDATE
Rowset Fetch Position Change Notification | DBPROP_NOTIFYROWSETFETCHPOSISIONCHANGE
Rowset Release Notification | DBPROP_NOTIFYROWSETRELEASE
Scroll Backwards | DBPROP_CANSCROLLBACKWARDS
Skip Deleted Bookmarks | DBPROP_BOOKMARKSKIPPED
Strong Row Identity | DBPROP_STRONGITDENTITY
Unique Rows | DBPROP_UNIQUEROWS
Updatability | DBPROP_UPDATABILITY
Use Bookmarks | DBPROP_BOOKMARKS

Command 动态属性

下列属性被添加到 Command 对象的 Properties 集合中。

ADO 属性名称 | OLE DB 属性名称
Access Order | DBPROP_ACCESSORDER
Blocking Storage Objects | DBPROP_BLOCKINGSTORAGEOBJECTS
Bookmark Type | DBPROP_BOOKMARKTYPE
Bookmarkable | DBPROP_IROWSETLOCATE
Change Inserted Rows | DBPROP_CHANGEINSERTEDROWS
Column Privileges | DBPROP_COLUMNRESTRICT
Column Set Notification | DBPROP_NOTIFYCOLUMNSET
Delay Storage Object Updates | DBPROP_DELAYSTORAGEOBJECTS
Fetch Backwards | DBPROP_CANFETCHBACKWARDS
Hold Rows | DBPROP_CANHOLDROWS
IAccessor | DBPROP_IAccessor
IColumnsInfo | DBPROP_IColumnsInfo
IColumnsRowset | DBPROP_IColumnsRowset
IConnectionPointContainer | DBPROP_IConnectionPointContainer
IConvertType | DBPROP_IConvertType
Immobile Rows | DBPROP_IMMOBILEROWS
IRowset | DBPROP_IRowset
IRowsetChange | DBPROP_IRowsetChange
IRowsetIdentity | DBPROP_IRowsetIdentity
IRowsetInfo | DBPROP_IRowsetInfo
IRowsetLocate | DBPROP_IRowsetLocate
IRowsetResynch |
IRowsetUpdate | DBPROP_IRowsetUpdate
ISequentialStream | DBPROP_ISequentialStream
ISupportErrorInfo | DBPROP_ISupportErrorInfo
Literal Bookmarks | DBPROP_LITERALBOOKMARKS
Literal Row Identity | DBPROP_LITERALIDENTITY
Maximum Open Rows | DBPROP_MAXOPENROWS
Maximum Pending Rows | DBPROP_MAXPENDINGROWS
Maximum Rows | DBPROP_MAXROWS
Notification Granularity | DBPROP_NOTIFICATIONGRANULARITY
Notification Phases | DBPROP_NOTIFICATIONPHASES
Objects Transacted | DBPROP_TRANSACTEDOBJECT
Own Changes Visible | DBPROP_OWNUPDATEDELETE
Own Inserts Visible | DBPROP_OWNINSERT
Preserve on Abort | DBPROP_ABORTPRESERVE
Preserve on Commit | DBPROP_COMMITPRESERVE
Quick Restart | DBPROP_QUICKRESTART
Reentrant Events | DBPROP_REENTRANTEVENTS
Remove Deleted Rows | DBPROP_REMOVEDELETED
Report Multiple Changes | DBPROP_REPORTMULTIPLECHANGES
Return Pending Inserts | DBPROP_RETURNPENDINGINSERTS
Row Delete Notification | DBPROP_NOTIFYROWDELETE
Row First Change Notification | DBPROP_NOTIFYROWFIRSTCHANGE
Row Insert Notification | DBPROP_NOTIFYROWINSERT
Row Privileges | DBPROP_ROWRESTRICT
Row Resynchronization Notification | DBPROP_NOTIFYROWRESYNCH
Row Threading Model | DBPROP_ROWTHREADMODEL
Row Undo Change Notification | DBPROP_NOTIFYROWUNDOCHANGE
Row Undo Delete Notification | DBPROP_NOTIFYROWUNDODELETE
Row Undo Insert Notification | DBPROP_NOTIFYROWUNDOINSERT
Row Update Notification | DBPROP_NOTIFYROWUPDATE
Rowset Fetch Position Change Notification | DBPROP_NOTIFYROWSETFETCHPOSITIONCHANGE
Rowset Release Notification | DBPROP_NOTIFYROWSETRELEASE
Scroll Backwards | DBPROP_CANSCROLLBACKWARDS
Skip Deleted Bookmarks | DBPROP_BOOKMARKSKIP
Strong Row Identity | DBPROP_STRONGIDENTITY
Updatability | DBPROP_UPDATABILITY
Use Bookmarks | DBPROP_BOOKMARKS

请参阅 有关 Microsoft OLE DB Provider for ODBC 的实现和功能的详细信息，请参阅 OLE DB Provider for ODBC 和 Microsoft OLE DB Programmer's Reference 文档（这些文档可以在 MDAC SDK 中得到）；或者访问 Universal Data Access Web 站点。

请参阅

Command 对象 | CommandText 属性 | Connection 对象 | ConnectionString 属性 | Execute 方法 (ADO Command) | Open 方法 (ADO Recordset) | Parameters 集合 | Properties 集合 | Provider 属性 | Recordset 对象 | Supports 方法


Microsoft OLE DB Provider for Microsoft Indexing Service

Microsoft OLE DB Provider for Microsoft Indexing Service 提供了对文件系统和由 Microsoft Indexing Service 索引的 Web 数据的可编程只读访问。ADO 应用程序可以发出 SQL 查询，以检索内容和文件属性信息。

提供者将不受线程控制并允许使用 Unicode。

连接字符串参数

要连接到此提供者，请将 ConnectionString 属性的 Provider= 参数设置为：

MSIDXS

读取 Provider 属性也将返回此字符串。

典型连接字符串

此提供者的典型连接字符串是：

"Provider=MSIDXS;Data Source=myCatalog;Locale Identifier=nnnn;"

该字符串包含下列关键字：

关键字 | 说明
Provider | 指定 OLE DB Provider for Microsoft Indexing Service。通常，这是连接字符串中指定的唯一关键字。
Data Source | 指定 Indexing Service 目录名称。如果未指定此关键字，将使用默认系统目录。
Locale Identifier | 指定唯一的 32 位数字（例如，1033），该数字指定与用户语言相关的首选项。这些首选项指示格式化日期和时间的方式、按字母顺序排列项目的方式、比较字符串的方式等等。如果未指定此关键字，将使用默认系统本地标识符。

命令文本

Indexing Service SQL 查询语法由 SQL-92 SELECT 语句的扩展及其 FROM 和 WHERE 子句组成。查询的结果将通过 OLE DB 行集合返回，这些结果可以被 ADO 使用并被当作 Recordset 对象操作。

可以搜索确切的词或短语，也可以使用通配符来搜索词的模式或出处。可以基于布尔运算、加权项目或与其他词的相近性进行搜索逻辑。也可以通过“自由文本”进行搜索，它根据意思而不是确切的词来查找匹配之处。

特定命令方言在 Microsoft Indexing Service Reference 中有完整的说明。

提供者不接受存储过程调用或简单的表名（例如，CommandType 属性将始终是 adCmdText）。

Recordset 行为

下表列出了由此提供者打开的 Recordset 对象的可用功能。只有静态游标类型 (adOpenStatic) 可用。

有关针对提供者配置的 Recordset 行为的详细信息，请运行 Supports 方法并枚举 Recordset 的 Properties 集合，以确定提供者特有的动态属性是否存在。

标准 ADO Recordset 属性的可用性：

属性 | 可用性
AbsolutePage | 读/写
AbsolutePosition | 读/写
ActiveConnection | 只读
BOF | 只读
Bookmark* | 读/写
CacheSize | 读/写
CursorLocation | 总是 adUseServer
CursorType | 总是 adOpenStatic
EditMode | 总是 adEditNone
EOF | 只读
Filter | 读/写
LockType | 读/写
MarshalOptions | 不可用
MaxRecords | 读/写
PageCount | 只读
PageSize | 读/写
RecordCount | 只读
Source | 读/写
State | 只读
Status | 只读

* 必须在提供者上激活书签以使 Recordset 具备此功能。

标准 ADO Recordset 方法的可用性：

方法 | 可用？
AddNew | 否
Cancel | 是
CancelBatch | 否
CancelUpdate | 否
Clone | 是
Close | 是
Delete | 否
GetRows | 是
Move | 是
MoveFirst | 是
NextRecordset | 是
Open | 是
Requery | 是
Resync | 是
Supports | 是
Update | 否
UpdateBatch | 否

请参阅 有关 Microsoft OLE DB Provider for Microsoft Index Server 的实现和功能的详细信息，请参阅 Microsoft OLE DB Programmer's Reference 和 Microsoft Indexing Service 文档，或者访问 Microsoft Internet Information Services Web 页。

请参阅

CommandType 属性 | ConnectionString 属性 | Properties 集合 | Provider 属性 | Recordset 对象 | Supports 方法


Microsoft OLE DB Provider for Microsoft Active Directory Service

Microsoft Active Directory Service Interfaces (ADSI) 提供者允许 ADO 通过 ADSI 连接到不同种类的目录服务。它使 ADO 应用程序可以以只读方式访问 Microsoft Windows NT 4.0 和 Microsoft Windows 2000 目录服务以及所有 LDAP 兼容的目录服务和 Novell 目录服务。ADSI 本身基于一个提供者模型，所以如果有新的提供者提供对其他目录的访问权限，ADO 应用程序将可以对其进行无缝访问。ADSI 提供者将不受线程控制并允许使用 Unicode。

连接字符串参数

要连接此提供者，请将 ConnectionString 属性的 Provider 参数设置为：

ADSDSOObject

读取 Provider 属性也将返回此字符串。

典型连接字符串

此提供者的典型连接字符串是：

"Provider=ADSDSOObject;User ID=userName;Password=userPassword;"

该字符串包含下列关键字：

关键字 | 说明
Provider | 指定 OLE DB Provider for Microsoft Active Directory Service。
User ID | 指定用户名称。如果省略此关键字，则使用当前登录。
Password | 指定用户密码。如果省略此关键字，则使用当前登录。

命令文本

在下列语法中，提供者能识别由四部分组成的命令文本字符串：

"Root; Filter; Attributes[; Scope]"
值 | 说明
Root | 指示开始搜索（即搜索的根）处的 ADsPath 对象。
Filter | 指示 RFC 1960 格式中的搜索过滤器。
Attributes | 指示要返回的用逗号分隔的属性列表。
Scope 可选。String，指定搜索范围。可以是下列字符串之一：
  • Base — 只搜索基本对象（搜索的根）。
  • OneLevel — 只搜索一级。
  • Subtree — 搜索整个子树。

例如：

"<LDAP://DC=ArcadiaBay,DC=COM>;(objectClass=*);sn, givenName; subtree"

提供者还支持命令文本中的 SQL SELECT。例如：

"SELECT title, telephoneNumber From 'LDAP://DC=Microsoft, DC=COM' WHERE
objectClass='user' AND objectCategory='Person'"

提供者不接受存储过程调用或简单的表名（例如，CommandType 属性将始终是 adCmdText）。有关命令文本元素的更完整的说明，请参阅 Active Directory Service Interfaces 文档。

Recordset 行为

下表列出了由该提供者打开的 Recordset 对象上的可用功能。只有静态游标类型 (adOpenStatic) 可用。

有关提供者配置的 Recordset 行为的详细信息，请运行 Supports 方法并枚举 Recordset 的 Properties 集合，以确定提供者特有的动态属性是否存在。

标准 ADO Recordset 属性的可用性：

属性 | 可用性
AbsolutePage | 读/写
AbsolutePosition | 读/写
ActiveConnection | 只读
BOF | 只读
Bookmark | 读/写
CacheSize | 读/写
CursorLocation | 总是 adUseServer
CursorType | 总是 adOpenStatic
EditMode | 总是 adEditNone
EOF | 只读
Filter | 读/写
LockType | 读/写
MarshalOptions | 不可用
MaxRecords | 读/写
PageCount | 只读
PageSize | 读/写
RecordCount | 只读
Source | 读/写
State | 只读
Status | 只读

标准 ADO Recordset 方法的可用性：

方法 | 可用？
AddNew | 否
Cancel | 否
CancelBatch | 否
CancelUpdate | 否
Clone | 是
Close | 是
Delete | 否
GetRows | 是
Move | 是
MoveFirst | 是
MoveLast | 是
MoveNext | 是
MovePrevious | 是
NextRecordset | 是
Open | 是
Requery | 是
Resync | 是
Supports | 是
Update | 否
UpdateBatch | 否

请参阅 有关 ADSI 的其他基本信息和提供者特有的信息，请参阅 Active Directory Service Interfaces 文档或者访问 ADSI Web 页。

请参阅

CommandType 属性 | ConnectionString 属性 | Properties 集合 | Provider 属性 | Recordset 对象 | Supports 方法


Microsoft OLE DB Provider for Microsoft Jet

OLE DB Provider for Microsoft Jet 允许 ADO 访问 Microsoft Jet 数据库。

连接字符串参数

要连接此提供者，请将 ConnectionString 属性的 Provider 参数设置为：

Microsoft.Jet.OLEDB.4.0

读取 Provider 属性也将返回此字符串。

典型连接字符串

此提供者的典型连接字符串是：

"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=databaseName;User ID=userName;Password=userPassword;"

该字符串包含下列关键字：

关键字 | 说明
Provider | 指定 OLE DB Provider for Microsoft Jet。
Data Source | 指定数据库路径和文件名（例如，c:\Northwind.mdb）。
User ID | 指定用户名称。如果未指定此关键字，则默认使用字符串 "admin"。
Password | 指定用户密码。如果未指定此关键字，则默认使用空字符串 ("")。

提供者特有的连接参数

除了 ADO 定义的动态属性外，OLE DB Provider for Microsoft Jet 还支持几个提供者特有的动态属性。象所有其他 Connection 参数一样，可以通过 Connection 对象的 Properties 集合或作为连接字符串的一部分来设置这些参数。

下表列出了这些属性，括号中为相应的 OLE DB 属性名称。

参数 | 说明
Jet OLEDB:Compact Reclaimed Space Amount (DBPROP_JETOLEDB_COMPACTFREESPACESIZE) | 指示空间的估计字节数，可以通过压缩数据库来回收空间。此值只有在建立数据库连接后才有效。
Jet OLEDB:Connection Control (DBPROP_JETOLEDB_CONNECTIONCONTROL) | 指示用户是否可以连接到该数据库。
Jet OLEDB:Create System Database (DBPROP_JETOLEDB_CREATESYSTEMDATABASE) | 指示创建新数据源时是否创建系统数据库。
Jet OLEDB:Database Locking Mode (DBPROP_JETOLEDB_DATABASELOCKMODE) | 指示此数据库的锁定模式。用于打开数据库的第一个用户确定了数据库打开时所使用的模式。
Jet OLEDB:Database Password (DBPROP_JETOLEDB_DATABASEPASSWORD) | 指示数据库密码。
Jet OLEDB:Don't Copy Locale on Compact (DBPROP_JETOLEDB_COMPACT_DONTCOPYLOCALE) | 指示压缩数据库时 Jet 是否复制地区信息。
Jet OLEDB:Encrypt Database (DBPROP_JETOLEDB_ENCRYPTDATABASE) | 指示压缩的数据库是否要加密。如果未设置此属性而且原数据库也是加密的，则压缩的数据库将被加密。
Jet OLEDB:Engine Type (DBPROP_JETOLEDB_ENGINE) | 指示用于访问当前数据存储的存储引擎。
Jet OLEDB:Exclusive Async Delay (DBPROP_JETOLEDB_EXCLUSIVEASYNCDELAY) | 指示当数据库以独占模式打开时，Jet 对磁盘的异步写入可以延迟的最大毫秒数。 除非将 Jet OLEDB:Flush Transaction Timeout 设置为 0，否则可忽略此属性。
Jet OLEDB:Flush Transaction Timeout (DBPROP_JETOLEDB_FLUSHTRANSACTIONTIMEOUT) | 指示缓存中用于异步写入的数据真正写入磁盘之前等待的时间长度。此设置覆盖了 Jet OLEDB:Shared Async Delay 和 Jet OLEDB:Exclusive Async Delay 的值。
Jet OLEDB:Global Bulk Transactions (DBPROP_JETOLEDB_GLOBALBULKNOTRANSACTIONS) | 指示是否处理 SQL 大量事务。
Jet OLEDB:Global Partial Bulk Ops (DBPROP_JETOLEDB_GLOBALBULKPARTIAL) | 指示用于打开数据库的密码。
Jet OLEDB:Implicit Commit Sync (DBPROP_JETOLEDB_IMPLICITCOMMITSYNC) | 指示对内部隐式事务所做的更改是以同步模式还是以异步模式写入。
Jet OLEDB:Lock Delay (DBPROP_JETOLEDB_LOCKDELAY) | 指示在上一次尝试获取锁定失败后再次尝试之前等待的毫秒数。
Jet OLEDB:Lock Retry (DBPROP_JETOLEDB_LOCKRETRY) | 指示试图访问锁定页的重复次数。
Jet OLEDB:Max Buffer Size (DBPROP_JETOLEDB_MAXBUFFERSIZE) | 指示 Jet 在开始刷新磁盘上的更改之前可以使用的最大内存量（以千字节为单位）。
Jet OLEDB:Max Locks Per File (DBPROP_JETOLEDB_MAXLOCKSPERFILE) | 指示 Jet 可以对数据库设置的最大锁定数目。默认值为 9500。
Jet OLEDB:New Database Password (DBPROP_JETOLEDB_NEWDATABASEPASSWORD) | 指示为此数据库设置的新密码。旧密码存储在 Jet OLEDB:Database Password 中。
Jet OLEDB:ODBC Command Time Out (DBPROP_JETOLEDB_ODBCCOMMANDTIMEOUT) | 指示来自 Jet 的远程 ODBC 查询超时之前的毫秒数。
Jet OLEDB:Page Locks to Table Lock (DBPROP_JETOLEDB_PAGELOCKSTOTABLELOCK) | 指示在 Jet 试图把锁定提升到表锁定之前需要在事务内部锁定的页数。如果此值为 0，则不会提升锁定。
Jet OLEDB:Page Timeout (DBPROP_JETOLEDB_PAGETIMEOUT) | 指示 Jet 在检查其缓存与数据库文件相比是否过时之前等待的毫秒数。
Jet OLEDB:Recycle Long-Valued Pages (DBPROP_JETOLEDB_RECYCLELONGVALUEPAGES) | 指示 Jet 是否应该在释放 BLOB 页时强制将其回收。
Jet OLEDB:Registry Path (DBPROP_JETOLEDB_REGPATH) | 指示包含 Jet 数据库引擎值的 Windows 注册表键。
Jet OLEDB:Reset ISAM Stats (DBPROP_JETOLEDB_RESETISAMSTATS) | 指示模式 Recordset DBSCHEMA_JETOLEDB_ISAMSTATS 是否应该在返回性能信息后重置其性能计数器。
Jet OLEDB:Shared Async Delay (DBPROP_JETOLEDB_SHAREDASYNCDELAY) | 指示当数据库以多用户模式打开时，Jet 对磁盘的异步写入可以延迟的最大毫秒数。
Jet OLEDB:System Database (DBPROP_JETOLEDB_SYSDBPATH) | 指示工作组信息文件（系统数据库）的路径和文件名。
Jet OLEDB:Transaction Commit Mode (DBPROP_JETOLEDB_TXNCOMMITMODE) | 指示事务提交时 Jet 是同步还是异步向磁盘写入数据。
Jet OLEDB:User Commit Sync (DBPROP_JETOLEDB_USERCOMMITSYNC) | 指示对事务所做的更改是以同步还是异步模式写入。

提供者特有的 Recordset 和 Command 属性

Jet 提供者还支持多个提供者特有的 Recordset 和 Command 属性。这些属性可以通过 Recordset 或 Command 对象的 Properties 集合进行访问和设置。表中列出了 ADO 属性名称，括号内为相应的 OLE DB 属性名。

属性名称 | 说明
Jet OLEDB:Bulk Transactions (DBPROP_JETOLEDB_BULKNOTRANSACTIONS) | 指示是否处理 SQL 大量操作。由于资源延迟，处理大量操作时可能会失败。
Jet OLEDB:Enable Fat Cursors (DBPROP_JETOLEDB_ENABLEFATCURSOR) | 指示预置远程行源的记录集时 Jet 是否应该缓存多行。
Jet OLEDB:Fat Cursor Cache Size (DBPROP_JETOLEDB_FATCURSORMAXROWS) | 指示使用远程数据存储行进行缓存时缓存的行数。除非 Jet OLEDB:Enable Fat Cursors 为 Ture，否则将忽略此值。
Jet OLEDB:Inconsistent (DBPROP_JETOLEDB_INCONSISTENT) | 指示查询结果是否允许不一致的更新。
Jet OLEDB:Locking Granularity (DBPROP_JETOLEDB_LOCKGRANULARITY) | 指示表是否使用行级锁定打开。
Jet OLEDB:ODBC Pass-Through Statement (DBPROP_JETOLEDB_ODBCPASSTHROUGH) | 指示 Jet 应该把 Command 对象中的 SQL 文本不加改变地传递到后端。
Jet OLEDB:Partial Bulk Ops (DBPROP_JETOLEDB_BULKPARTIAL) | 指示当 SQL DML 操作失败时 Jet 的行为。
Jet OLEDB:Pass Through Query Bulk-Op (DBPROP_JETOLEDB_PASSTHROUGHBULKOP) | 指示是否将不返回 Recordset 的查询不加改变地传递给数据源。
Jet OLEDB:Pass Through Query Connect String (DBPROP_JETOLEDB_ODBCPASSTHROUGHCONNECTSTRING) | 指示用于连接到远程数据存储的 Jet 连接字符串。除非 Jet OLEDB:ODBC Pass-Through Statement 为 Ture，否则将忽略此值。
Jet OLEDB:Stored Query (DBPROP_JETOLEDB_STOREDQUERY) | 指示是否应该将命令文本解释为存储查询而不是 SQL 命令。
Jet OLEDB:Validate Rules On Set (DBPROP_JETOLEDB_VALIDATEONSET) | 指示在设置列数据或向数据库提交更改时是否计算 Jet 验证规则。

默认情况下，OLE DB Provider for Microsoft Jet 以读/写模式打开 Microsoft Jet 数据库。要以只读模式打开数据库，请把 ADO Connection 对象的 Mode 属性设置为 adModeRead。

Command 对象的用法

Command 对象中的命令文本使用 Microsoft Jet SQL 方言。可以在命令文本中指定行返回查询、操作查询和表名，但存储过程将不受支持也不能指定。

Recordset 行为

Microsoft Jet 数据库引擎不支持动态游标。因此，OLE DB Provider for Microsoft Jet 不支持 adLockDynamic 游标类型。请求动态游标时，提供者将返回一个键集游标并重置 CursorType 属性以指示返回的 Recordset 的类型。另外，如果请求可更新的 Recordset（LockType 为 adLockOptimistic、adLockBatchOptimistic 或 adLockPessimistic），提供者也将返回一个键集游标并重置 CursorType 属性。

动态属性

OLE DB Provider for Microsoft Jet 向未打开的 Connection、Recordset 和 Command 对象的 Properties 集合中插入了多个动态属性。

下表是每个动态属性的 ADO 和 OLE DB 名称的交叉索引。OLE DB Programmer's Reference 使用“Description”项 引用 ADO 属性名称。有关这些属性的详细信息，请参阅 OLE DB Programmer's Reference。请在“索引”中搜索 OLE DB 属性名称或参阅 Appendix C:OLE DB Properties。

Connection 动态属性

下列属性被添加到 Connection 对象的 Properties 集合中。

ADO 属性名称 | OLE DB 属性名称
Active Sessions | DBPROP_ACTIVESESSIONS
Asynchable Abort | DBPROP_ASYNCTXNABORT
Asynchable Commit | DBPROP_ASYNCTNXCOMMIT
Autocommit Isolation Levels | DBPROP_SESS_AUTOCOMMITISOLEVELS
Catalog Location | DBPROP_CATALOGLOCATION
Catalog Term | DBPROP_CATALOGTERM
Column Definition | DBPROP_COLUMNDEFINITION
Current Catalog | DBPROP_CURRENTCATALOG
Data Source | DBPROP_INIT_DATASOURCE
Data Source Name | DBPROP_DATASOURCENAME
Data Source Object Threading Model | DBPROP_DSOTHREADMODEL
DBMS Name | DBPROP_DBMSNAME
DBMS Version | DBPROP_DBMSVER
GROUP BY Support | DBPROP_GROUPBY
Heterogeneous Table Support | DBPROP_HETEROGENEOUSTABLES
Identifier Case Sensitivity | DBPROP_IDENTIFIERCASE
Isolation Levels | DBPROP_SUPPORTEDTXNISOLEVELS
Isolation Retention | DBPROP_SUPPORTEDTXNISORETAIN
Locale Identifier | DBPROP_INIT_LCID
Maximum Index Size | DBPROP_MAXINDEXSIZE
Maximum Row Size | DBPROP_MAXROWSIZE
Maximum Row Size Includes BLOB | DBPROP_MAXROWSIZEINCLUDESBLOB
Maximum Tables in SELECT | DBPROP_MAXTABLESINSELECT
Mode | DBPROP_INIT_MODE
Multiple Parameter Sets | DBPROP_MULTIPLEPARAMSETS
Multiple Results | DBPROP_MULTIPLERESULTS
Multiple Storage Objects | DBPROP_MULTIPLESTORAGEOBJECTS
Multi-Table Update | DBPROP_MULTITABLEUPDATE
NULL Collation Order | DBPROP_NULLCOLLATION
NULL Concatenation Behavior | DBPROP_CONCATNULLBEHAVIOR
OLE DB Version | DBPROP_PROVIDEROLEDBVER
OLE Object Support | DBPROP_OLEOBJECTS
Open Rowset Support | DBPROP_OPENROWSETSUPPORT
ORDER BY Columns in Select List | DBPROP_ORDERBYCOLUMNSINSELECT
Output Parameter Availability | DBPROP_OUTPUTPARAMETERAVAILABILITY
Pass By Ref Accessors | DBPROP_BYREFACCESSORS
Password | DBPROP_AUTH_PASSWORD
Persistent ID Type | DBPROP_PERSISTENTIDTYPE
Prepare Abort Behavior | DBPROP_PREPAREABORTBEHAVIOR
Prepare Commit Behavior | DBPROP_PREPARECOMMITBEHAVIOR
Procedure Term | DBPROP_PROCEDURETERM
Prompt | DBPROP_INIT_PROMPT
Provider Friendly Name | DBPROP_PROVIDERFRIENDLYNAME
Provider Name | DBPROP_PROVIDERFILENAME
Provider Version | DBPROP_PROVIDERVER
Read-Only Data Source | DBPROP_DATASOURCEREADONLY
Rowset Conversions on Command | DBPROP_ROWSETCONVERSIONSONCOMMAND
Schema Term | DBPROP_SCHEMATERM
Schema Usage | DBPROP_SCHEMAUSAGE
SQL Support | DBPROP_SQLSUPPORT
Structured Storage | DBPROP_STRUCTUREDSTORAGE
Subquery Support | DBPROP_SUBQUERIES
Table Term | DBPROP_TABLETERM
Transaction DDL | DBPROP_SUPPORTEDTXNDDL
User ID | DBPROP_AUTH_USERID
User Name | DBPROP_USERNAME
Window Handle | DBPROP_INIT_HWND

Recordset 动态属性

下列属性被添加到 Recordset 对象的 Properties 集合中。

ADO 属性名称 | OLE DB 属性名称
Access Order | DBPROP_ACCESSORDER
Append-Only Rowset | DBPROP_APPENDONLY
Blocking Storage Objects | DBPROP_BLOCKINGSTORAGEOBJECTS
Bookmark Type | DBPROP_BOOKMARKTYPE
Bookmarkable | DBPROP_IROWSETLOCATE
Bookmarks Ordered | DBPROP_ORDEREDBOOKMARKS
Cache Deferred Columns | DBPROP_CACHEDEFERRED
Change Inserted Rows | DBPROP_CHANGEINSERTEDROWS
Column Privileges | DBPROP_COLUMNRESTRICT
Column Set Notification | DBPROP_NOTIFYCOLUMNSET
Column Writable | DBPROP_MAYWRITECOLUMN
Defer Column | DBPROP_DEFERRED
Delay Storage Object Updates | DBPROP_DELAYSTORAGEOBJECTS
Fetch Backwards | DBPROP_CANFETCHBACKWARDS
Hold Rows | DBPROP_CANHOLDROWS
IAccessor | DBPROP_IAccessor
IColumnsInfo | DBPROP_IColumnsInfo
IColumnsRowset | DBPROP_IColumnsRowset
IConnectionPointContainer | DBPROP_IConnectionPointContainer
IConvertType | DBPROP_IConvertType
ILockBytes | DBPROP_ILockBytes
Immobile Rows | DBPROP_IMMOBILEROWS
IRowset | DBPROP_IRowset
IRowsetChange | DBPROP_IRowsetChange
IRowsetIdentity | DBPROP_IRowsetIdentity
IRowsetIndex | DBPROP_IRowsetIndex
IRowsetInfo | DBPROP_IRowsetInfo
IRowsetLocate | DBPROP_IRowsestLocate
IRowsetResynch |
IRowsetScroll | DBPROP_IRowsetScroll
IRowsetUpdate | DBPROP_IRowsetUpdate
ISequentialStream | DBPROP_ISequentialStream
IStorage | DBPROP_IStorage
IStream | DBPROP_IStream
ISupportErrorInfo | DBPROP_ISupportErrorInfo
Literal Bookmarks | DBPROP_LITERALBOOKMARKS
Literal Row Identity | DBPROP_LITERALIDENTITY
Maximum Open Rows | DBPROP_MAXOPENROWS
Maximum Pending Rows | DBPROP_MAXPENDINGROWS
Maximum Rows | DBPROP_MAXROWS
Memory Usage | DBPROP_MEMORYUSAGE
Notification Granularity | DBPROP_NOTIFICATIONGRANULARITY
Notification Phases | DBPROP_NOTIFICATIONPHASES
Objects Transacted | DBPROP_TRANSACTEDOBJECT
Others' Changes Visible | DBPROP_OTHERUPDATEDELETE
Others' Inserts Visible | DBPROP_OTHERINSERT
Own Changes Visible | DBPROP_OWNUPDATEDELETE
Own Inserts Visible | DBPROP_OWNINSERT
Preserve on Abort | DBPROP_ABORTPRESERVE
Preserve on Commit | DBPROP_COMMITPRESERVE
Quick Restart | DBPROP_QUICKRESTART
Reentrant Events | DBPROP_REENTRANTEVENTS
Remove Deleted Rows | DBPROP_REMOVEDELETED
Report Multiple Changes | DBPROP_REPORTMULTIPLECHANGES
Return Pending Inserts | DBPROP_RETURNPENDINGINSERTS
Row Delete Notification | DBPROP_NOTIFYROWDELETE
Row First Change Notification | DBPROP_NOTIFYROWFIRSTCHANGE
Row Insert Notification | DBPROP_NOTIFYROWINSERT
Row Privileges | DBPROP_ROWRESTRICT
Row Resynchronization Notification | DBPROP_NOTIFYROWRESYNCH
Row Threading Model | DBPROP_ROWTHREADMODEL
Row Undo Change Notification | DBPROP_NOTIFYROWUNDOCHANGE
Row Undo Delete Notification | DBPROP_NOTIFYROWUNDODELETE
Row Undo Insert Notification | DBPROP_NOTIFYROWUNDOINSERT
Row Update Notification | DBPROP_NOTIFYROWUPDATE
Rowset Fetch Position Change Notification | DBPROP_NOTIFYROWSETFETCHPOSISIONCHANGE
Rowset Release Notification | DBPROP_NOTIFYROWSETRELEASE
Scroll Backwards | DBPROP_CANSCROLLBACKWARDS
Skip Deleted Bookmarks | DBPROP_BOOKMARKSKIPPED
Strong Row Identity | DBPROP_STRONGITDENTITY
Updatability | DBPROP_UPDATABILITY
Use Bookmarks | DBPROP_BOOKMARKS

Command 动态属性

下列属性被添加到 Command 对象的 Properties 集合中。

ADO 属性名称 | OLE DB 属性名称
Access Order | DBPROP_ACCESSORDER
Append-Only Rowset | DBPROP_APPENDONLY
Blocking Storage Objects | DBPROP_BLOCKINGSTORAGEOBJECTS
Bookmark Type | DBPROP_BOOKMARKTYPE
Bookmarkable | DBPROP_IROWSETLOCATE
Change Inserted Rows | DBPROP_CHANGEINSERTEDROWS
Column Privileges | DBPROP_COLUMNRESTRICT
Column Set Notification | DBPROP_NOTIFYCOLUMNSET
Defer Column | DBPROP_DEFERRED
Delay Storage Object Updates | DBPROP_DELAYSTORAGEOBJECTS
Fetch Backwards | DBPROP_CANFETCHBACKWARDS
Hold Rows | DBPROP_CANHOLDROWS
IAccessor | DBPROP_IAccessor
IColumnsInfo | DBPROP_IColumnsInfo
IColumnsRowset | DBPROP_IColumnsRowset
IConnectionPointContainer | DBPROP_IConnectionPointContainer
IConvertType | DBPROP_IConvertType
ILockBytes | DBPROP_ILockBytes
Immobile Rows | DBPROP_IMMOBILEROWS
IRowset | DBPROP_IRowset
IRowsetChange | DBPROP_IRowsetChange
IRowsetIdentity | DBPROP_IRowsetIdentity
IRowsetIndex | DBPROP_IRowsetIndex
IRowsetInfo | DBPROP_IRowsetInfo
IRowsetLocate | DBPROP_IRowsetLocate
IRowsetResynch |
IRowsetScroll | DBPROP_IRowsetScroll
IRowsetUpdate | DBPROP_IRowsetUpdate
ISequentialStream | DBPROP_ISequentialStream
IStorage | DBPROP_IStorage
IStream | DBPROP_IStream
ISupportErrorInfo | DBPROP_ISupportErrorInfo
Literal Bookmarks | DBPROP_LITERALBOOKMARKS
Literal Row Identity | DBPROP_LITERALIDENTITY
Lock Mode | DBPROP_LOCKMODE
Maximum Open Rows | DBPROP_MAXOPENROWS
Maximum Pending Rows | DBPROP_MAXPENDINGROWS
Maximum Rows | DBPROP_MAXROWS
Notification Granularity | DBPROP_NOTIFICATIONGRANULARITY
Notification Phases | DBPROP_NOTIFICATIONPHASES
Objects Transacted | DBPROP_TRANSACTEDOBJECT
Others' Changes Visible | DBPROP_OTHERUPDATEDELETE
Others' Inserts Visible | DBPROP_OTHERINSERT
Own Changes Visible | DBPROP_OWNUPDATEDELETE
Own Inserts Visible | DBPROP_OWNINSERT
Preserve on Abort | DBPROP_ABORTPRESERVE
Preserve on Commit | DBPROP_COMMITPRESERVE
Quick Restart | DBPROP_QUICKRESTART
Reentrant Events | DBPROP_REENTRANTEVENTS
Remove Deleted Rows | DBPROP_REMOVEDELETED
Report Multiple Changes | DBPROP_REPORTMULTIPLECHANGES
Return Pending Inserts | DBPROP_RETURNPENDINGINSERTS
Row Delete Notification | DBPROP_NOTIFYROWDELETE
Row First Change Notification | DBPROP_NOTIFYROWFIRSTCHANGE
Row Insert Notification | DBPROP_NOTIFYROWINSERT
Row Privileges | DBPROP_ROWRESTRICT
Row Resynchronization Notification | DBPROP_NOTIFYROWRESYNCH
Row Threading Model | DBPROP_ROWTHREADMODEL
Row Undo Change Notification | DBPROP_NOTIFYROWUNDOCHANGE
Row Undo Delete Notification | DBPROP_NOTIFYROWUNDODELETE
Row Undo Insert Notification | DBPROP_NOTIFYROWUNDOINSERT
Row Update Notification | DBPROP_NOTIFYROWUPDATE
Rowset Fetch Position Change Notification | DBPROP_NOTIFYROWSETFETCHPOSITIONCHANGE
Rowset Release Notification | DBPROP_NOTIFYROWSETRELEASE
Scroll Backwards | DBPROP_CANSCROLLBACKWARDS
Server Data on Insert | DBPROP_SERVERDATAONINSERT
Skip Deleted Bookmarks | DBPROP_BOOKMARKSKIP
Strong Row Identity | DBPROP_STRONGIDENTITY
Updatability | DBPROP_UPDATABILITY
Use Bookmarks | DBPROP_BOOKMARKS

请参阅 有关 OLE DB Provider for Microsoft Jet 的特定实现和功能的详细信息，请参阅 MDAC SDK 中的 OLE DB Provider for Microsoft Jet 文档。

请参阅

ConnectionString 属性 | Provider 属性 | Recordset 对象

OLE DB 文档中的“OLE DB Provider for Microsoft Jet”。


Microsoft OLE DB Provider for SQL Server

Microsoft OLE DB Provider for SQL Server (SQLOLEDB) 允许 ADO 访问 Microsoft SQL Server。

连接字符串参数

要连接此提供者，请将 ConnectionString 属性的 Provider 参数设置为：

SQLOLEDB

也可以使用 Provider 属性设置或读取此值。

典型连接字符串

此提供者的典型连接字符串是：

"Provider=SQLOLEDB;Data Source=serverName;"Initial Catalog=databaseName;
User ID=userName;Password=userPassword;"

该字符串包含下列关键字：

关键字 | 说明
Provider | 指定 OLE DB Provider for SQL Server。
Data Source 或 Server | 指定服务器的名称。
Initial Catalog 或 Database | 指定服务器上的数据库名称。
User ID 或 uid | 指定用户名（用于 SQL Server Authentication）。
Password 或 pwd | 指定用户密码（用于 SQL Server Authentication）。

提供者特有的连接参数

除了由 ADO 定义的连接参数以外，该提供者还支持几种提供者特有的连接参数。象 ADO 连接参数一样，这些提供者特有的属性可以通过 Connection 的 Properties 集合或作为 ConnectionString 的一部分进行设置。

参数 | 说明
Trusted_Connection | 指示用户的身份验证模式。可以将它设置为 Yes 或 No。默认值为 No。如果将此属性设置为 Yes，则 SQLOLEDB 使用 Microsoft Windows NT “验证模式”授权用户访问由 Location 和 Datasource 属性值指定的 SQL Server 数据库。如果将此属性设置为 No，则 SQLOLEDB 使用“混合模式”授权用户访问 SQL Server 数据库。SQL Server 的登录和密码在 User Id 和 Password 属性中指定。
Current Language | 指示 SQL Server 语言名。标识系统消息选择和格式化所使用的语言。该语言必须安装在 SQL Server 上，否则打开连接的操作将失败。
Network Address | 指示由 Location 属性指定的 SQL Server 的网络地址。
Network Library | 指示用来与 SQL Server 进行通讯的网络库 (DLL) 的名称。该名称不应包括路径或 .dll 文件扩展名。默认名称由 SQL Server 客户端配置提供。
Use Procedure for Prepare | 确定在（用 Prepared 属性）准备 Commands 时 SQL Server 是否创建临时存储过程。
Auto Translate | 指示是否转换 OEM/ANSI 字符。该属性可设置为 True 或 False。默认值是 True。如果将此属性设置为 True，则从 SQL Server 检索多字节字符串或将其发送到 SQL Server 时，SQLOLEDB 将执行 OEM/ANSI 字符转换。如果将此属性设置为 False，则 SQLOLEDB 不对多字节字符串数据执行 OEM/ANSI 字符转换。
Packet Size | 指示网络包的字节数。包大小属性值必须在 512 和 32767 之间。默认的 SQLOLEDB 网络包大小是 4096。
Application Name | 指示客户端应用程序的名称。
Workstation ID | 标识工作站的字符串。

Command 对象的用法

SQLOLEDB 的有效语法混合了 ODBC、ANSI 和 SQL Server 特有的 Transact-SQL。例如，下面的 SQL 语句使用 ODBC SQL 转义序列来指定 LCASE 字符串函数：

SELECT customerid={fn LCASE(CustomerID)} FROM Customers

LCASE 返回字符串，将所有大写字符转换为相同的小写字符。ANSI SQL 字符串函数 LOWER 执行相同的操作，因此，下面的 SQL 语句是上述 ODBC 语句的 ANSI 等价语句：

SELECT customerid=LOWER(CustomerID) FROM Customers

当被指定为命令的文本时，SQLOLEDB 能成功地处理任何一种格式的语句。

存储过程

当使用 SQLOLEDB 命令执行 SQL Server 存储过程时，请在命令文本中使用 ODBC 过程调用转义序列。然后，SQLOLEDB 使用 SQL Server 的远程过程调用机制来优化命令的处理。例如，下面的 ODBC SQL 语句是 Transact-SQL 格式上的首选命令文本：

ODBC SQL

{call SalesByCategory('Produce', '1995')}

Transact-SQL

EXECUTE SalesByCategory 'Produce', '1995'

Recordset 行为

SQLOLEDB 不能使用 SQL Server 游标来支持由多个命令生成的多个结果。如果客户请求需要 SQL Server 游标支持的记录集，那么当所使用的命令文本在其结果中生成多个记录集时，将发生错误。

SQL Server 游标支持可卷动的 SQLOLEDB 记录集。SQL Server 限制对其他数据库用户所做的更改敏感的游标。特别是一些游标中的行不能排序，试图使用包含 SQL ORDER BY 子句的命令创建记录集将导致失败。

动态属性

Microsoft OLE DB Provider for SQL Server 向未打开的 Connection、Recordset 和 Command 对象的 Properties 集合中插入了多个动态属性。

下表是每个动态属性的 ADO 和 OLE DB 名称的交叉索引。OLE DB Programmer's Reference 使用“Description”项引用 ADO 属性名称。有关这些属性的详细信息，请参阅 OLE DB Programmer's Reference。请在“索引”中搜索 OLE DB 属性名称或参阅 Appendix C: OLE DB Properties。

Connection 动态属性

下列属性被添加到 Connection 对象的 Properties 集合中。

ADO 属性名称 | OLE DB 属性名称
Active Sessions | DBPROP_ACTIVESESSIONS
Asynchable Abort | DBPROP_ASYNCTXNABORT
Asynchable Commit | DBPROP_ASYNCTNXCOMMIT
Autocommit Isolation Levels | DBPROP_SESS_AUTOCOMMITISOLEVELS
Catalog Location | DBPROP_CATALOGLOCATION
Catalog Term | DBPROP_CATALOGTERM
Column Definition | DBPROP_COLUMNDEFINITION
Connect Timeout | DBPROP_INIT_TIMEOUT
Current Catalog | DBPROP_CURRENTCATALOG
Data Source | DBPROP_INIT_DATASOURCE
Data Source Name | DBPROP_DATASOURCENAME
Data Source Object Threading Model | DBPROP_DSOTHREADMODEL
DBMS Name | DBPROP_DBMSNAME
DBMS Version | DBPROP_DBMSVER
Extended Properties | DBPROP_INIT_PROVIDERSTRING
GROUP BY Support | DBPROP_GROUPBY
Heterogeneous Table Support | DBPROP_HETEROGENEOUSTABLES
Identifier Case Sensitivity | DBPROP_IDENTIFIERCASE
Initial Catalog | DBPROP_INIT_CATALOG
Isolation Levels | DBPROP_SUPPORTEDTXNISOLEVELS
Isolation Retention | DBPROP_SUPPORTEDTXNISORETAIN
Locale Identifier | DBPROP_INIT_LCID
Maximum Index Size | DBPROP_MAXINDEXSIZE
Maximum Row Size | DBPROP_MAXROWSIZE
Maximum Row Size Includes BLOB | DBPROP_MAXROWSIZEINCLUDESBLOB
Maximum Tables in SELECT | DBPROP_MAXTABLESINSELECT
Multiple Parameter Sets | DBPROP_MULTIPLEPARAMSETS
Multiple Results | DBPROP_MULTIPLERESULTS
Multiple Storage Objects | DBPROP_MULTIPLESTORAGEOBJECTS
Multi-Table Update | DBPROP_MULTITABLEUPDATE
NULL Collation Order | DBPROP_NULLCOLLATION
NULL Concatenation Behavior | DBPROP_CONCATNULLBEHAVIOR
OLE DB Version | DBPROP_PROVIDEROLEDBVER
OLE Object Support | DBPROP_OLEOBJECTS
Open Rowset Support | DBPROP_OPENROWSETSUPPORT
ORDER BY Columns in Select List | DBPROP_ORDERBYCOLUMNSINSELECT
Output Parameter Availability | DBPROP_OUTPUTPARAMETERAVAILABILITY
Pass By Ref Accessors | DBPROP_BYREFACCESSORS
Password | DBPROP_AUTH_PASSWORD
Persist Security Info | DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO
Persistent ID Type | DBPROP_PERSISTENTIDTYPE
Prepare Abort Behavior | DBPROP_PREPAREABORTBEHAVIOR
Prepare Commit Behavior | DBPROP_PREPARECOMMITBEHAVIOR
Procedure Term | DBPROP_PROCEDURETERM
Prompt | DBPROP_INIT_PROMPT
Provider Friendly Name | DBPROP_PROVIDERFRIENDLYNAME
Provider Name | DBPROP_PROVIDERFILENAME
Provider Version | DBPROP_PROVIDERVER
Read-Only Data Source | DBPROP_DATASOURCEREADONLY
Rowset Conversions on Command | DBPROP_ROWSETCONVERSIONSONCOMMAND
Schema Term | DBPROP_SCHEMATERM
Schema Usage | DBPROP_SCHEMAUSAGE
SQL Support | DBPROP_SQLSUPPORT
Structured Storage | DBPROP_STRUCTUREDSTORAGE
Subquery Support | DBPROP_SUBQUERIES
Table Term | DBPROP_TABLETERM
Transaction DDL | DBPROP_SUPPORTEDTXNDDL
User ID | DBPROP_AUTH_USERID
User Name | DBPROP_USERNAME
Window Handle | DBPROP_INIT_HWND

Recordset 动态属性

下列属性被添加到 Recordset 对象的 Properties 集合中。

ADO 属性名称 | OLE DB 属性名称
Access Order | DBPROP_ACCESSORDER
Blocking Storage Objects | DBPROP_BLOCKINGSTORAGEOBJECTS
Bookmark Type | DBPROP_BOOKMARKTYPE
Bookmarkable | DBPROP_IROWSETLOCATE
Change Inserted Rows | DBPROP_CHANGEINSERTEDROWS
Column Privileges | DBPROP_COLUMNRESTRICT
Column Set Notification | DBPROP_NOTIFYCOLUMNSET
Command Time Out | DBPROP_COMMANDTIMEOUT
Defer Column | DBPROP_DEFERRED
Delay Storage Object Updates | DBPROP_DELAYSTORAGEOBJECTS
Fetch Backwards | DBPROP_CANFETCHBACKWARDS
Hold Rows | DBPROP_CANHOLDROWS
IAccessor | DBPROP_IAccessor
IColumnsInfo | DBPROP_IColumnsInfo
IColumnsRowset | DBPROP_IColumnsRowset
IConnectionPointContainer | DBPROP_IConnectionPointContainer
IConvertType | DBPROP_IConvertType
Immobile Rows | DBPROP_IMMOBILEROWS
IRowset | DBPROP_IRowset
IRowsetChange | DBPROP_IRowsetChange
IRowsetIdentity | DBPROP_IRowsetIdentity
IRowsetInfo | DBPROP_IRowsetInfo
IRowsetLocate | DBPROP_IRowsestLocate
IRowsetResynch |
IRowsetScroll | DBPROP_IRowsetScroll
IRowsetUpdate | DBPROP_IRowsetUpdate
ISequentialStream | DBPROP_ISequentialStream
ISupportErrorInfo | DBPROP_ISupportErrorInfo
Literal Bookmarks | DBPROP_LITERALBOOKMARKS
Literal Row Identity | DBPROP_LITERALIDENTITY
Maximum Open Rows | DBPROP_MAXOPENROWS
Maximum Pending Rows | DBPROP_MAXPENDINGROWS
Maximum Rows | DBPROP_MAXROWS
Notification Granularity | DBPROP_NOTIFICATIONGRANULARITY
Notification Phases | DBPROP_NOTIFICATIONPHASES
Objects Transacted | DBPROP_TRANSACTEDOBJECT
Others' Changes Visible | DBPROP_OTHERUPDATEDELETE
Others' Inserts Visible | DBPROP_OTHERINSERT
Own Changes Visible | DBPROP_OWNUPDATEDELETE
Own Inserts Visible | DBPROP_OWNINSERT
Preserve on Abort | DBPROP_ABORTPRESERVE
Preserve on Commit | DBPROP_COMMITPRESERVE
Quick Restart | DBPROP_QUICKRESTART
Reentrant Events | DBPROP_REENTRANTEVENTS
Remove Deleted Rows | DBPROP_REMOVEDELETED
Report Multiple Changes | DBPROP_REPORTMULTIPLECHANGES
Return Pending Inserts | DBPROP_RETURNPENDINGINSERTS
Row Delete Notification | DBPROP_NOTIFYROWDELETE
Row First Change Notification | DBPROP_NOTIFYROWFIRSTCHANGE
Row Insert Notification | DBPROP_NOTIFYROWINSERT
Row Privileges | DBPROP_ROWRESTRICT
Row Resynchronization Notification | DBPROP_NOTIFYROWRESYNCH
Row Threading Model | DBPROP_ROWTHREADMODEL
Row Undo Change Notification | DBPROP_NOTIFYROWUNDOCHANGE
Row Undo Delete Notification | DBPROP_NOTIFYROWUNDODELETE
Row Undo Insert Notification | DBPROP_NOTIFYROWUNDOINSERT
Row Update Notification | DBPROP_NOTIFYROWUPDATE
Rowset Fetch Position Change Notification | DBPROP_NOTIFYROWSETFETCHPOSISIONCHANGE
Rowset Release Notification | DBPROP_NOTIFYROWSETRELEASE
Scroll Backwards | DBPROP_CANSCROLLBACKWARDS
Server Cursor | DBPROP_SERVERCURSOR
Skip Deleted Bookmarks | DBPROP_BOOKMARKSKIPPED
Strong Row Identity | DBPROP_STRONGITDENTITY
Unique Rows | DBPROP_UNIQUEROWS
Updatability | DBPROP_UPDATABILITY
Use Bookmarks | DBPROP_BOOKMARKS

Command 动态属性

下列属性被添加到 Command 对象的 Properties 集合中。

ADO 属性名称 | OLE DB 属性名称
Access Order | DBPROP_ACCESSORDER
Base Path | SSPROP_STREAM_BASEPATH
Blocking Storage Objects | DBPROP_BLOCKINGSTORAGEOBJECTS
Bookmark Type | DBPROP_BOOKMARKTYPE
Bookmarkable | DBPROP_IROWSETLOCATE
Change Inserted Rows | DBPROP_CHANGEINSERTEDROWS
Column Privileges | DBPROP_COLUMNRESTRICT
Column Set Notification | DBPROP_NOTIFYCOLUMNSET
Content Type | SSPROP_STREAM_CONTENTTYPE
Cursor Auto Fetch | SSPROP_CURSORAUTOFETCH
Defer Column | DBPROP_DEFERRED
Defer Prepare | SSPROP_DEFERPREPARE
Delay Storage Object Updates | DBPROP_DELAYSTORAGEOBJECTS
Fetch Backwards | DBPROP_CANFETCHBACKWARDS
Hold Rows | DBPROP_CANHOLDROWS
IAccessor | DBPROP_IAccessor
IColumnsInfo | DBPROP_IColumnsInfo
IColumnsRowset | DBPROP_IColumnsRowset
IConnectionPointContainer | DBPROP_IConnectionPointContainer
IConvertType | DBPROP_IConvertType
Immobile Rows | DBPROP_IMMOBILEROWS
IRowset | DBPROP_IRowset
IRowsetChange | DBPROP_IRowsetChange
IRowsetIdentity | DBPROP_IRowsetIdentity
IRowsetInfo | DBPROP_IRowsetInfo
IRowsetLocate | DBPROP_IRowsetLocate
IRowsetResynch | DBPROP_IRowsetResynch
IRowsetScroll | DBPROP_IRowsetScroll
IRowsetUpdate | DBPROP_IRowsetUpdate
ISequentialStream | DBPROP_ISequentialStream
ISupportErrorInfo | DBPROP_ISupportErrorInfo
Literal Bookmarks | DBPROP_LITERALBOOKMARKS
Literal Row Identity | DBPROP_LITERALIDENTITY
Lock Mode | DBPROP_LOCKMODE
Maximum Open Rows | DBPROP_MAXOPENROWS
Maximum Pending Rows | DBPROP_MAXPENDINGROWS
Maximum Rows | DBPROP_MAXROWS
Notification Granularity | DBPROP_NOTIFICATIONGRANULARITY
Notification Phases | DBPROP_NOTIFICATIONPHASES
Objects Transacted | DBPROP_TRANSACTEDOBJECT
Others' Changes Visible | DBPROP_OTHERUPDATEDELETE
Others' Inserts Visible | DBPROP_OTHERINSERT
Output Encoding Property | DBPROP_OUTPUTENCODING
Output Stream Property | DBPROP_OUTPUTSTREAM
Own Changes Visible | DBPROP_OWNUPDATEDELETE
Own Inserts Visible | DBPROP_OWNINSERT
Preserve on Abort | DBPROP_ABORTPRESERVE
Preserve on Commit | DBPROP_COMMITPRESERVE
Quick Restart | DBPROP_QUICKRESTART
Reentrant Events | DBPROP_REENTRANTEVENTS
Remove Deleted Rows | DBPROP_REMOVEDELETED
Report Multiple Changes | DBPROP_REPORTMULTIPLECHANGES
Return Pending Inserts | DBPROP_RETURNPENDINGINSERTS
Row Delete Notification | DBPROP_NOTIFYROWDELETE
Row First Change Notification | DBPROP_NOTIFYROWFIRSTCHANGE
Row Insert Notification | DBPROP_NOTIFYROWINSERT
Row Privileges | DBPROP_ROWRESTRICT
Row Resynchronization Notification | DBPROP_NOTIFYROWRESYNCH
Row Threading Model | DBPROP_ROWTHREADMODEL
Row Undo Change Notification | DBPROP_NOTIFYROWUNDOCHANGE
Row Undo Delete Notification | DBPROP_NOTIFYROWUNDODELETE
Row Undo Insert Notification | DBPROP_NOTIFYROWUNDOINSERT
Row Update Notification | DBPROP_NOTIFYROWUPDATE
Rowset Fetch Position Change Notification | DBPROP_NOTIFYROWSETFETCHPOSITIONCHANGE
Rowset Release Notification | DBPROP_NOTIFYROWSETRELEASE
Scroll Backwards | DBPROP_CANSCROLLBACKWARDS
Server Cursor | DBPROP_SERVERCURSOR
Server Data on Insert | DBPROP_SERVERDATAONINSERT
Skip Deleted Bookmarks | DBPROP_BOOKMARKSKIP
Strong Row Identity | DBPROP_STRONGIDENTITY
Updatability | DBPROP_UPDATABILITY
Use Bookmarks | DBPROP_BOOKMARKS
XML Root | SSPROP_STREAM_XMLROOT
XSL | SSPROP_STREAM_XSL

有关 Microsoft SQL Server OLE DB Provider 的实现和功能的详细信息，请参阅 MDAC SDK“OLE DB”一节中的 OLE DB Provider for SQL Server 文档。

请参阅

ConnectionString 属性 | Provider 属性 | Recordset 对象

© 1998-2002 Microsoft Corporation。保留所有权利。


Microsoft OLE DB Provider for Oracle

Microsoft OLE DB Provider for Oracle 允许 ADO 访问 Oracle 数据库。

连接字符串参数

要连接此提供者，请将 ConnectionString 属性的 Provider 参数设置为：

MSDAORA

读取 Provider 属性也将返回此字符串。

如果在 Oracle 数据库中使用键集或动态游标执行联接查询，将发生错误。Oracle 仅支持静态只读游标。

典型连接字符串

此提供者的典型连接字符串是：

"Provider=MSDAORA;Data Source=serverName;User ID=userName; Password=userPassword;"

该字符串包含下列关键字：

关键字 | 说明
Provider | 指定 OLE DB Provider for Oracle。
Data Source | 指定服务器的名称。
User ID | 指定用户名称。
Password | 指定用户密码。

提供者特有的连接参数

除了由 ADO 定义的连接参数以外，该提供者还支持几种提供者特有的连接参数。与 ADO 连接属性相同，这些提供者特有的属性可以通过 Connection 的 Properties 集合或作为 ConnectionString 的一部分进行设置。

这些参数在 OLE DB Programmer's Reference 中有完整的描述。（ADO 动态属性索引提供了这些参数名和相应的 OLE DB 属性之间的交叉引用。）

参数 | 说明
Window Handle | 指示用于提示详细信息的窗口句柄。
Locale Identifier | 指示唯一的 32 位数字（例如，1033），该数字指定与用户语言相关的首选项。这些首选项指示格式化日期和时间的方式、按字母顺序排列项目的方式、比较字符串的方式等等。
OLE DB Services | 指示把 OLE DB 服务指定为启用或禁用的位掩码。
Prompt | 指示在建立连接后是否提示用户。
Extended Properties | 字符串，包含提供者特有的、扩展的连接信息。此属性仅用于不能通过属性机制描述的提供者特有的连接信息。

请参阅

ConnectionString 属性 | Provider 属性 | Recordset 对象

MDAC SDK 文档“OLE DB”一节中的“OLE DB Provider for Oracle”


Microsoft OLE DB Provider for Internet Publishing

Microsoft OLE DB Provider for Internet Publishing 允许 ADO 访问由 Microsoft FrontPage 或 Microsoft Internet Information Server 提供的资源。这些资源包括 Web 源文件（例如 HTML 文件）或 Windows 2000 Web 文件夹。

连接字符串参数

要连接此提供者，请将 ConnectionString 属性的 Provider 参数设置为：

MSDAIPP.DSO

也可以使用 Provider 属性设置或读取此值。

典型连接字符串

此提供者的典型连接字符串是：

"Provider=MSDAIPP.DSO;Data Source=ResourceURL;User ID=userName;Password=userPassword;"

-或-

"URL=ResourceURL;User ID=userName;Password=userPassword;"

该字符串包含下列关键字：

关键字 | 说明
Provider | 指定 OLE DB Provider for Internet Publishing。
Data Source -或- URL | 指定在 Web Folder 中发布的文件或目录的 URL。
User ID | 指定用户名称。
Password | 指定用户密码。

如果将来自连接字符串的“URL=”的 ResourceURL 值设置为一个无效值，那么默认情况下，Internet Publishing Provider 将显示一个对话框提示输入有效值。应用程序中间层中的组件不应发生这种情况，因为这会使程序的执行挂起直到清除对话框为止，并且由于客户端未从组件接收到响应，因此它似乎被冻结了。

注意 如果 MSDAIPP.DSO 被显式指定为提供者的值（使用 Provider 连接字符串关键字或 Provider 属性），您将不能在连接字符串中使用“URL=”。否则，将会出现错误。相反，可以简单地指定 URL，如在主题将 ADO 与 OLE DB Provider for Internet Publishing 配合使用中所示。

请参阅

Internet 发布方案 | 将 ADO 与 OLE DB Provider for Internet Publishing 配合使用


Microsoft Data Shaping Service for OLE DB (ADO Service Provider)

ADO 2.5 附录

Microsoft Data Shaping Service for OLE DB

Microsoft Data Shaping Service for OLE DB 服务提供者支持数据提供者的分级（成形）Recordset 对象结构。

Provider 关键字

要调用 Data Shaping Service for OLE DB，请在连接字符串中指定下列关键字和值。

"Provider=MSDataShape"

动态属性

当调用此服务提供者时，下列动态属性将被添加到 Connection 对象的 Properties 集合中。

动态属性名称 | 说明
Unique Reshape Names | 指示是否允许重复 Recordset 对象的 Reshape Name 属性值。如果此动态属性为 True，并且生成的新的 Recordset 与现有的 Recordset 具有相同的用户指定的重构形名称，则新的 Recordset 对象的重构形名称将被修改以保持唯一性。如果此属性为 False，并且生成的新的 Recordset 与现有的 Recordset 具有相同的用户指定的重构形名称，则两个 Recordset 对象将具有相同的重构形名称。因此，只要两个记录集都存在，那么两个 Recordset 都不能被重新构形。 此属性的默认值为 False。
Data Provider | 指示提供者的名称，该提供者将提供要构形的行。如果不打算使用提供者来提供行，则此值可以为 NONE。

也可以通过在连接字符串中将可写的动态属性的名称指定为关键字来设置这些可写动态属性。例如，在 Microsoft Visual Basic 中，可按下面的格式将 Data Provider 动态属性设置为“MSDASQL”：

Dim cn as New ADODB.Connection
cn.Open "Provider=MSDataShape;Data Provider=MSDASQL"

也可以通过将动态属性的名称指定为 Properties 属性的索引来设置或检索动态属性。例如，获取和打印 Data Provider 动态属性的当前值，然后设置新值，如下所示：

Debug.Print cn.Properties("Data Provider")
cn.Properties("Data Provider") = "MSDASQL"

有关数据构形的详细信息，请参阅数据构形。

请参阅

MDAC SDK 文档“OLE DB”一节中的“Data Shaping Service for OLE DB”


Microsoft OLE DB Persistence Provider (ADO Service Provider)

ADO 2.5 附录

Microsoft OLE DB Persistence Provider

Microsoft OLE DB Persistence Provider 允许将 Recordset 对象保存到文件中，并随后从文件中恢复该 Recordset 对象。模式信息、数据和挂起更改被保留下来。

既可以用专有的 Advanced Data Table Gram (ADTG) 格式保存 Recordset，也可以用开放的可扩展标记语言 (XML) 格式保存。

Provider 关键字

要调用此提供者，请在连接字符串中指定下列关键字和值。

"Provider=MSPersist"

错误

在应用程序中可检测到由此提供者产生的下列错误。

常量 | 说明
E_BADSTREAM | 打开的文件不具备有效格式（即，格式不是 ADTG 或 XML）。
E_CANTPERSISTROWSET | 保存的 Recordset 对象具有禁止保存的特性。

说明

Microsoft OLE DB Persistence Provider 不显露动态属性。

目前，只有参数化分级 Recordset 对象不能保存。

有关持久存储 Recordset 对象的详细信息，请参阅 Recordset 持久性。

使用流打开 Recordset 时，除指定 Open 方法的 Source 参数之外，不指定其他任何参数。

请参阅

MDAC SDK 文档“OLE DB”一节中的“OLE DB Persistence Provider”


Microsoft OLE DB Remoting Provider (ADO Service Provider)

ADO 2.5 附录

Microsoft OLE DB Remoting Provider

Microsoft OLE DB Remoting Provider 允许客户端计算机上的本地用户调用远程计算机上的数据提供者。象远程计算机上的本地用户一样指定远程计算机的数据提供者参数，然后指定 Remoting Provider 用来访问远程计算机的参数。最终结果是，您可以象本地用户一样访问远程计算机。

Provider 关键字

要调用 OLE DB Remoting Provider，请在连接字符串中指定下列关键字和值。（请注意提供者名称中的空格。）

"Provider=MS Remote"

其他关键字

当调用此服务提供者时，将涉及其他关键字，如下所示。

关键字 | 说明
Data Source | 指定远程数据源的名称。该远程数据源将被传递到 OLE DB Remoting Provider 进行处理。 此关键字等价于 RDS.DataControl 对象的 Connect 属性。

动态属性

当调用此服务提供者时，下列动态属性将被添加到 Connection 对象的 Properties 集合中。

动态属性名称 | 说明
DFMode 指示 DataFactory Mode。指定服务器上所需的 DataFactory 对象版本的字符串。请在打开连接以请求特定版本的 DataFactory 之前设置此属性。如果不能使用请求的版本，将尝试使用以前的版本。如果没有以前的版本，则将出现错误。如果 DFMode 低于可用版本，将出现错误。连接后此属性为只读。

可以是下列有效字符串值之一：

  • "25" — 版本 2.5（默认值）
  • "21" — 版本 2.1
  • "20" — 版本 2.0
  • "15" — 版本 1.5
Command Properties | 指示将要向 MS Remote Provider 发送到服务器的 command (rowset) 属性的字符串添加的值。此字符串的默认值为 vt_empty。
Current DFMode 指示服务器上 DataFactory 的实际版本号。检查此属性以查看是否可以得到 DFMode 属性中请求的版本。

可以是下列有效 Long 整数值之一：

  • 25 — 版本 2.5（默认值）
  • 21 — 版本 2.1
  • 20 — 版本 2.0
  • 15 — 版本 1.5

在使用 MSRemote 提供者时向连接字符串中添加“DFMode=20;”可以提高服务器更新数据的性能。通过这项设置，服务器上的 RDSServer.DataFactory 对象将使用较低的资源集中模式。但是，下列功能在此配置中无效。

  • 使用参数化查询。
  • 调用 Execute 方法前获得参数或列信息。
  • 将 Transact Updates 设置为 True。
  • 获得行状态。
  • 调用 Resync 方法。
  • 通过 Update Resync 属性刷新（显式或自动）。
  • 设置 Command 或 Recordset 属性。
  • 使用 adCmdTableDirect。
Handler | 指示服务器端用于扩展 RDSServer.DataFactory 功能的服务器端自定义程序（即处理程序）的名称，以及处理程序所使用的任意参数，各项之间用逗号分隔 (",")。String 值。
Internet Timeout | 指示请求在服务器上来回传输所等候的最大毫秒数。（默认值为五分钟。）
Remote Provider | 指示用于远程服务器的数据提供者的名称。
Remote Server | 指示用于此连接的服务器名称和通讯协议。此属性等价于 RDS.DataControl 对象的 Server 属性。
Transact Updates | 如果设置为 True，此值指示在服务器上执行 UpdateBatch 时，将在事务内部执行。此 Boolean 动态属性的默认值为 False。

也可以通过在连接字符串中将可写的动态属性的名称指定为关键字来设置这些可写动态属性。例如，按下面的格式将 Internet Timeout 动态属性设置为五秒。

Dim cn as New ADODB.Connection
cn.Open "Provider=MS Remote;Internet Timeout=5000"

也可以通过将动态属性的名称指定为 Properties 属性的索引来设置或检索该动态属性。例如，获得和打印 Internet Timeout 动态属性的当前值，然后设置新值，如下所示：

Debug.Print cn.Properties("Internet Timeout")
cn.Properties("Internet Timeout") = 5000

说明

在 ADO 2.0 中，只能在 Recordset 对象 Open 方法的 ActiveConnection 参数中指定 OLE DB Remoting Provider。从 ADO 2.1 开始，也可以在 Connection 对象 Open 方法的 ConnectionString 参数中指定此提供者。

RDS.DataControl 对象 SQL 属性没有等价项。而由 Recordset 对象 Open 方法的 Source 参数代替。

指定“...;Remote Provider=MS Remote;...”将创建一个四层方案。超过三层的方案尚未经过测试，并且应该没有必要。

范例

这个范例在名为 YourServer 的服务器上查询 pubs 数据库的 authors 表。在 Connection 对象 Open 方法中提供远程数据源和远程服务器的名称，在 Recordset 对象 Open 方法中指定 SQL 查询。Recordset 对象将被返回、编辑并用于更新数据源。

Dim rs as New ADODB.Recordset
Dim cn as New ADODB.Connection
cn.Open  "Provider=MS Remote;Data Source=pubs;" & _
         "Remote Server=http://YourServer"
rs.Open "SELECT * FROM authors", cn
...                'Edit the recordset
rs.UpdateBatch     'Equivalent of RDS SubmitChanges
...

请参阅

MDAC SDK 文档“OLE DB”一节中的“OLE DB Remoting Provider”


Microsoft Cursor Service for OLE DB (ADO Service Component)

ADO 2.5 附录

Microsoft Cursor Service for OLE DB

Microsoft Cursor Service for OLE DB 补充了数据提供者的游标支持功能。因此，用户可以从所有数据提供者处获得相对统一的功能。

Cursor Service 使动态属性可用，并且增强了某些方法的功能。例如，Optimize 动态属性允许创建临时索引以简化某些操作，如 Find 方法。

Cursor Service 允许支持各种情况的批更新。当数据提供者只能提供功能较少的游标（如静态游标）时，批更新可以模拟功能较多的游标类型（如动态游标）。

关键字

要调用此服务组件，请将 Recordset 或 Connection 对象的 CursorLocation 属性设置为 adUseClient。

connection.CursorLocation=adUseClient
recordset.CursorLocation=adUseClient

动态属性

当调用 Cursor Service for OLE DB 时，下列动态属性将被添加到 Recordset 对象的 Properties 集合中。ADO 动态属性索引中列出了 Connection 和 Recordset 对象动态属性的完整列表。相关的 OLE DB 属性名称包括在相应的 ADO 属性名称后面的括号内。

调用 Cursor Service 后，对于基本数据源来说，对某些动态属性的更改是不可见的。例如，在 Recordset 上设置 Command Time out 属性对于基本数据提供者来说将是不可见的。

...
Recordset1.CursorLocation = adUseClient     'invokes cursor service
Recordset1.Open "authors", _
    "Provider=SQLOLEDB;Data Source=DBServer;User Id=usr;" & _
    "Password=pwd;Initial Catalog=pubs;",,adCmdTable
Recordset1.Properties.Item("Command Time out") = 50
' 'Command Time out' property on DBServer is still default (30).
...

如果应用程序需要 Cursor Service，但是又需要在基本数据提供者上设置动态属性，请在调用 Cursor Service 之前设置此属性。无论游标位置如何，命令对象属性设置将始终被传递给基本数据提供者。因此可以随时使用命令对象来设置属性。

注意 即使基本数据提供者支持动态属性 DBPROP_SERVERDATAONINSERT，游标服务也不支持该属性。
属性名称 | 说明
Auto Recalc (DBPROP_ADC_AUTORECALC) | 对于用 Data Shaping Service 创建的记录集，此值指示计算列和合计列的计算频率。只要 Data Shaping Service 确定值发生更改，默认值（值 =1）便将被重新计算。如果值为 0，当分级结构被初始化编译时，将只计算计算列或合计列。
Batch Size (DBPROP_ADC_BATCHSIZE) | 指示在传送到数据存储之前可以成批处理的更新语句数目。批中包含的语句越多，数据存储的循环次数就越少。
Cache Child Rows (DBPROP_ADC_CACHECHILDROWS) | 对于由 Data Shaping Service 创建的记录集，此值指示子记录集是否存储在缓存中以便将来使用。
Cursor Engine Version (DBPROP_ADC_CEVER) | 指示所使用的 Cursor Service 的版本。
Maintain Change Status (DBPROP_ADC_MAINTAINCHANGESTATUS) | 指示用于将多表联接中的一行或多行重新同步的命令文本。
Optimize | 指示是否应该创建索引。当设置为 True 时，允许临时创建索引，以便改善某些操作的执行。
Reshape Name | 指示 Recordset 的名称。可能在当前或后续的数据构形命令中被引用。
Resync Command | 指定当 Unique Table 属性生效时 Resync 方法所使用的自定义命令字符串。
Unique Catalog | 指示数据库的名称，该数据库包含 Unique Table 属性中引用的表。
Unique Schema | 指示 Unique Table 属性中引用的表的所有者的名称。
Unique Table | 指示 Recordset 中的一个表的名称，该 Recordset 由多个可以通过插入、更新或删除进行修改的表创建而成。
Update Criteria (DBPROP_ADC_UPDATECRITERIA) | 指示 WHERE 子句中用于处理更新过程中产生的冲突的字段。
Update Resync (DBPROP_ADC_UPDATERESYNC) | 指示当 Unique Table 属性生效时，是否在 UpdateBatch 方法（及其行为）后隐式调用 Resync 方法。

也可以通过将动态属性的名称指定为 Properties 集合的索引来设置或检索该动态属性。例如，获得和打印 Optimize 动态属性的当前值，然后设置新值，如下所示：

Debug.Print rs.Properties("Optimize")
rs.Properties("Optimize") = True

内置属性行为

Cursor Service for OLE DB 也影响某些内置属性的行为。

属性名称 | 说明
CursorType | 补充 Recordset 可用的游标类型。
LockType | 补充 Recordset 可用的锁定类型。启用批更新。
Sort | 指定 Recordset 用作排序依据的一个或多个字段名称，并指定每个字段是按升序还是按降序排序。

方法行为

Cursor Service for OLE DB 启用或影响 Field 对象的 Append 方法的行为，以及 Recordset 对象的 Open、Resync、UpdateBatch 和 Save 方法的行为。

请参阅

MDAC SDK 文档“OLE DB”一节中的“Cursor Service for OLE DB”


附录 B：ADO 错误

有关特定错误消息的详细信息，请参阅下面的主题：

  • ADO 错误代码
  • DataControl 错误代码
  • Internet Explorer 错误代码
  • Internet Information Services 错误代码

请参阅

ADO API 参考 | ADO 集合 | ADO 动态属性 | ADO 枚举常量 | ADO 事件 | ADO 方法 | ADO 对象模型 | ADO 对象 | ADO 属性


ADO 错误代码

除了在 Errors 集合的 Error 对象中返回的提供者错误外，ADO 自身也可以向运行时环境的例外处理机制返回错误。使用编程语言的错误捕获机制（如 Microsoft Visual Basic 中的 On Error 语句，或者 Microsoft Visual C++ 或 Microsoft Visual J++ 中的 try-catch 块），可以捕获 ADO 错误。

有关 ADO 错误代码的列表，请参阅 ErrorValueEnum。

请参阅

Error 对象 | Errors 集合


DataControl 错误代码

下表列出 RDS.DataControl 对象的错误代码。显示两个低位字节的正十进制转换、完整错误代码的负十进制转换和十六进制值。

RDS.DataControl 错误代码 | 编号 | 说明
IDS_AsyncPending | 4107 -2146824175 0x800A1011 | 不能在异步操作进行期间执行操作。
IDS_BadInlineTablegram | 4105 -2146824183 0x800A1009 | 不正确的 Inline Tablegram。
IDS_CantConnect | 4099 -2146824189 0x800A1003 | 无法连接到服务器。
IDS_CantCreateObject | 4100 -2146824188 0x800A1004 | 无法创建业务对象。
IDS_CantFindDataspace | 4102 -2146824186 0x800A1006 | 数据空间属性无效。
IDS_CantInvokeMethod | 4101 -2146824187 0x800A1005 | 无法启动业务对象上的方法。
IDS_CrossDomainWarning | 4112 -2146824170 0x800A1016 | 此页正在访问其它域的数据。您允许这样做吗？为了避免此信息出现在 Internet Exporer 中，请从“Internet 选项”对话框的“安全”选项卡中添加“信任站点”区的 Web 站点。
IDS_InvalidADCClientVersion | 4106 -2146824176 0x800A1010 | RDS 客户端版本无效 — 客户端比服务器端新。
IDS_INVALIDARG | 5376 -2147019520 0x80071500 | 一个或多个参数无效。
IDS_InvalidBindings | 4097 -2146824191 0x800A1001 | 绑定属性错误。
IDS_InvalidParam | 4110 -2146824172 0x800A1014 | 一个或多个参数无效。
IDS_NOINTERFACE | 5377 -2147019519 0x80071501 | 不被支持的接口。
IDS_NotReentrant | 4111 -2146824171 0x800A1015 | 当事件处理程序仍在运行时，请求无法被执行。
IDS_ObjectNotSafe | 4103 -2146824185 0x800A1007 | 本机安全设置禁止创建业务对象。
IDS_RecordsetNotOpen | 4109 -2146824173 0x800A1013 | Recordset 未被打开。
IDS_ResetInvalidField | 4108 -2146824174 0x800A1012 | SortColumn 或 FilterColumn 中所指定的列不存在。
IDS_RowsetNotUpdateable | 4104 -2146824184 0x800A1008 | 行集合不能更新。
IDS_UnexpectedError | 4351 -2146823937 0x800A10FF | 意外错误。
IDS_UpdatesFailed | 4098 -2146824190 0x800A1002 | 不能更新数据库。
IDS_URLMONNotFound | 4119 -2146824169 0x800A1017 | 无法找到 DataControl URL 属性需要的系统文件 Urlmon.dll。

请参阅

DataControl 对象 (RDS)


Internet Explorer 错误代码

下表列出与使用远程数据服务相关的 Microsoft Internet Explorer 错误代码。显示两个低位字节的正十进制转换、完整错误代码的负十进制转换和十六进制值。

Internet Explorer (Wininet) 错误 | 编号 | 说明
IDS_WinInet_CantConnect | 8195 -2146820093 0x800A2003 | Internet 客户端错误：不能连接服务器。
IDS_WinInet_ ConnectionReset | 12031 -2146816257 0x800A2EFF | Internet 客户端错误：连接复位。
IDS_WinInet_Error | 8193 -2146820095 0x800A2001 | Internet 客户端错误。
IDS_WinInet_ InvalidServerResponse | 8430 -2146819858 0x800A20EE | Internet 客户端错误：无效的服务器应答。
IDS_WinInet_ SSLPostLimitation | 8196 -2146820092 0x800A2004 | Internet 客户端错误：SSL 错误（可能 32K 数据加载受限）。
IDS_WinInet_Timeout | 8194 -2146820094 0x800A2002 | Internet 客户端错误：请求超时。


Internet Information Services 错误代码

下表列出与使用远程数据服务相关的 Microsoft Internet Information Services (IIS) 错误代码。显示两个低位字节的正十进制转换、完整错误代码的负十进制转换和十六进制值。

Internet Information Services 错误 | 编号 | 说明
IDS_IIS_AccessDenied | 8208 -2146820080 0x800A2010 | Internet 服务器错误：访问被拒绝。
IDS_IIS_ObjectNotFound | 8209 -2146820079 0x800A2011 | Internet 服务器错误：找不到对象或模块。
IDS_IIS_RequestForbidden | 8210 -2146820078 0x800A2012 | Internet 服务器错误：禁止请求。
IDS_IIS_UnexpectedError | 8447 -2146819841 0x800A20FF | Internet 服务器错误。


附录 C：ADO 编程

ADO 是一个 COM 自动接口组件，它可以同多种编程语言结合使用。这些语言包括 Microsoft Visual Basic、VBScript、JScript、Visual C++ 和 Visual J++。ADO 版本与上述各种工具和其他应用程序（例如 Microsoft Office 和 Microsoft SQL Server）一起安装。ADO 的最新版本可以单独配合 Microsoft Data Access Components 使用。有关详细信息，请参阅 Microsoft Data Access 网站。

ADO 库为 msado15.dll，程序 ID (ProgID) 前缀为“ADODB”。例如，要显式地引用 ADO Recordset，请使用 ADODB.Recordset。

有关在各种开发环境中用 ADO 编程的详细信息，请参阅下列主题：

  • 通过 Microsoft Visual Basic 使用 ADO
  • 通过脚本语言使用 ADO
  • 通过 Microsoft Visual C++ 使用 ADO
  • 通过 Microsoft Visual J++ 使用 ADO

请参阅

ADO API 参考 | ADO 范例 | 配置 RDS | ActiveX Data Objects 开始页 | 附录 A：提供者 | ADO 的新增内容


通过 Microsoft Visual Basic 使用 ADO

设置 ADO 工程和编写 ADO 代码与用 Visual Basic 或 Visual Basic for Applications 非常相似。本主题既阐述通过 Visual Basic 使用 ADO，也阐述通过 Visual Basic for Applications 使用 ADO，并注明其区别。

引用 ADO 库

您的工程必须引用 ADO 库。

从 Microsoft Visual Basic 引用 ADO 的步骤：

  1. 在 Visual Basic 中，从“工程”菜单中选择“引用”。
  2. 从列表中选择“Microsoft ActiveX Data Objects x.x Library”。请验证至少还选择了下列库：
    • Visual Basic for Applications
    • Visual Basic runtime objects and procedures
    • Visual Basic objects and procedures
    • OLE Automation
  3. 单击“确定”。

在 Visual Basic for Applications 中使用 ADO 同样简单，下面以 Microsoft Access 为例。

从 Microsoft Access 中引用 ADO 的步骤：

  1. 在 Microsoft Access 中，从“数据库”窗口的“模块”选项卡中选择或创建一个模块。
  2. 从“工具”菜单中选择“引用”。
  3. 从列表中选择“Microsoft ActiveX Data Objects x.x Library”。请验证至少还选择了下列库：
    • Visual Basic for Applications
    • Microsoft Access 11.0 Object Library（或更新版本）
  4. 单击“确定”。

在 Visual Basic 中创建 ADO 对象

若要创建一个自动变量和该变量的一个对象实例，可以使用两种方法：Dim 或 CreateObject。

Dim

在 Dim 中使用 New 关键字，可以只用一步就完成 ADO 对象的声明和实例化：

Dim conn As New ADODB.Connection

或者，也可用两步来完成 Dim 语句声明和对象实例化：

Dim conn As ADODB.Connection
Set conn = New ADODB.Connection
注意 如果在工程中引用了适当的 ADO 库，则不必在 Dim 语句中显式使用 ADODB progid。但使用它可以保证避免与其他库发生命名冲突。
例如，如果您在同一个工程中既引用 ADO 又引用 DAO，则应包含一个限定符指定实例化 Recordset 对象时要使用的对象模型，如下列代码所示：
Dim adoRS As ADODB.Recordset
Dim daoRS As DAO.Recordset

CreateObject

如果使用 CreateObject 方法，则声明和对象实例化必须通过两个单独的步骤来完成：

Dim conn1
Set conn1 = CreateObject("ADODB.Connection") As Object

用 CreateObject 实例化的对象是后绑定的，这表明它们不是健壮的类型，并且不能通过命令行完成。但是，它允许跳过在工程中引用 ADO 库这一步骤，并可以对特定版本的对象进行实例化。例如：

Set conn1 = CreateObject("ADODB.Connection.2.0") As Object

您也可以通过专门创建对 ADO 2.0 版类型库的引用和创建对象来完成此任务。

通常用 CreateObject 方法实例化对象要比用 Dim 语句慢。

处理事件

为了在 Microsoft Visual Basic 中处理 ADO 事件，必须使用 WithEvents 关键字声明模块级变量。变量可以只声明为类模块的一部分，并且必须在模块级进行声明。有关处理 ADO 事件的更详细的论述，请参阅第 7 章：处理 ADO 事件。

Visual Basic 范例

ADO 文档中包含了许多 Visual Basic 范例。有关详细信息，请参阅 Microsoft Visual Basic 中的 ADO 代码范例。

请参阅

ActiveX Data Objects 开始页 | 通过 Microsoft Visual C++ 使用 ADO | 通过 Microsoft Visual J++ 使用 ADO | 通过脚本语言使用 ADO

© 1998-2002 Microsoft Corporation。保留所有权利。


通过脚本语言使用 ADO

在脚本环境中，ADO 允许以服务器端脚本方式显露数据。在此方案中，ADO（脚本语言所使用的基本 OLE DB 提供者）和引用给定数据存储所需的所有其他组件都安装在运行 Internet Information Services (IIS) 的服务器上。在使用 Active Server Pages (ASP) 时，ADO 是可以生成如 HTML 语言的脚本所引用的一个组件。HTML 的内容可以通过 HTTP 传递到客户端 Web 浏览器。通过使用脚本，Web 页可以将操作发送回服务器端脚本，从而允许您更新、移动或查看特定数据。

ODBC 数据源

如果使用了 ODBC 数据源，那么它将是脚本 ADO 代码与非脚本 ADO 代码之间的一个明显区别。对于非脚本应用程序，您可以在“ODBC 数据源管理器”中创建一个“用户 DSN”。对于在 IIS 环境下运行的脚本，必须创建一个“系统 DSN”，否则脚本将无法识别您创建的数据源。这适用于所有通过 Microsoft IIS 使用 Microsoft OLE DB Provider for ODBC 的 ADO 脚本应用程序。

引用 ADO 库

带有脚本语言的 N/A。

处理事件

带有脚本语言的 N/A。

下列主题包含有关通过脚本语言使用 ADO 的其他特定信息：

  • 在 VBScript 中使用 ADO
  • 在 JScript 中使用 ADO

请参阅

ActiveX Data Objects 开始页 | 通过 Microsoft Visual Basic 使用 ADO | 通过 Microsoft Visual C++ 使用 ADO | 通过 Microsoft Visual J++ 使用 ADO


VBScript ADO 编程

创建 ADO 工程

Microsoft Visual Basic Scripting Edition 不支持类型库，因此不必在工程中引用 ADO。也因而不支持相关联的功能，例如通过命令行完成。默认情况下，ADO 枚举常量也不在 VBScript 中定义。

但是，ADO 可向您提供两个包含文件，它们包含下列将在 VBScript 中使用的定义：

  • 对服务器端脚本使用 Adovbs.inc。默认情况下，它安装在 c:\Program Files\Common Files\System\ado\ 文件夹中。
  • 对客户端脚本使用 Adcvbs.inc。默认情况下，它安装在 c:\Program Files\Common Files\System\msdac\ 文件夹中。

您可以从这些文件中复制常量定义并将它们粘贴到 ASP 页上；如果您正在编写服务器端脚本，也可将 Adovbs.inc 文件复制到您的 Web 站点的文件夹中，然后再从 ASP 页上引用，如下所示：

<!--#include File="adovbs.inc"-->

在 VBScript 中创建 ADO 对象

不能用 Dim 语句将对象指定为 VBScript 中的特定类型。VBScript 也不支持与 Visual Basic for Applications 中的 Dim 语句一起使用的 New 语法。您必须使用 CreateObject 函数调用：

Dim Rs1
Set Rs1 = Server.CreateObject( "ADODB.Recordset" )

VBScript 范例

下列代码是在 Active Server Page (ASP) 文件中的 VBScript 服务器端编程的一个普通范例：

<%  @LANGUAGE="VBSCRIPT" %>
<%  Option Explicit %>
<!--#include File="adovbs.inc"-->
<HTML>
    <BODY BGCOLOR="White" topmargin="10" leftmargin="10">

    <!-- Your ASP Code goes here -->
<%
Dim Source
Dim Connect
Dim Rs1

Source = "SELECT * FROM Authors"
Connect = "Provider=sqloledb;Data Source=srv;" & _
    "Initial Catalog=Pubs;Integrated Security=SSPI;"

Set Rs1 = Server.CreateObject( "ADODB.Recordset" )
Rs1.Open Source, Connect, adOpenForwardOnly
Response.Write("Success!")
%>
    </BODY>
</HTML>

ADO 文档中包括更多特定的 VBScript 范例。有关详细信息，请参阅 Microsoft Visual Basic Scripting Edition 中的 ADO 代码范例。

VBScript 与 Visual Basic 的区别

通过 VBScript 使用 ADO 与通过 Visual Basic 使用 ADO 在许多方面都是相似的，包括使用的语法。但它们之间却存在着明显的区别：

  • VBScript 只支持 Variant 数据类型，该数据类型可保存各种不同类型的数据。您可将所需的数据存储为 Variant 数据类型，这些数据将通过 VBScript 执行以发挥相应的作用。它可以识别 ADO 所需的类型，并相应地转换 Variant 中的值。
  • 不能在 VBScript 中使用 on error goto <label>。
  • VBScript 支持某些内置 Visual Basic 函数，如 Msgbox、Date 和 IsNumeric。但由于 VBScript 是 Visual Basic 的一个子集，因此它并不支持所有内置函数。例如，VBScript 不支持 Format 函数和文件 I/O 函数。


JScript ADO 编程

创建 ADO 工程

Microsoft JScript 不支持类型库，因此不必在工程中引用 ADO。也因而不支持相关联的功能，例如通过命令行完成。默认情况下，ADO 枚举常量也不在 JScript 中定义。

但是，ADO 向您提供了两个包含文件，它们包含下列将在 JScript 中使用的定义：

  • 对服务器端脚本使用 Adojavas.inc。默认情况下，它安装在 c:\Program Files\Common Files\System\ado\ 文件夹中。
  • 对客户端脚本使用 Adcjavas.inc。默认情况下，它安装在 c:\Program Files\Common Files\System\msdac\ 文件夹中。

您可以从这些文件中复制常量定义并将它们粘贴到 ASP 页上；如果您正在编写服务器端脚本，也可将 Adojavas.inc 文件复制到您的 Web 站点的文件夹中，然后再从 ASP 页上引用，如下所示：

<!--#include File="adojavas.inc"-->

在 JScript 中创建 ADO 对象

您必须使用 CreateObject 函数调用：

var Rs1;
Rs1 = Server.CreateObject("ADODB.Recordset");

JScript 范例

下列代码是 JScript 服务器端编程的一个普通范例，在可打开 Recordset 对象的 Active Server Page (ASP) 文件中：

<%  @LANGUAGE="JScript" %>
<!--#include File="adojavas.inc"-->
<HTML>
<BODY BGCOLOR="White" topmargin="10" leftmargin="10">
<%
var Source = "SELECT * FROM Authors";
var Connect =  "Provider=sqloledb;Data Source=srv;" +
    "Initial Catalog=Pubs;Integrated Security=SSPI;"
var Rs1 = Server.CreateObject( "ADODB.Recordset.2.5" );
Rs1.Open(Source,Connect,adOpenForwardOnly);
Response.Write("Success!");
%>
</BODY>
</HTML>


通过 Microsoft Visual C++ 使用 ADO

有关通过 Visual C++ 使用 ADO 的详细信息，请参阅下列各节：

  • Visual C++ ADO 编程
  • Visual C++ Extensions for ADO
  • 用于 COM 的 ADO for Visual C++ 语法索引
  • 使用 #import 的 ADO for Visual C++ 语法索引

请参阅

ActiveX Data Objects 开始页 | 用于 COM 的 ADO for Visual C++ 语法索引 | 使用 #import 的 ADO for Visual C++ 语法索引 | 通过 Microsoft Visual Basic 使用 ADO | 通过 Microsoft Visual J++ 使用 ADO | 通过脚本语言使用 ADO | Visual C++ Extensions for ADO


Visual C++ ADO 编程

“ADO API 参考”使用与 Microsoft Visual Basic 类似的语法来描述 ADO 应用程序编程接口 (API) 的功能。尽管假定读者为所有用户，ADO 程序员仍采用多种语言，如 Visual Basic、Visual C++（带或不带 #import 伪指令）和 Visual J++（带 ADO/WFC 类软件包）。

为适应这种多样性，ADO for Visual C++ 语法索引提供了 Visual C++ 语言特有的语法，并且链接到“API 参考”中有关功能、参数、例外行为的常规说明。

ADO 通过 COM（组件对象模型）接口实现。但是，对于程序员来说，在 COM 中用某些编程语言编程比用其他语言更容易。例如，对于 Visual Basic 程序员，几乎所有使用 COM 的细节都可隐式处理，而 Visual C++ 程序员则必须自己处理这些细节。

下面各节为 C 和 C++ 程序员总结了使用 ADO 和 #import 伪指令的细则。它着重描述 COM 特有的数据类型（Variant、BSTR 和 SafeArray）及错误处理 (_com_error)。

使用 #import 编译器伪指令

#import Visual C++ 编译器伪指令简化了 ADO 方法和属性的使用。该伪指令接受包含类型库的文件名称，如 ADO .dll (Msado15.dll)，并生成包含 typedef 声明、接口智能指针和枚举常量的头文件。每个接口均封装在一个类中。

对于类中的每一操作（即方法或属性调用），都有一个直接调用操作的声明（即操作的“原始”形式），以及一个调用原始操作和在操作未能成功执行时放弃 COM 错误的声明。如果该操作是一个属性，通常会出现一个编译器伪指令，它为具有与 Visual Basic 类似语法的操作创建替换语法。

检索属性值的操作的名称形式为 Get Property。设置属性值的操作的名称形式为 Put Property。用指向 ADO 对象的指针来设置属性值的操作的名称形式为 PutRef Property。

可以通过这些形式的调用来获取或设置属性：

variable = objectPtr->GetProperty(); // get property value
objectPtr->PutProperty(value);       // set property value
objectPtr->PutRefProperty(&value);   // set property with object pointer

使用属性伪指令

__declspec(property...) 编译器伪指令是 Microsoft 特有的 C 语言扩展，它声明用作属性的函数具有替换语法。因此，可以用与 Visual Basic 相似的方式设置或获取属性的值。例如，可以通过下列方式设置和获取属性：

objectPtr->property = value;        // set property value
variable = objectPtr->property;     // get property value

注意，您不必编码：

objectPtr->PutProperty(value);      // set property value
variable = objectPtr->GetProperty;  // get property value

编译器将根据所声明的替换语法，并根据属性是被读取还是被写入来生成相应的 Get-、Put- 或 PutRef Property 调用。

__declspec(property...) 编译器伪指令只能声明函数的 get、put 或 get 和 put 的替换语法。只读操作只具有 get 声明；只写操作只具有 put 声明；可读写的操作则同时具有 get 和 put 声明。

此伪指令只可能有两个声明，但每个属性都可能具有三个属性函数：Get Property、Put Property 和 PutRef Property。在这种情况下，只有两种形式的属性具有替换语法。

例如，Command 对象的 ActiveConnection 属性就使用 Get ActiveConnection 和 PutRef ActiveConnection 的替换语法来声明。PutRef- 语法是不错的选择，因为实际上您通常都想将打开的 Connection 对象（即 Connection 对象指针）放入该属性。另一方面，虽然 Recordset 对象具有 Get-、Put- 和 PutRef ActiveConnection 操作，但它没有替换语法。

集合、GetItem 方法和 Item 属性

ADO 定义包括 Fields、Parameters、Properties 和 Errors 在内的若干集合。在 Visual C++ 中，GetItem(index) 方法返回集合的一个成员。Index 是一个 Variant，其值是集合中成员的数字索引，或者是包含成员名称的字符串。

__declspec(property...) 编译器伪指令将 Item 属性声明为每个集合的基本 GetItem() 方法的替换语法。替换语法使用方括号，看起来类似于数组引用。通常情况下，这两种形式如下所示：

collectionPtr->GetItem(index);
collectionPtr->Item[index];

例如，给名为 rs 的 Recordset 对象的字段分配一个值，该对象源自 pubs 数据库的 authors 表。用 Item() 属性访问 Recordset 对象 Fields 集合的第三个 Field（从零开始对集合进行索引，假定第三个字段名称为 au_fname）。然后调用 Field 对象的 Value() 方法来分配字符串值。

在 Visual Basic 中，可以用下列四种方式来表示（后两种形式为 Visual Basic 所独有，其他语言没有等价的形式）：

rs.Fields.Item(2).Value = "value"
rs.Fields.Item("au_fname").Value = "value"
rs(2) = "value"
rs!au_fname = "value"

在 Visual C++ 中，与上述前两种形式等价的形式为：

rs->Fields->GetItem(long(2))->PutValue("value");
rs->Fields->GetItem("au_fname")->PutValue("value");

-或-（还列出了 Value 属性的替换语法）

rs->Fields->Item[long(2)]->Value = "value";
rs->Fields->Item["au_fname"]->Value = "value";

COM 特有的数据类型

一般情况下，“ADO API 参考”中的所有 Visual Basic 数据类型都有等价的 Visual C++ 类型。包括标准数据类型，如对应于 Visual Basic Byte 的 unsigned char、对应于 Integer 的 short 和对应于 Long 的 Long。若要查看给定方法或属性的操作数所需的确切数据类型，请参阅“语法索引”。

下面 COM 特有的数据类型属于该规则的例外情况：Variant、BSTR 和 SafeArray。

Variant

Variant 是结构化的数据类型，它包含值成员和数据类型成员。Variant 可能包含许多其他的数据类型，如包括另一个 Variant、BSTR、Boolean、IDispatch 或 IUnknown 指针、货币、日期等等。COM 还提供便于将一种数据类型转换为另一数据类型的方法。

_variant_t 类封装和管理 Variant 数据类型。

如果“ADO API 参考”讲述某个方法或者属性操作数接受某个值，通常表明该值在 _variant_t 中传递。

如果“ADO API 参考”主题中的“参数”部分讲述操作数是 Variant，那么此规则显然是正确的。一个例外是文档明确讲述操作数接受标准数据类型（如 Long 或 Byte）或枚举。另一个例外是操作数接受 String。

BSTR

BSTR (Basic STRing) 是结构化数据类型，它包含字符串和字符串的长度。COM 提供分配、处理和释放 BSTR 的方法。

_bstr_t 类封装和管理 BSTR 数据类型。

如果“ADO API 参考”讲述某个方法或属性接受 String 值，表明该值的形式为 _bstr_t。

Casting _variant_t 和 _bstr_t 类

对于某个操作，通常不必在参数中对 _variant_t 或 _bstr_t 进行显式编码。如果 _variant_t 或 _bstr_t 类具有一个与参数的数据类型相匹配的构造函数，编译器将生成相应的 _variant_t 或 _bstr_t。

但如果参数不确定（即参数的数据类型与多个构造函数相匹配），那么必须给参数指定适当的数据类型以调用正确的构造函数。

例如，对 Recordset::Open 方法的声明为：

    HRESULT Open (
        const _variant_t & Source,
        const _variant_t & ActiveConnection,
        enum CursorTypeEnum CursorType,
        enum LockTypeEnum LockType,
        long Options );

ActiveConnection 参数引用 _variant_t，您可能会将其编码为连接字符串或指向打开的 Connection 对象的指针。

如果传递诸如“DSN=pubs;uid=sa;pwd=;”的字符串或诸如“(IDispatch *) pConn”的指针，将隐式构造正确的 _variant_t。

或者可以显式编码包含诸如“_variant_t((IDispatch *) pConn, true)”的指针的 _variant_t。(IDispatch *) 用另一个接受指向 IUnknown 接口的指针的构造函数来解决这种不确定的问题。

ADO 是一个 IDispatch 接口，这一点虽然很少提及，但却至关重要。只要将指向 ADO 对象的指针作为 Variant 传递，就必须将该指针指定为指向 IDispatch 接口的指针。

最后一种情况将通过其选项（默认值为 True）对构造函数的第二个布尔参数进行显式编码。此参数可使 Variant 构造函数调用其 AddRef() 方法，该方法对 ADO 方法或属性调用完毕时 ADO 自动调用 _variant_t::Release() 方法作了补偿。

SafeArray

SafeArray 是一种结构化数据类型，包含其他数据类型的数组。SafeArray 之所以称为“安全”，是因为它包含有关每个数组维的范围的信息，并且限制对这些范围内的数组元素进行访问。

如果“ADO API 参考”讲述某个方法或属性接受或返回一个数组，表明该方法或属性接受或返回 SafeArray，而不是原生的 C/C++ 数组。

例如，Connection 对象 OpenSchema 方法的第二个参数需要一个 Variant 值的数组。必须将这些 Variant 值作为 SafeArray 的元素传递，并且该 SafeArray 必须设置为另一个 Variant 的值。这另一个 Variant 是作为 OpenSchema 的第二个参数来传递的。

进一步举例，Find 方法的第一个参数是其值为一维 SafeArray 的 Variant；每一个 AddNew 的第一和第二个可选参数都是一维 SafeArray；GetRows 方法的返回值是其值为二维 SafeArray 的 Variant。

缺少和默认参数

Visual Basic 允许在方法中缺少参数。例如，Recordset 对象 Open 方法有五个参数，您可以忽略中间参数并放弃后续参数。根据缺少操作数的数据类型，将用默认的 BSTR 或 Variant 作替代。

在 C/C++ 中，必须指定所有操作数。如果要指定其数据类型为字符串的缺少参数，请指定一个包含 Null 字符串的 _bstr_t。如果要指定其数据类型为 Variant 的缺少参数，请指定一个值为 DISP_E_PARAMNOTFOUND 的 VT_ERROR 类型的 _variant_t。或者也可以指定等价的 _variant_t 常量 vtMissing，它由 #import 伪指令提供。

有三种方法属于 vtMissing 典型用法的例外情况。它们是 Connection 和 Command 对象的 Execute 方法，还有 Recordset 对象的 NextRecordset 方法。其特征如下：

_RecordsetPtr Execute( _bstr_t CommandText, VARIANT * RecordsAffected,
        long Options );  // Connection
_RecordsetPtr Execute( VARIANT * RecordsAffected, VARIANT * Parameters,
        long Options );  // Command
_RecordsetPtr NextRecordset( VARIANT * RecordsAffected );  // Recordset

参数 RecordsAffected 和 Parameters 是指向 Variant 的指针。Parameters 是一个输入参数，它指定 Variant 的地址，该 Variant 包含将修改正在执行的命令的单个参数或参数数组。RecordsAffected 是一个输出参数，它指定 Variant 的地址，受该方法影响的行数将返回到该 Variant。

在 Command 对象 Execute 方法中，通过将 Parameters 设置为 &vtMissing（建议使用这种方法）或设置为空指针（即 NULL 或 0）来指示未指定参数。如果将 Parameters 设置为空指针，该方法将内部替代等价的 vtMissing，然后完成操作。

在所有方法中，通过将 RecordsAffected 设置为空指针来指示不应返回受影响的记录数。在这种情况下，与其说空指针是缺少参数，不如说它指示该方法应放弃受影响的记录数。

因此，对于这三种方法，可有效编写如下内容：

pConnection->Execute("commandText", NULL, adCmdText);
pCommand->Execute(NULL, NULL, adCmdText);
pRecordset->NextRecordset(NULL);

错误处理

在 COM 中，许多操作均返回一个 HRESULT 返回代码，指示某个功能是否顺利完成。#import 伪指令针对每种“原始”方法或属性生成封装代码，并检查返回的 HRESULT。如果 HRESULT 指示失败，封装代码将通过把 HRESULT 返回代码作为参数来调用 _com_issue_errorex() 的方式放弃 COM 错误。可在 try-catch 块中捕获 COM 错误对象。（为提高效率，请引用 _com_error 对象。）

请记住下列 ADO 错误，这些错误源于 ADO 操作失败。由基本提供者返回的错误在 Connection 对象 Errors 集合中显示为 Error 对象。

#import 伪指令只创建在 ADO .dll 中声明过的属性和方法的错误处理例程。但是，通过写入您自己的错误检查宏或内联函数便可以利用此错误处理机制。有关范例，请参阅 Visual C++ Extensions 主题或下面各节中的代码。

Visual Basic 规则的 Visual C++ 等价内容

下面的内容是 ADO 文档中若干规则的汇总（用 Visual Basic 编码），以及这些规则在 Visual C++ 中的等价内容。

声明 ADO 对象

在 Visual Basic 中，对 ADO 对象变量（本例为 Recordset 对象）的声明如下：

Dim rst As ADODB.Recordset

“ADODB.Recordset”子句是在注册表中定义的 Recordset 对象的 ProgID。对 Record 对象的新实例的声明如下：

Dim rst As New ADODB.Recordset

-或-

Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset

在 Visual C++ 中，#import 伪指令为所有 ADO 对象生成智能指针类型的声明。例如，指向 _Recordset 对象的变量属于 _RecordsetPtr 类型，其声明如下：

_RecordsetPtr  rs;

指向 _Recordset 对象新实例的变量，其声明如下：

_RecordsetPtr  rs("ADODB.Recordset");

-或-

_RecordsetPtr  rs;
rs.CreateInstance("ADODB.Recordset");

-或-

_RecordsetPtr  rs;
rs.CreateInstance(__uuidof(_Recordset));

调用 CreateInstance 方法后，可将该变量用作：

rs->Open(...);

请注意，在一种情况下，使用“.”操作符是将变量当作类的实例 (rs.CreateInstance)；而在另一种情况下，使用“->”操作符则是将变量当作指向接口的指针 (rs->Open)。

可以用两种方式来使用一个变量，因为“->”操作符被重载，从而使类的实例与指向接口的指针的表现相似。实例变量的专用类成员包含一个指向 _Recordset 接口的指针，“->”操作符返回该指针，返回的指针访问 _Recordset 对象的成员。

对缺少的参数进行编码 — String

如果需要在 Visual Basic 中对缺少的 String 操作数进行编码，只需省略该操作数即可。在 Visual C++ 中则必须指定该操作数。对值为空字符串的 _bstr_t 进行编码。

_bstr_t strMissing(L"");

对缺少的参数进行编码 — Variant

如果需要在 Visual Basic 中对缺少的 Variant 操作数进行编码，只需省略该操作数即可。在 Visual C++ 中则必须指定所有操作数。通过将 _variant_t 设置为特殊值 DISP_E_PARAMNOTFOUND 和 VT_ERROR 类型来对缺少的 Variant 参数进行编码。也可以指定 vtMissing，它是由 #import 伪指令提供的预定义的等价常量。

_variant_t  vtMissingYours(DISP_E_PARAMNOTFOUND, VT_ERROR);

-或使用-

...vtMissing...;

声明 Variant

在 Visual Basic 中，用 Dim 语句声明 Variant，如下所示：

Dim VariableName As Variant

在 Visual C++ 中，将变量声明为 _variant_t 类型。一些示意性的 _variant_t 声明如下。

注意 这些声明只是就您在自己的程序中将进行编码提供大致意见。有关详细信息，请参阅下面的范例及 Visual C++ 文档。
_variant_t  VariableName(value);
_variant_t  VariableName((data type cast) value);
_variant_t  VariableName(value, VT_DATATYPE);
_variant_t  VariableName(interface * value, bool fAddRef = true);

使用 Variants 数组

在 Visual Basic 中，可以用 Dim 语句对 Variants 数组进行编码，也可以使用 Array 函数，如下述范例代码所示：

Public Sub ArrayOfVariants
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim fld As ADODB.Field

cn.Open "DSN=pubs", "sa", ""
rs = cn.OpenSchema(adSchemaColumns, _
                     Array(Empty, Empty, "authors", Empty))
For Each fld in rs.Fields
   Debug.Print "Name = "; fld.Name
Next fld
rs.Close
cn.Close
End Sub

下面的 Visual C++ 范例演示了将 SafeArray 与 _variant_t 一起使用的方法。

注意 下面的注释对应于代码范例中所注释的部分。
1. 同样，定义 TESTHR() 内联函数也使用现有的错误处理机制。
2. 由于只需要一个一维数组，因此可以使用 SafeArrayCreateVector，而无需常规用途的 SAFEARRAYBOUND 声明和 SafeArrayCreate 函数。下面是使用 SafeArrayCreate 时该代码的形式：
   SAFEARRAYBOUND   sabound[1];
      sabound[0].lLbound = 0;
      sabound[0].cElements = 4;
      pSa = SafeArrayCreate(VT_VARIANT, 1, sabound);
3. 由枚举常量 adSchemaColumns 所标识的方案与下面四个约束列相关联：TABLE_CATALOG、TABLE_SCHEMA、TABLE_NAME 和 COLUMN_NAME。因此，创建了一个具有四个元素的 Variant 值的数组。然后指定一个与第三列 TABLE_NAME 相对应的约束值。
返回的 Recordset 由若干列组成，上述约束列便是其中的一个子集。每个返回行的约束列的值必须与对应的约束值相同。
4. 退出前不调用 SafeArrayDestroy()，也许熟悉 SafeArrays 的人会对此感到奇怪。事实上，在这种情况下调用 SafeArrayDestroy() 将导致运行时例外。因为当 _variant_t 超出范围时，vtCriteria 的析构函数将调用 VariantClear()，从而释放 SafeArray。如果未手动清除 _variant_t 便调用 SafeArrayDestroy，将导致析构函数试图清除无效的 SafeArray 指针。
如果调用 SafeArrayDestroy，代码的形式如下：
      TESTHR(SafeArrayDestroy(pSa));
   vtCriteria.vt = VT_EMPTY;
      vtCriteria.parray = NULL;
但这比用 _variant_t 管理 SafeArray 简单得多。
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
   no_namespace rename("EOF", "EndOfFile")
#include <stdio.h>

// Note 1
inline void TESTHR( HRESULT _hr )
   { if FAILED(_hr) _com_issue_error(_hr); }

void main(void)
{
   CoInitialize(NULL);
   try
   {
   _RecordsetPtr   pRs("ADODB.Recordset");
   _ConnectionPtr  pCn("ADODB.Connection");
   _variant_t      vtTableName("authors"),
                   vtCriteria;
   long            ix[1];
   SAFEARRAY       *pSa = NULL;

   pCn->Open("DSN=pubs;User ID=MyUserId;pwd=MyPassword;Provider=MSDASQL;", "", "",
               adConnectUnspecified);
// Note 2, Note 3
   pSa = SafeArrayCreateVector(VT_VARIANT, 1, 4);
   if (!pSa) _com_issue_error(E_OUTOFMEMORY);

// Specify TABLE_NAME in the third array element (index of 2).

   ix[0] = 2;
   TESTHR(SafeArrayPutElement(pSa, ix, &vtTableName));

//   There is no Variant constructor for a SafeArray, so manually set the
//   type (SafeArray of Variant) and value (pointer to a SafeArray).

   vtCriteria.vt = VT_ARRAY | VT_VARIANT;
   vtCriteria.parray = pSa;

   pRs = pCn->OpenSchema(adSchemaColumns, vtCriteria, vtMissing);

   long limit = pRs->GetFields()->Count;
   for (long x = 0; x < limit; x++)
      printf("%d: %s\n", x+1,
         ((char*) pRs->GetFields()->Item[x]->Name));
// Note 4
   pRs->Close();
   pCn->Close();
   }
   catch (_com_error &e)
   {
   printf("Error:\n");
   printf("Code = %08lx\n", e.Error());
   printf("Code meaning = %s\n", (char*) e.ErrorMessage());
   printf("Source = %s\n", (char*) e.Source());
   printf("Description = %s\n", (char*) e.Description());
   }
   CoUninitialize();
}

使用 Get/Put/PutRef 属性

在 Visual Basic 中，无论是否对属性进行检索、分配还是分配引用，都不会限定属性名称。

Public Sub GetPutPutRef
Dim rs As New ADODB.Recordset
Dim cn As New ADODB.Connection
Dim sz as Integer
cn.Open "Provider=sqloledb;Data Source=yourserver;" & _
         "Initial Catalog=pubs;Integrated Security=SSPI;"
rs.PageSize = 10
sz = rs.PageSize
rs.ActiveConnection = cn
rs.Open "authors",,adOpenStatic
' ...
rs.Close
cn.Close
End Sub

此 Visual C++ 范例演示了 Get/Put/PutRef Property。

注意 下面的注释对应于代码范例中所注释的部分。
1. 此范例使用两种形式的缺少的字符串参数：一个显式常量 strMissing 和一个编译器用来创建临时 _bstr_t 的字符串，该 _bstr_t 将存在于 Open 方法范围内。
2. 不必将 rs->PutRefActiveConnection(cn) 的操作数指定为 (IDispatch *)，因为该操作数的类型已经是 (IDispatch *)。
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
   no_namespace rename("EOF", "EndOfFile")
#include <stdio.h>

void main(void)
{
   CoInitialize(NULL);
   try
   {
      _ConnectionPtr  cn("ADODB.Connection");
      _RecordsetPtr   rs("ADODB.Recordset");
      _bstr_t         strMissing(L"");
      long            oldPgSz = 0,
                      newPgSz = 5;

// Note 1
      cn->Open("Provider=sqloledb;Data Source=MyServer;"
         "Initial Catalog=pubs;Integrated Security=SSPI;",
         strMissing, "",
         adConnectUnspecified);

      oldPgSz = rs->GetPageSize();
   // -or-
      oldPgSz = rs->PageSize;

      rs->PutPageSize(newPgSz);
   // -or-
      rs->PageSize = newPgSz;

// Note 2
      rs->PutRefActiveConnection( cn );
      rs->Open("authors", vtMissing, adOpenStatic, adLockReadOnly,
               adCmdTable);
      printf("Original pagesize = %d, new pagesize = %d\n", oldPgSz,
               rs->GetPageSize());
      rs->Close();
      cn->Close();
   }
   catch (_com_error &e)
   {
      printf("Description = %s\n", (char*) e.Description());
   }
   ::CoUninitialize();
}

使用 GetItem(x) 和 Item[x]

本 Visual Basic 范例演示了用于 Item() 的标准语法和替换语法。

Public Sub GetItemItem
Dim rs As New ADODB.Recordset
Dim name as String
rs = rs.Open "authors", "DSN=pubs;", adOpenDynamic, _
         adLockBatchOptimistic, adTable
name = rs(0)
' -or-
name = rs.Fields.Item(0)
rs(0) = "Test"
rs.UpdateBatch
' Restore name
rs(0) = name
rs.UpdateBatch
rs.Close
End Sub

此 Visual C++ 范例演示了 Item。

注意 下面的注释对应于代码范例中所注释的部分。
1. 如果集合可通过 Item 访问，那么必须将索引 2 指定为 long 以调用适当的构造函数。
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
   no_namespace rename("EOF", "EndOfFile")
#include <stdio.h>

void main(void)
{
   CoInitialize(NULL);
   try {
      _RecordsetPtr   rs("ADODB.Recordset");
      _variant_t      vtFirstName;

      rs->Open("authors",
               "Provider=sqloledb;Data Source=MyServer;"
               "Initial Catalog=pubs;Integrated Security=SSPI;",
               adOpenStatic, adLockOptimistic, adCmdTable);
      rs->MoveFirst();

// Note 1. Get a field.
      vtFirstName = rs->Fields->GetItem((long)2)->GetValue();
   // -or-
      vtFirstName = rs->Fields->Item[(long)2]->Value;

      printf( "First name = '%s'\n", (char*) ((_bstr_t) vtFirstName));

      rs->Fields->GetItem((long)2)->Value = L"TEST";
      rs->Update(vtMissing, vtMissing);

   // Restore name
      rs->Fields->GetItem((long)2)->PutValue(vtFirstName);
      // -or-
      rs->Fields->GetItem((long)2)->Value = vtFirstName;
      rs->Update(vtMissing, vtMissing);
      rs->Close();
   }
   catch (_com_error &e)
   {
      printf("Description = '%s'\n", (char*) e.Description());
   }
   ::CoUninitialize();
}

用 (IDispatch *) 指定 ADO 对象指针

下列 Visual C++ 范例演示了用 (IDispatch *) 指定 ADO 对象指针的方法。

注意 下面的注释对应于代码范例中所注释的部分。
1. 在显式编码的 Variant 中指定一个打开的 Connection 对象。用 (IDispatch *) 指定该对象，以调用正确的构造函数。此外，将第二个 _variant_t 参数显式设置为默认值 True，以保证当 Recordset::Open 操作结束时对象引用计数正确无误。
2. (_bstr_t) 表达式不是一个指定表达式，而是一个 _variant_t 操作符，该操作符从 Value 所返回的 Variant 中提取 _bstr_t 字符串。
(char*) 表达式不是一个指定表达式，而是一个 _bstr_t 操作符，该操作符在 _bstr_t 对象中提取指向封装字符串的指针。
本段代码演示了 _variant_t 和 _bstr_t 操作符的一些用法。
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
no_namespace rename("EOF", "EndOfFile")

#include <stdio.h>

void main(void)
{
   CoInitialize(NULL);
   try
   {
      _ConnectionPtr pConn("ADODB.Connection");
      _RecordsetPtr  pRst("ADODB.Recordset");

      pConn->Open("Provider=sqloledb;Data Source=MyServer;"
         "Initial Catalog=pubs;Integrated Security=SSPI;",
         "", "", adConnectUnspecified);
// Note 1.
      pRst->Open(
         "authors",
         _variant_t((IDispatch *) pConn, true),
         adOpenStatic,
         adLockReadOnly,
         adCmdTable);
      pRst->MoveLast();
// Note 2.
      printf("Last name is '%s %s'\n",
            (char*) ((_bstr_t) pRst->GetFields()->GetItem("au_fname")->GetValue()),
            (char*) ((_bstr_t) pRst->Fields->Item["au_lname"]->Value));

      pRst->Close();
      pConn->Close();
   }
   catch (_com_error &e)
   {
      printf("Description = '%s'\n", (char*) e.Description());
   }
::CoUninitialize();
}


Visual C++ Extensions for ADO

使用 Visual C++ 编程 ADO 的首选方法是使用在 Microsoft Visual C++ ADO 编程中描述的 #import 伪指令。但是，ADO 早期版本提供了使用 Visual C++ 编程的一种可选方法：Visual C++ Extensions。本部分文档为必须维护 Visual C++ Extensions 代码，但应该使用 #import 编写新 ADO 代码的那些用户描述了此功能。

用 ADO 检索数据时，Visual C++ 程序员面对的一项最冗长而乏味的工作是将以 VARIANT 数据类型返回的数据转换为 C++ 数据类型，然后将转换后的数据存储在类或结构中。除了过程繁琐外，通过 VARIANT 数据类型检索 C++ 数据还会降低性能。

ADO 提供一个接口，该接口支持不通过 VARIANT 而将数据检索到原生 C/C++ 数据类型中。它同时还提供简化接口使用的预处理器宏。因此得到一个性能良好而又易于使用的灵活工具。

普通 C/C++ 客户端方案是将 Recordset 中的记录绑定到包含原生 C/C++ 类型的 C/C++ 结构或类上。使用 VARIANT 时，将涉及编写从 VARIANT 转换到 C/C++ 原生类型的代码。Visual C++ Extensions for ADO 的目的是使 Visual C++ 程序员更容易实现此方案。

有关 Visual C++ Extensions for ADO 的详细信息，请参阅下面的主题。

  • 使用 Visual C++ Extensions for ADO
  • Visual C++ Extensions 头文件
  • ADO with Visual C++ Extensions 范例

请参阅

用于 COM 的 ADO for Visual C++ 语法索引 | ADO with Visual C++ Extensions 范例 | 使用 Visual C++ Extensions for ADO | Visual C++ Extensions 头文件


使用 Visual C++ Extensions

IADORecordBinding 接口

Microsoft Visual C++ Extensions for ADO 将 Recordset 对象的字段关联或绑定到 C/C++ 变量。只要被绑定的 Recordset 的当前行更改，Recordset 中的所有绑定字段都将被复制到 C/C++ 变量中。必要时，复制的数据将被转换为 C/C++ 变量的已声明数据类型。

IADORecordBinding 接口的 BindToRecordset 方法将字段绑定到 C/C++ 变量。AddNew 方法向被绑定的 Recordset 中添加新行。Update 方法用 C/C++ 变量的值来预置 Recordset 的新行中的字段，或者更新现有行中的字段。

IADORecordBinding 接口由 Recordset 对象实现。您不用亲自对实现进行编码。

绑定项目

Visual C++ Extensions for ADO 将 Recordset 对象的字段映射到 C/C++ 变量。字段与变量之间映射的定义称作“绑定项目”。宏为数字型、定长型和变长型数据提供绑定项目。绑定项目和 C/C++ 变量在源自 Visual C++ Extensions CADORecordBinding 类的类中声明。CADORecordBinding 类由绑定项目的宏进行内部定义。

ADO 将这些宏中的参数内部映射到 OLE DB DBBINDING 结构，并且创建一个 OLE DB Accessor 对象以管理字段与变量之间的数据移动和转换。OLE DB 将数据定义为由以下三部分组成：存储数据的缓冲区；指示字段是否被顺利存储到缓冲区或如何将变量恢复为字段的状态；以及数据的长度。（有关详细信息，请参阅 OLE DB Programmer's Reference 中的 Chapter 6: Getting and Setting Data。）

头文件

应用程序中应包含下列文件以使用 Visual C++ Extensions for ADO：

#include <icrsint.h>

绑定 Recordset 字段

将 Recordset 字段绑定到 C/C++ 变量的步骤：

  1. 创建一个源自 CADORecordsetBinding 类的类。
  2. 在得出的类中指定绑定项目和对应的 C/C++ 变量。将 BEGIN_ADO_BINDING 和 END_ADO_BINDING 宏之间的绑定项目用括号括起来。不要用逗号或分号终止宏。每一个宏将自动指定适当的分隔符号。

    为每一个要映射到 C/C++ 变量的字段指定一个绑定项目。使用宏的 ADO_FIXED_LENGTH_ENTRY、ADO_NUMERIC_ENTRY 或 ADO_VARIABLE_LENGTH_ENTRY 类中的适当成员。

  3. 在应用程序中创建一个源自 CADORecordBinding 的类的实例。从 Recordset 中获取 IADORecordBinding 接口。 然后调用 BindToRecordset 方法将 Recordset 字段绑定到 C/C++ 变量。

有关详细信息，请参阅 Visual C++ Extensions 范例。

接口方法

IADORecordBinding 接口有三种方法：BindToRecordset、AddNew 和 Update。每种方法的专用参数都是一个指向源自 CADORecordBinding 的类的实例的指针。因此，AddNew 和 Update 方法无法指定任何同名的 ADO 方法的参数。

语法

BindToRecordset 方法将 Recordset 字段与 C/C++ 变量相关联。

BindToRecordset(CADORecordBinding *binding)

AddNew 方法调用其同名方法（ADO AddNew 方法）向 Recordset 中添加新行。

AddNew(CADORecordBinding *binding)

Update 方法调用其同名方法（ADO Update 方法）更新 Recordset。

Update(CADORecordBinding *binding)

绑定项目的宏

绑定项目的宏定义 Recordset 字段与变量之间的关联。开始宏和结束宏分隔绑定项目的集合。

针对给定长数据（如 adDate 或 adBoolean）、数字型数据（如 adTinyInt、adInteger 或 adDouble）和变长数据（如 adChar、adVarChar 或 adVarBinary）提供了几类宏。除 adVarNumeric 以外，所有数字类型也都是定长类型。每一类均有不同的参数集，从而可排除无关的绑定信息。

（有关详细信息，请参阅 OLE DB Programmer's Reference 中的 Appendix A：Data Types。）

开始绑定项目

BEGIN_ADO_BINDING(Class)

定长数据

ADO_FIXED_LENGTH_ENTRY(Ordinal, DataType, Buffer, Status, Modify)
ADO_FIXED_LENGTH_ENTRY2(Ordinal, DataType, Buffer, Modify)

数字型数据

ADO_NUMERIC_ENTRY(Ordinal, DataType, Buffer, Precision, Scale, Status,
Modify)
ADO_NUMERIC_ENTRY2(Ordinal, DataType, Buffer, Precision, Scale, Modify)

变长数据

ADO_VARIABLE_LENGTH_ENTRY(Ordinal, DataType, Buffer, Size, Status,
Length, Modify)
ADO_VARIABLE_LENGTH_ENTRY2(Ordinal, DataType, Buffer, Size, Status,
Modify)
ADO_VARIABLE_LENGTH_ENTRY3(Ordinal, DataType, Buffer, Size, Length,
Modify)
ADO_VARIABLE_LENGTH_ENTRY4(Ordinal, DataType, Buffer, Size, Modify)

结束绑定项目

END_ADO_BINDING()

参数 | 说明
Class | 在其中定义绑定项目和 C/C++ 变量的类。
Ordinal | 与 C/C++ 变量相对应的 Recordset 字段的序号（从一开始计数）。
DataType | C/C++ 变量的等价 ADO 数据类型（有关有效数据类型的列表，请参阅 DataTypeEnum）。必要时，Recordset 字段的值将转换为此数据类型。
Buffer | 存储 Recordset 字段的 C/C++ 变量的名称。
Size | Buffer 的最大字节大小。如果 Buffer 包含变长字符串，请为终止到零预留空间。
Status | 变量名称，指示 Buffer 的内容是否有效以及是否已成功地将字段转换为 DataType。 此变量的两个最重要的值为 adFldOK（表明转换成功）和 adFldNull（表明字段值为类型 VT_NULL 的 VARIANT，而不仅仅是空值）。 下表“Status 值”列出了 Status 可能的值。
Modify | Boolean 标志。如果是 TRUE，则指示允许 ADO 用 Buffer 中包含的值来更新对应的 Recordset 字段。 将 Boolean modify 参数设置为 TRUE 以启用 ADO 来更新绑定的字段。如果只想检查字段而不想对它进行更改，请将该参数设置为 FALSE。
Precision | 表示数字型变量的位数。
Scale | 数字型变量的小数位数。
Length | 包含 Buffer 中数据的实际长度的四字节变量的名称。

Status 值

Status 变量的值指示是否已成功地将字段复制到变量。

设置数据时，可将 Status 设置为 adFldNull 以指示应将 Recordset 字段设置为 Null。

常量 | 值 | 说明
adFldOK | 0 | 返回非 Null 字段值。
adFldBadAccessor | 1 | 绑定无效。
adFldCantConvertValue | 2 | 无法转换值，但不是因为符号不匹配或数据溢出。
adFldNull | 3 | 获取字段时，指示返回 Null 值。 设置字段时，指示当字段不能自己编码 NULL（如字符数组或整数）时应将字段设置为 NULL。
adFldTruncated | 4 | 变长数据或数字型数据被截断。
adFldSignMismatch | 5 | 值带符号而变量数据类型无符号。
adFldDataOverFlow | 6 | 值比变量数据类型可存储的值大。
adFldCantCreate | 7 | 已打开未知的列类型和字段。
adFldUnavailable | 8 | 无法确定字段值，例如在没有默认值的新字段上。
adFldPermissionDenied | 9 | 更新时不允许写入数据。
adFldIntegrityViolation | 10 | 更新时，字段值可能会破坏列的完整性。
adFldSchemaViolation | 11 | 更新时，字段值可能会破坏列的模式。
adFldBadStatus | 12 | 更新时，状态参数无效。
adFldDefault | 13 | 更新时，使用默认值。

请参阅

ADO with Visual C++ Extensions 范例 | Visual C++ Extensions 头文件


Visual C++ Extensions 头文件

下面的头文件 icrsint.h 详细说明了允许客户从 Recordset 向变量中检索字段的接口，这些变量在源自 CADORecordBinding 的类中定义。您必须为要访问的每一个字段指定一个 ADO 绑定宏。

#ifndef _ICRSINT_H_
#define _ICRSINT_H_

#include <olectl.h>
#include <stddef.h>

// forwards
class CADORecordBinding;

#define classoffset(base, derived) ((DWORD)(static_cast<base*>((derived*)8))-8)

enum ADOFieldStatusEnum
{
   adFldOK = 0,
   adFldBadAccessor = 1,
   adFldCantConvertValue = 2,
   adFldNull = 3,
   adFldTruncated = 4,
   adFldSignMismatch = 5,
   adFldDataOverFlow = 6,
   adFldCantCreate = 7,
   adFldUnavailable = 8,
   adFldPermissionDenied = 9,
   adFldIntegrityViolation = 10,
   adFldSchemaViolation = 11,
   adFldBadStatus = 12,
   adFldDefault = 13
};

typedef struct stADO_BINDING_ENTRY
{
   ULONG      ulOrdinal;
   WORD       wDataType;
   BYTE       bPrecision;
   BYTE       bScale;
   ULONG      ulSize;
   ULONG      ulBufferOffset;
   ULONG      ulStatusOffset;
   ULONG      ulLengthOffset;
   ULONG      ulADORecordBindingOffSet;
   BOOL       fModify;
} ADO_BINDING_ENTRY;

#define BEGIN_ADO_BINDING(cls) public: \
   typedef cls ADORowClass; \
   const ADO_BINDING_ENTRY* STDMETHODCALLTYPE GetADOBindingEntries() { \
   static const ADO_BINDING_ENTRY rgADOBindingEntries[] = {

//
// Fixed length non-numeric data
//
#define ADO_FIXED_LENGTH_ENTRY(Ordinal, DataType, Buffer, Status, Modify)\
   {Ordinal, \
   DataType, \
   0, \
   0, \
   0, \
   offsetof(ADORowClass, Buffer), \
   offsetof(ADORowClass, Status), \
   0, \
   classoffset(CADORecordBinding, ADORowClass), \
   Modify},

#define ADO_FIXED_LENGTH_ENTRY2(Ordinal, DataType, Buffer, Modify)\
   {Ordinal, \
   DataType, \
   0, \
   0, \
   0, \
   offsetof(ADORowClass, Buffer), \
   0, \
   0, \
   classoffset(CADORecordBinding, ADORowClass), \
   Modify},

//
// Numeric data
//
#define ADO_NUMERIC_ENTRY(Ordinal, DataType, Buffer, Precision, Scale, Status, Modify)\
   {Ordinal, \
   DataType, \
   Precision, \
   Scale, \
   0, \
   offsetof(ADORowClass, Buffer), \
   offsetof(ADORowClass, Status), \
   0, \
   classoffset(CADORecordBinding, ADORowClass), \
   Modify},

#define ADO_NUMERIC_ENTRY2(Ordinal, DataType, Buffer, Precision, Scale, Modify)\
   {Ordinal, \
   DataType, \
   Precision, \
   Scale, \
   0, \
   offsetof(ADORowClass, Buffer), \
   0, \
   0, \
   classoffset(CADORecordBinding, ADORowClass), \
   Modify},

//
// Variable length data
//
#define ADO_VARIABLE_LENGTH_ENTRY(Ordinal, DataType, Buffer, Size, Status, Length, Modify)\
   {Ordinal, \
   DataType, \
   0, \
   0, \
   Size, \
   offsetof(ADORowClass, Buffer), \
   offsetof(ADORowClass, Status), \
   offsetof(ADORowClass, Length), \
   classoffset(CADORecordBinding, ADORowClass), \
   Modify},

#define ADO_VARIABLE_LENGTH_ENTRY2(Ordinal, DataType, Buffer, Size, Status, Modify)\
   {Ordinal, \
   DataType, \
   0, \
   0, \
   Size, \
   offsetof(ADORowClass, Buffer), \
   offsetof(ADORowClass, Status), \
   0, \
   classoffset(CADORecordBinding, ADORowClass), \
   Modify},

#define ADO_VARIABLE_LENGTH_ENTRY3(Ordinal, DataType, Buffer, Size, Length, Modify)\
   {Ordinal, \
   DataType, \
   0, \
   0, \
   Size, \
   offsetof(ADORowClass, Buffer), \
   0, \
   offsetof(ADORowClass, Length), \
   classoffset(CADORecordBinding, ADORowClass), \
   Modify},

#define ADO_VARIABLE_LENGTH_ENTRY4(Ordinal, DataType, Buffer, Size, Modify)\
   {Ordinal, \
   DataType, \
   0, \
   0, \
   Size, \
   offsetof(ADORowClass, Buffer), \
   0, \
   0, \
   classoffset(CADORecordBinding, ADORowClass), \
   Modify},

#define END_ADO_BINDING()   {0, adEmpty, 0, 0, 0, 0, 0, 0, 0, FALSE}};\
   return rgADOBindingEntries;}

//
// Interface that the client 'record' class needs to support. The ADO Binding entries
// provide the implementation for this interface.
//
class CADORecordBinding
{
public:
   STDMETHOD_(const ADO_BINDING_ENTRY*, GetADOBindingEntries) (VOID) PURE;
};

//
// Interface that allows a client to fetch a record of data into class data members.
//
struct __declspec(uuid("00000544-0000-0010-8000-00aa006d2ea4")) IADORecordBinding;
DECLARE_INTERFACE_(IADORecordBinding, IUnknown)
{
public:
   STDMETHOD(BindToRecordset) (CADORecordBinding *pAdoRecordBinding) PURE;
   STDMETHOD(AddNew) (CADORecordBinding *pAdoRecordBinding) PURE;
   STDMETHOD(Update) (CADORecordBinding *pAdoRecordBinding) PURE;
};

#endif // !_ICRSINT_H_

请参阅

ADO with Visual C++ Extensions 范例 | 使用 Visual C++ Extensions for ADO


Visual C++ Extensions 范例

此程序说明如何从字段中检索值并转换到 C/C++ 变量中。

此范例还利用了“智能指针”，它自动处理 COM 特有的 QueryInterface 调用和 IADORecordBinding 接口的引用计数的细节。

如果没有智能指针，需要编写代码：

IADORecordBinding   *picRs = NULL;
...
TESTHR(pRs->QueryInterface(
          __uuidof(IADORecordBinding), (LPVOID*)&picRs));
...
if (picRs) picRs->Release();

如果有智能指针，则可以用此语句从 IADORecordBinding 接口中获得 IADORecordBindingPtr 类型：

_COM_SMARTPTR_TYPEDEF(IADORecordBinding, __uuidof(IADORecordBinding));

对指针的实例化如下：

IADORecordBindingPtr picRs(pRs);

由于 Visual C++ Extensions 通过 Recordset 对象实现，因此用于 picRs 智能指针的构造函数接受 _RecordsetPtr 指针 pRs。构造函数用 pRs 来调用 QueryInterface，以查找 IADORecordBinding 接口。

// Visual C++ Extensions Example
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
   no_namespace rename("EOF", "EndOfFile")

#include <stdio.h>
#include <icrsint.h>
_COM_SMARTPTR_TYPEDEF(IADORecordBinding, __uuidof(IADORecordBinding));

inline void TESTHR(HRESULT _hr) { if FAILED(_hr) _com_issue_error(_hr); }

class CCustomRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CCustomRs)
   ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_ch_fname,
                        sizeof(m_ch_fname), m_ul_fnameStatus, false)
   ADO_VARIABLE_LENGTH_ENTRY2(4, adVarChar, m_ch_lname,
                        sizeof(m_ch_lname), m_ul_lnameStatus, false)
END_ADO_BINDING()
public:
   CHAR    m_ch_fname[22];
   CHAR    m_ch_lname[32];
   ULONG   m_ul_fnameStatus;
   ULONG   m_ul_lnameStatus;
};

void main(void)
{
   ::CoInitialize(NULL);
   try
      {
      _RecordsetPtr pRs("ADODB.Recordset");
      CCustomRs rs;
      IADORecordBindingPtr picRs(pRs);

      pRs->Open("SELECT * FROM Employee ORDER BY lname",
         "dsn=pubs;uid=sa;pwd=;",
         adOpenStatic, adLockOptimistic, adCmdText);

      TESTHR(picRs->BindToRecordset(&rs));

      while (!pRs->EndOfFile)
         {
      // Process data in the CCustomRs C++ instance variables.
         printf("Name = %s %s\n",
            (rs.m_ul_fnameStatus == adFldOK ? rs.m_ch_fname: "<Error>"),
            (rs.m_ul_lnameStatus == adFldOK ? rs.m_ch_lname: "<Error>"));

      // Move to the next row of the Recordset.
      // Fields in the new row will automatically be
      // placed in the CCustomRs C++ instance variables.

         pRs->MoveNext();
         }
      }
   catch (_com_error &e )
      {
      printf("Error:\n");
      printf("Code = %08lx\n", e.Error());
      printf("Meaning = %s\n", e.ErrorMessage());
      printf("Source = %s\n", (LPCSTR) e.Source());
      printf("Description = %s\n", (LPCSTR) e.Description());
      }
   ::CoUninitialize();
}

请参阅

使用 Visual C++ Extensions for ADO | Visual C++ Extensions 头文件


通过 Microsoft Visual J++ 使用 ADO

您可以通过下列方式使用 Visual J++ 实现 ADO：

  • 在 Visual J++ 6.0（或更新版本）中，使用 ADO for Windows Foundation Classes。
  • 在 Visual J++ 1.x 中，使用 Java Type Library Wizard。
  • 使用 Microsoft SDK for Java 实用程序。

有关通过 Visual J++ 使用 ADO 的详细信息，请参阅下列主题：

  • ADO Java 类封装
  • ADO/WFC 语法索引

请参阅

ADO for Windows Foundation Classes | ADO Java 类封装 | ADO/WFC 语法索引 | 通过 Microsoft Visual Basic 使用 ADO | 通过 Microsoft Visual C++ 使用 ADO | 通过脚本语言使用 ADO | 通过 Java Type Library Wizard 使用 ADO | 通过 Microsoft SDK for Java 使用 ADO


ADO/WFC 编程

对于 Microsoft Visual J++ 6.0，ADO 已经被扩展为以下列方式使用 Windows Foundation Classes (WFC)。首先，已经实现了一个 Java 类的集合，它可扩展 ADO 接口并创建 Java 程序员感兴趣的通知；该 Java 类还具有把 Java 类型返回给用户的函数。为了提高性能，Java 类直接访问 OLE DB 行集合对象中的原生数据类型，并把它们作为 Java 类型返回给 Java 程序员，而不是先与变体型相互转换。ADO 还被扩展为使用 WFC 框架中的事件通知。

ADO for Windows Foundation Classes (ADO/WFC) 支持所有标准 ADO 方法、属性、对象和事件。然而，需要变体型参数的操作在 Microsoft Visual Basic 等语言中性能较优，但在 Visual J++ 等语言中性能较低。因此，ADO/WFC 还提供了 Field 对象的存取函数，用原生 Java 数据类型代替了变体型数据类型。

有关包含在 ADO 文档中的 ADO/WFC 包的详细信息，请参阅 ADO/WFC 语法索引。

有关 Visual J++ 文档中的相关信息，请参阅 Converting Visual Basic ADO Examples to Visual J++。

引用库

若要将 ADO/WFC 数据类导入到工程中，请在代码中包括以下行：

import com.ms.wfc.data.*;

请参阅

不同语言的 ADO 事件实例 | ADO/WFC 语法索引 | 通过 Java Type Library Wizard 使用 ADO | 通过 Microsoft SDK for Java 使用 ADO


使用 Java Type Library Wizard

Java Type Library Wizard 是 Visual J++ 1.x 的一项功能，它被集成到开发环境的 Tools 菜单中。它的目的是搜索类型库并创建一个允许访问 COM 对象的 Java 接口。对于 Visual J++ 6.0，Java Type Library Wizard 已经被 ADO for Windows Foundation Classes 所代替。

Java Type Library Wizard 与 Microsoft SDK for Java 包括的命令行工具产生相似的结果。但是，您不能跟踪到 Wizard 生成的类封装中，这一点与 Microsoft SDK for Java 生成的类封装不同。

Java Type Library Wizard 在下列位置生成类：\<Windows 目录>\Java\trustlib\msado15。位于生成类的目录中的 Summary.txt 文件显示了生成的类定义。

Java Type Library Wizard 把在任何给定的类型库中找到的枚举类型转换为 INT（整数）类型。它还定义了与类型库中每个枚举类型相对应的接口。您可以通过下列语法引用 ADO 枚举类型的值：

msado15.<Enum Name>.<constant Name>

下列用于设置 Command 对象的 CommandType 属性的代码段显示了一个范例：

Cmd1.putCommandType( msado15.CommandTypeEnum.adCmdStoredProc );

也可以从 Java Type Library Wizard 生成的枚举类型封装继承。如果是这种情况，可以从语法中删除“msado15.”。但是，您的类将需要从其引用的每个 Java 对象和枚举类型接口继承，以便彻底消除在所有 ADO 对象和枚举值前面引用 msado15.* 的要求。

有关更多的范例代码，请参阅 ADO Java 类封装。

从 Visual J++ 版本 1.x 运行 Java Type Library Wizard 的步骤：

  1. 从“工具” 菜单中选择“Java Type Library Wizard”。
  2. 选择“Microsoft ActiveX Data Objects Library”，然后单击“确定”。现在，在 ADO 的 \trustlib 目录（默认情况下为 c:\winnt\java\trustlib\msado15）下生成（或重新生成）文件。如果您已经使用 Microsoft SDK for Java 生成了 ADO 的类，它们将被 Java Type Library Wizard 中的类替换。
  3. 要使用这些文件，请在 Visual J++ 中打开您的工程。从 Project 菜单中选择 Add To Project。选择 Files，然后把所有在 \trustlib 目录（默认情况下为 c:\winnt\java\trustlib\msado15）中生成的 .JAVA 文件添加到您的工程中。

请参阅

ADO for Windows Foundation Classes | ADO Java 类封装 | 通过 Microsoft SDK for Java 使用 ADO


使用 Microsoft SDK for Java

Microsoft SDK for Java 是用于 Microsoft Internet Explorer 环境的开发人员工具包。它提供了工具、信息和范例，帮助您开发基于 JDK 1.1 和 Microsoft Win32 虚拟机 (Microsoft VM) 的 Java 程序和 Applet。Microsoft SDK for Java 没有与 Microsoft Visual J++ 捆绑在一起，它可以从 http://www.microsoft.com/Java 网址下载。

Jactivex.exe 实用程序从类型库生成类，但是只能在命令行中调用。此功能未集成在 Visual J++ 开发环境中。与 Java Type Library Wizard 生成的类不同，您可以单步跟踪到 SDK 创建的类封装中。这有助于调试代码使用 ADO 封装类的方式。

此机制读取 ADO 类型库并生成可以在应用程序中实例化的类。它在下列位置生成类：\<Windows 目录>\Java\trustlib\msado15。

从源代码来看，使用 Microsoft SDK for Java 在 Java 中创建 ADO 应用程序与使用 Java Type Library Wizard 是基本相同的。有关的范例代码，请参阅 ADO Java 类封装。唯一真正的区别在于在第一个位置生成封装类的方式，如下列步骤所示。

用 Microsoft SDK for Java 创建 ADO 工程的步骤：

  1. 从命令提示符运行下列命令。需要将路径设置到包含 Microsoft SDK for Java Bin 目录，或者从该位置运行命令。通常，Microsoft SDK for Java 与 Visual Studio 安装在相同的位置。这是一个单命令语句。
    \<path to DevStudio>\<path to Java SDK>\bin\JactiveX.exe /javatlb "C:\program files\common files\system\ado\msado15.dll"
  2. 运行下列命令来编译生成的类。/g:t 开关打开可生成调试符号，这样您就可以跟踪到 .Java 符号中。编译正式版本时要删除调试符号。
    jvc /g:t c:\<windows>\Java\trustlib\msado15\*.Java
  3. 要使用这些文件，请在 Visual J++ 中打开您的工程。从 Project 菜单中选择 Add To Project。选择 Files，然后把在 trustlib\msado15 目录中生成的所有 .JAVA 文件添加到您的工程中。

请参阅

ADO for Windows Foundation Classes | ADO Java 类封装 | 通过 Java Type Library Wizard 使用 ADO


ADO Java 类封装

此代码声明了一个 ADO Recordset 类封装的实例并对它进行初始化，所有操作都在同一行代码中完成。此后，它声明了 Open 方法中每个参数的变量，尤其是 LockType 和 CursorType（因为 Java 不支持枚举类型）。它可以打开和关闭 Recordset 对象。把 Rs1 设置为 NULL 只是在 Java 系统地和间歇性释放未使用的对象时安排释放该变量。

public static void main( String args[])
{
   msado15._Recordset   Rs1 = new msado15.Recordset();
   Variant Source     = new Variant( "SELECT * FROM Authors" );
   Variant Connect    = new Variant( "DSN=AdoDemo;UID=admin;PWD=;" );
   int     LockType   = msado15.CursorTypeEnum.adOpenForwardOnly;
   int     CursorType = msado15.LockTypeEnum.adLockReadOnly;
   int     Options    = -1;

   Rs1.Open( Source, Connect, LockType,  CursorType, Options );
   Rs1.Close();
   Rs1 = null;

   System.out.println( "Success!\n" );
}

请参阅

通过 Java Type Library Wizard 使用 ADO | 通过 Microsoft SDK for Java 使用 ADO


附录 D：ADO 范例

MDAC SDK 包含了几个范例应用程序，用于演示 ADO 和 RDS 代码的用法。

ADO 文档还包括多种语言的代码范例，它们以主题的形式包含在此联机帮助中。有关这些范例的详细信息，请参阅 ADO 代码范例。

还可以获得许多其他范例代码资源。Visual Studio 文档和 MSDN Library 包含各种范例应用程序，以及有助于您了解 ADO 和 RDS 的文档。

Visual Studio 范例

  • Visual Studio Solutions Center 网站
  • Island Hopper News Sample
  • Visual Basic Samples
  • Visual C++ Samples
  • Visual InterDev Samples
  • Visual J++ Samples

Visual Studio 文档

  • Visual Studio: Data Access and Security Strategies
  • Visual Basic: Data Access Guide
  • Visual InterDev: Integrating Databases
  • Visual J++: Accessing Data

请参阅

ADO API 参考 | 配置 RDS | ActiveX 数据对象起始页 | ADO 编程 | 附录 A：提供者 | ADO 的新增内容


ADO 词汇表

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

A

绝对 URL

ActiveX 控件

ADISAPI

高级数据 Internet 服务器应用程序编程接口

合计函数

别名

房间线程

异步操作

B

绑定项目

位掩码

书签

业务对象

业务规则

C

计算表达式

子集

子集别名

字符集

子

子别名

类标识符

CLSID

客户端层

COM

COM 组件

比较操作符

组件

组件对象模型

复合文件

常量

游标

D

数据绑定

数据定义语言

数据操作语言

数据提供者

数据构形

数据源名称

数据源层

DCOM

DDL

默认流

断开连接的记录集

分布式应用程序

分布式组件对象模型

DLL

DML

文档源提供者

DSN

动态链接库

动态属性

E

枚举

事件

事件处理程序

F

G

H

处理程序

分级记录集

分级结构

I

Internet 服务器应用程序编程接口

ISAPI

J

K

键

L

M

调度

中间层

MIME

多用途 Internet 多用途

N

节点

O

对象变量

ODBC

OLE DB

开放式数据库互连

开放式锁定

序号值

P

参数化命令

父

父别名

父子关系

持久

保守式锁定

缓冲池

ProgID

编程标识符

代理

Q

R

相对 URL

远程数据源

资源记录

根

行集合

S

模式

范围

服务提供者

成形 Recordset

兄弟

存储过程

通讯模块

子节点

同步操作

T

树

U

统一资源定位符

URL

V

W

Web 服务器

X

Y

Z

术语与定义

绝对 URL

完全确定的 URL，它指定资源在 Internet 或 Intranet 上的位置。请参阅 URL 和相对 URL。

返回顶部

ActiveX 控件

自注册的进程内 COM 组件，在设计时或运行时通常包含可视元素。ActiveX 控件还具有与 Active Document 容器（如 Microsoft Internet Explorer）进行通讯的能力。

返回顶部

ADISAPI（高级数据 Internet 服务器应用程序编程接口）

提供语法分析、自动控制、Recordset 调度和 MIME 打包的 ISAPI DLL。ADISAPI 组件通过由 Internet Information Services (IIS) 提供的 API 工作。请参阅 ISAPI。

返回顶部

合计函数

在查询中，函数（如 COUNT、AVG 或 STDEV）使用表的一个列中的所有行进行计算。在编写表达式和编程时，可以用 SQL 合计函数（包括上面所列的三个函数）和域合计函数进行各种统计。

返回顶部

别名

赋予 SQL SELECT 语句中的列或表达式的替换名称，通常较短或更有意义。例如，BobSales 是下列 SELECT 语句的别名：“Select wr-Sales as BobSales from SalesDB”。可以用别名动态分配列，以控制 DataControl 对象上的绑定。

返回顶部

房间线程

COM 线程模型，在这种模型中对一个对象的所有调用均发生在一个线程上。在房间线程中，COM 同步并调度调用。请参阅 COM。

返回顶部

异步操作

不等操作完成便将控件返回调用程序的一种操作。在操作完成之前，继续执行代码。请参阅同步操作。

返回顶部

绑定项目

表中字段与变量之间的映射。在 ADO Visual C++ 扩展中，Recordset 字段被映射到 C/C++ 变量。

返回顶部

位掩码

用于与其他数字值进行逐位值比较的数字值，通常用于标记参数中的选项或返回值。通常，这种比较通过位逻辑运算符完成，例如 Visual Basic 中的 And 和 Or，C++ 中的 & 和 |。
例如，可将 ADO FieldAttributeEnum 值用作位掩码，以确定字段的属性。假设要确定某字段是否可更新，可在 Visual Basic 中用下列表达式对此进行测试：

Field.Attributes AND adFldUpdatable
如果结果为 TRUE，那么字段可更新。

返回顶部

书签

唯一标识行集合中的行以便用户快速定位到该行的标记。

返回顶部

业务对象

执行已定义的某组操作（如数据验证或业务规则逻辑）的对象。业务对象通常位于中间层。

返回顶部

业务规则

验证编辑、登录验证、数据库查找、策略以及算法变换的组合，共同组成企业的业务运转方式。也称为“业务逻辑”。

返回顶部

计算表达式

不是常量，其值取决于其他值的表达式。要进行计算，计算表达式必须获取并计算其他源中的值，通常是其他字段或行中的值。

返回顶部

子集

对数据源的行的范围的引用。在 ADO 中，子集通常是对另一个 Recordset 的引用。
子集列可以定义“父子”关系，其中“父”是包含子集列的 Recordset，“子”是由子集表示的 Recordset。

返回顶部

子集别名

引用追加到父的列的别名。

返回顶部

字符集

一组字符与其数字值之间的映射。例如，Unicode 是一个 16 位字符集，它可对所有已知的字符进行编码，因而可用作全球范围的字符编码标准。

返回顶部

子

分级关系的附属端。子是分级结构中的一个节点，分级结构中有其他节点位于此节点之上（更靠近根）。请参阅子别名、父子关系和父。

返回顶部

子别名

引用子的别名。请参阅别名和子。

返回顶部

CLSID（类标识符）

标识 COM 组件的通用的唯一标识符 (UUID)。每个 COM 组件在 Windows 注册表中都有自己的 CLSID，以便于其他应用程序加载。请参阅 ProgID 和 COM。

返回顶部

客户端层

分布式系统的逻辑层，通常向用户显示数据并处理用户的输入，有时引用为“前端”。通常，客户端层通过输入向服务器请求数据，然后将其格式化并显示结果。请参阅中间层、数据源层和分布式应用程序。

返回顶部

COM（组件对象模型）

二进制标准，使对象能在网络化的环境中共同操作，而无须考虑开发对象时所用的语言或所在的计算机。基于 COM 的技术包括 ActiveX 控件、Automation 及对象链接和嵌入 (OLE)。COM 允许对象向其他组件和主机应用程序显示其功能。它既定义对象显示自己的方式，又定义这种显示跨越进程和网络进行工作的方式。COM 还定义对象的生命周期。

返回顶部

COM 组件

二进制文件（如 .dll、.ocx 和某些 .exe 文件），它支持用于提供对象的 COM 标准。这样的文件包含有关一个或多个类机制、COM 类、注册项目机制、加载代码等的代码。

返回顶部

比较操作符

对两个表达式进行比较并返回一个 Boolean 值的操作符。
标准参数，可表达为“>”（大于）、“<”（小于）、“=”（等于）、“>=”（大于或等于）、“<=”（小于或等于）、“<>”（不等于）或“like”（模式匹配）。

返回顶部

组件

封装数据和代码的对象，它提供一组特定的公开可用服务。

返回顶部

复合文件

文件的 COM 结构化存储的实现。复合文件将单独对象存储在单一的、结构化文件中，此文件由两个主要元素组成：存储对象和流对象。二者结合使用，可象文件内的文件系统一样起作用。有关详细信息，请参阅 Microsoft Platform SDK 中的 Compound Files。
多个单个文件绑定在一个物理文件中。复合文件中的每个单个文件均可作为一个物理文件进行访问。

返回顶部

常量

不会发生更改的数字值或字符串值。可在代码中使用已命名的 ADO 枚举（枚举常量）来代替实际的值，例如，adUseClient 是值为 3 的常量 (Const adUseClient = 3)。请参阅枚举。

返回顶部

游标

数据库元素，它控制记录定位、数据可更新性以及其他用户对数据库所做的更改的可视性。

返回顶部

数据绑定

将应用程序的对象或控件关联到数据源的过程。与数据源相关联的控件称为“数据绑定控件”。
数据绑定控件的内容与数据库的值相关联。例如，当更新 Recordset 中的行时，也可更新绑定到 Recordset 对象的网格控件。如果 Recordset 检索到新值，那么这些新值将显示在网格控件中。

返回顶部

数据提供者

通过服务提供者或者直接向 ADO 应用程序显露数据的软件。请参阅服务提供者。

返回顶部

数据构形

一种技术，它用正式语法（称为“构形语言”）来定义专门的 Recordset 对象（称为成形 Recordset），该对象不仅包含数据，还包含对其他 Recordset 对象和/或基于这些 Recordset 对象的计算值的引用。

返回顶部

数据源层

分布式系统的逻辑层，表示正在运行 DBMS（如 SQL Server 数据库）的计算机。请参阅客户端层、中间层和分布式应用程序。

返回顶部

DCOM

传输协议，它使 COM 组件能够跨越网络彼此间直接进行通讯。请参阅 COM 和组件。

返回顶部

DDL（数据定义语言）

定义而不是操作数据的 SQL 语句。用 DDL 创建或修改数据库的模式。例如，CREATE TABLE、CREATE INDEX、GRANT 和 REVOKE 都是 SQL DDL 语句。

返回顶部

默认流

当使用某些 OLE DB 提供者（如 Microsoft OLE DB Provider for Internet Publishing）时与 Record 或 Recordset 对象相关联的文本或二进制流（由 Stream 对象表示）。默认流通常包含文件（如网站的根的 HTML 代码）的内容。

返回顶部

分布式应用程序

编写的程序，便于通过网络将处理过程分发到多个计算机。通常，分布式应用程序被分为显示、业务逻辑和数据存储层（或“层”）。请参阅客户端层、中间层和数据源层。

返回顶部

断开连接的记录集

不再包含到服务器的活动连接的客户端缓存中的 Recordset 对象。如果由于某种原因（如更新数据）需要再次访问原数据源，必须重新建立连接。但是，仍可以访问断开连接的 Recordset 的集合、属性和方法。

返回顶部

DLL（动态链接库）

包含一个或多个函数的文件，对这些函数的编译、链接和存储独立于使用它们的进程。在进程启动或运行时，操作系统将把 DLL 映射到调用进程的地址空间。

返回顶部

DML（数据操作语言）

用于操作而不是定义数据的 SQL 语句。用 DML 选择和修改数据库中的值。例如，INSERT、UPDATE、DELETE 和 SELECT 都是 SQL DML 语句。

返回顶部

文档源提供者

一类特殊的提供者，它管理文件夹和文档。当 Record 对象表示文档或者 Recordset 对象表示文档的文件夹时，文档源提供者将用唯一一组描述文档特性的字段（而不是实际文档）来预置这些对象。请参阅资源记录。

返回顶部

DSN（数据源名称）

用于将应用程序连接到特定的 ODBC 数据库的信息集合。ODBC 驱动程序管理器用这些信息创建与数据库的连接。DSN 可存储在文件（文件 DSN）或 Windows 注册表（计算机 DSN）中。

返回顶部

动态属性

数据提供者或游标服务特有的属性。对象的 Properties 集合由这些属性自动（“动态地”）预置。通过特定的数据提供者连接到数据源之前，对象不具有动态属性。请参阅数据提供者和游标。

返回顶部

枚举

命名常量的列表。枚举值不必唯一。但是，每个值的名称在定义该枚举的范围内必须是唯一的。在 ADO 中，枚举用于数字型参数和返回值、给 ADO 代码添加意义以及屏蔽数字值（数字值在不同版本中可能会有所变化）的开发人员。例如，若要打开一个静态的 Recordset，请使用 adOpenStatic 枚举值：

Recordset.Open ,,adOpenStatic
还被引用为“枚举常量”。请参阅常量。

返回顶部

事件

由对象识别的操作，可以针对它编写响应的代码。事件可以由其他操作中的命令执行、事务完成、记录集定位和数据更新生成。请参阅事件处理程序。

返回顶部

事件处理程序

事件处理程序是当事件发生时执行的代码。请参阅事件。

返回顶部

处理程序

管理命令及相对简单的情况或操作的例程，例如错误恢复或数据管理。

返回顶部

分级 Recordset

包含另一个 Recordset 的 Recordset。请参阅数据构形和子集。
有关详细信息，请参阅访问分级 Recordset 中的行。

返回顶部

分级结构

通常，分级结构是一个包含顶级别和从属级别的等级化结构。在 ADO 中，分级 Recordset 用于表示记录和子集之间的父子关系。同样在 ADO 中，Record 和 Stream 对象可用于访问分级树结构（如文件夹和文档）。ADO MD 还包括 Hierarchy 对象，表示 OLAP 立方中维的各个级别之间的关系。请参阅分级 Recordset、父子关系、子集和树。

返回顶部

ISAPI（Internet 服务器应用程序编程接口）

Internet 服务器的一组函数，例如运行 Microsoft Internet Information Services (IIS) 的 Windows NT Server/Windows 2000 Server。

返回顶部

键

表中的一列或多列，唯一标识某行。通常用于建立表的索引。

返回顶部

调度

跨越线程或进程边界将接口方法参数打包、发送和拆包的过程。

返回顶部

中间层

分布式系统中用户接口或 Web 客户端与数据库之间的逻辑层。通常，业务对象在中间层进行实例化。中间层是生成并操作接收信息的业务规则和函数的集合。它们通过业务规则（可以频繁更改）完成此任务，并由此被封装到物理上独立于应用程序逻辑本身的组件中。也称为“应用程序服务器层”。请参阅分布式应用程序、客户端层和数据源层。

返回顶部

MIME（多用途 Internet 邮件扩展）

Internet 协议，最初开发用于允许使用不同网络、计算机和电子邮件环境上的丰富内容来进行电子邮件消息交换。实际上，非邮件应用程序也采用 MIME 并加以发展。
MIME 是允许在 Internet 上发布和读取二进制数据的标准。带二进制数据的文件的文件头包含 MIME 类型数据，这将通知客户端程序（例如 Web 浏览器和邮件软件包）需要按与处理纯文本不同的方式来处理该数据。例如，包含 JPEG 图形的 Web 文档的文件头包含 JPEG 文件格式特有的 MIME 类型。这允许浏览器用其 JPEG 查看程序（如果有的话）来显示该文件。

返回顶部

节点

分级树结构中的元素。节点可能是根，或者另一个节点的子。节点还可以是多个子的父。请参阅分级结构、树、根、子和父。

返回顶部

对象变量

包含对象引用的变量。例如，objCustomObject 是指向 CustomObject 类型对象的变量：

Set objCustomObject = CreateObject(adodb.Recordset)

返回顶部

ODBC（开放式数据库互连）

用于连接到各种不同数据源的标准编程语言接口。一般通过控制面板对它进行访问，在控制面板中可指定数据源名称 (DSN) 以使用特定的 ODBC 驱动程序。

返回顶部

OLE DB

一组接口，显示使用 COM 的不同的源中的数据。OLE DB 接口向应用程序提供对存储在不同信息源中的数据统一访问的方式。这些接口支持适于数据源的 DBMS 功能的数量，使它能够共享数据源中的数据。请参阅 COM。

返回顶部

开放式锁定

一种锁定类型，在这种锁定类型下，包含正在编辑的记录的数据页仅在通过 Update 方法更新记录时被锁定，不能被其他用户使用，但在调用 Update 之前和之后均可用。
如果打开 Recordset 对象时，其 LockType 参数或属性设置为 adLockOptimistic 或 adLockBatchOptimistic，那么将使用开放式锁定。请参阅保守式锁定。

返回顶部

序号值

某项目在序列内用数字表示的位置。在 ADO 集合中，第一个项目的序号值为零 (0)。下一个项目的序号值为一 (1)，依次类推。

返回顶部

参数化命令

允许用户在执行命令前设置参数值的查询或命令。例如，可以通过在 SQL 字符串中嵌入参数标记（由“?”标明）来对 SQL 字符串进行参数化。然后应用程序为每个参数指定值并且执行该命令。

返回顶部

父

分级关系的控制端。在分级结构中，父下面直接包含一个或多个子节点。请参阅父别名、父子关系和子。

返回顶部

父别名

引用父的别名。请参阅别名和父。

返回顶部

父子关系

分级结构中的关系，在分级结构中父是一个较高的级别，它直接与一个或多个子相关联。子是较低的级别，它必须有一个父。请参阅父和子。

返回顶部

持久

以持久状态保存数据，例如将 Recordset 保存到文件。

返回顶部

保守式锁定

一种锁定类型，在这种锁定类型下，包含正在编辑的记录的页不能被其他用户使用，以确保更新的进行。保守式锁定行为由 OLE DB 提供者定义。通常，在 Update 方法完成前，编辑时记录均被锁定并且不可用。
如果打开 Recordset 对象时，LockType 参数或属性设置为 adLockPessimistic，那么将启用保守式锁定。请参阅开放式锁定。

返回顶部

缓冲池

基于使用预分配资源（例如对象或数据库连接）的集合的性能优化方式。从缓冲池中抽取现有资源比创建新资源效率更高。

返回顶部

ProgID（编程标识符）

由 COM 应用程序映射到 Windows 注册表的唯一名称。ADO Connection 的 ProgID 是“ADODB.Connection”。请参阅 CLSID、COM。

返回顶部

代理

接口特有的对象，它提供客户端所需的参数调度和通讯，以调用在不同执行环境（例如不同的线程或另一个进程）下运行的应用程序对象。代理与客户位于同一处并与对应的通讯模块进行通讯，该通讯模块与正在调用的应用程序对象位于同一处。请参阅通讯模块。

返回顶部

相对 URL

部分确定的 URL，它指定 Internet 或 Intranet 上的资源，其位置与绝对 URL 或等价 ADO Connection 对象指定的起点有关。实际上，绝对和相对 URL 连接组成一个完整的 URL。请参阅 URL 和绝对 URL。

返回顶部

远程数据源

位于另一台计算机而非本地系统（运行客户端应用程序）上的数据源。

返回顶部

资源记录

文档源提供者中的记录，包含定义和说明文件夹或文档的字段。文档本身不包含在资源记录中，但是通常可以通过默认流或包含 URL 的资源记录中的字段进行访问。请参阅文档源提供者、默认流和 URL。

返回顶部

根

分级树结构中的最高级别。根节点没有父，但可能有子。请参阅分级结构、树、父和子。

返回顶部

行集合

数据源中所有具有相同字段模式的行的集合。行集合可以表示表中全部或部分字段。也可以表示由查询或两个（或更多）表的联接所创建的虚拟表。在 ADO 中，行集合由 Recordset 对象表示。

返回顶部

模式

对数据库管理系统 (DBMS) 的数据库的说明，通常由 DBMS 提供的数据定义语言生成。模式定义了数据库的属性，如表、列和属性。

返回顶部

范围

对象、变量或视图（或表）中一组记录的引用范围。例如，只可在定义本地变量的过程中引用它们。在应用程序中的任何地方均可访问公共变量。如果对象（如当前数据库）位于已定义的查找路径中，那么它们将在范围内。记录范围可通过许多命令中的 Scope 子句指定。

返回顶部

服务提供者

通过产生和消费数据来封装服务的软件，由此可增加 ADO 应用程序的功能。提供者并不直接显露数据，而是提供服务，例如处理查询。服务提供者可以处理由数据提供者提供的数据。请参阅数据提供者。

返回顶部

成形 Recordset

一种 Recordset，它的列经过专门定义，使得它不仅包含数据，还包含对其他 Recordset 对象和/或基于其他 Recordset 对象的计算值的引用（称作子集）。

返回顶部

兄弟

分级结构中任意两个或多个节点，它们位于分级结构中的同一级别上。分级结构的根节点没有兄弟。

返回顶部

存储过程

代码的预编译集合，例如以某名称存储并被作为单元进行处理的 SQL 语句和可选的流控制语句。存储过程保存在数据库中。可以通过应用程序的调用来执行这些存储过程。它们还允许使用用户声明的变量、条件操作和其他有效编程功能。

返回顶部

通讯模块

接口特有的对象，提供应用程序对象所需的参数调度和通讯，接受运行于不同执行环境（例如不同的线程或另一个进程）下的客户端对它的调用。通讯模块与应用程序对象位于同一位置并与对应的代理进行通讯，该代理与调用它的客户端位于同一位置。请参阅代理。

返回顶部

子节点

请参阅子。

返回顶部

同步操作

由代码启动并在下一个操作开始之前完成的操作。请参阅异步操作。

返回顶部

树

表示元素（节点）间分级关系的结构。树的最高级别（根）位置上有一个节点。根下面可以有多个子。每个子可以依次为其他子的父，如此形成树状分支。包含文档和其他文件夹的文件夹即是树结构的典型范例。请参阅分级结构、节点、根、子和父。

返回顶部

URL（统一资源定位符）

指定 Internet 或 Intranet 上资源的位置。一个完整的 URL 由模式（例如 FTP、HTTP、mailto、file 等）、冒号、服务器名称和完整的资源路径（例如文档、图形或其他文件）组成。部分 URL 范例如下：

http://www.domain.com/default.html
ftp://ftp.server.somewhere/ftp.file
file://Server/Share/File.doc
请参阅绝对 URL 和相对 URL。

返回顶部

Web 服务器

向 Intranet 和 Internet 用户提供 Web 服务和 Web 页的计算机。

返回顶部


ADO 程序员参考

本部分 ADO 文档包含 ADO、RDS、ADO MD 和 ADOX 的参考主题。

  • ADO API 参考
  • RDS API 参考
  • ADO MD API 参考
  • ADOX API 参考


ADO API 参考

ADO 文档的这一节包含每个 ADO 对象、集合、属性、动态属性、方法、事件和枚举的主题。此外，它还包含一个在 Microsoft Visual C++ 和 Windows Foundation Classes (WFC) 中使用的 ADO 语法索引的列表。

有关详细信息，请在索引中搜索特定主题或参阅下面的主题：

  • ADO 对象模型
  • ADO 对象
  • ADO 集合
  • ADO 属性
  • ADO 动态属性
  • ADO 方法
  • ADO 事件
  • ADO 枚举常量
  • ADO 语法索引

请参阅

附录 D：ADO 范例 | 配置 RDS | ActiveX Data Objects 开始页 | 附录 C：ADO 编程 | 附录 A：提供者 | ADO 的新增内容


ADO 对象模型

下面的图表显示 ADO 对象及其集合。单击一个对象或集合以获取详细信息。

请参阅

ADO 集合 | ADO 动态属性 | ADO 枚举常量 | 附录 B：ADO 错误 | ADO 事件 | ADO 方法 | ADO 对象 | ADO 属性


ADO 对象和接口

这些对象之间的关系表示在 ADO 对象模型中。

每个对象都可以包含在对应的集合中。例如，Error 对象可包含在 Errors 集合中。有关详细信息，请参阅 ADO 集合或特定集合的主题。

ADORecordConstruction | 在 C/C++ 应用程序的 OLE DB Row 对象中构造 ADO Record 对象。
ADORecordsetConstruction | 在 C/C++ 应用程序的 OLE DB Rowset 对象中构造 ADO Recordset 对象。
Error | 包含有关数据访问错误的详细信息，这些错误与涉及提供者的单个操作有关。
Field | 表示公共数据类型的数据列。
Parameter | 表示与基于参数化查询或存储过程的 Command 对象相关联的参数。
Property | 表示由提供者定义的 ADO 对象的动态特性。
Record | 表示 Recordset 的行，或者文件系统中的目录或文件。
Recordset | 表示基本表或命令执行结果的记录全集。任何时候 Recordset 都只将集合中的单个记录作为当前记录引用。
Stream | 表示数据的二进制流。

请参阅

ADO API 参考 | ADO 集合 | ADO 动态属性 | ADO 枚举常量 | 附录 B：ADO 错误 | ADO 事件 | ADO 方法 | ADO 对象模型 | ADO 属性


ADORecordConstruction 接口 (ADO)

ADO 2.5 API 参考

ADORecordConstruction 接口

ADORecordConstruction 接口用于在 C/C++ 应用程序中从 OLE DB Row 对象构造 ADO Record 对象。

此接口支持下列属性：

属性

ParentRow | 只写。 在此 ADO Record 对象上设置 OLE DB Row 对象的容器。
Row | 读/写。 在此 ADO Record 对象上设置 OLE DB Row 对象，或从此 ADO Record 对象上获取 OLE DB Row 对象。

方法

无。

事件

无。

说明

如果给出一个 OLE DB Row 对象 (pRow)，则 ADO Record 对象 (adoR) 的构造可以归结为以下三个基本操作：

  1. 创建 ADO Record 对象：
    _RecordPtr adoR;
adoRs.CreateInstance(__uuidof(_Record));
  2. 在 Record 对象上查询 IADORecordConstruction 接口：
    adoRecordConstructionPtr adoRConstruct=NULL;
adoR->QueryInterface(__uuidof(ADORecordConstruction),
                    (void**)&adoRConstruct);
  3. 调用 IADORecordConstruction::put_Row 属性方法在 ADO Record 对象上设置 OLE DB Row 对象：
    IUnknown *pUnk=NULL;
pRow->QueryInterface(IID_IUnknown, (void**)&pUnk);
adoRConstruct->put_Row(pUnk);

所得到的 adoR 对象当前表示从 OLE DB Row 对象构造的 ADO Record 对象。

也可以从 OLE DB Row 对象的容器构造 ADO Record 对象。

需求

版本：ADO 2.0 及更高版本

库：msado15.dll

UUID：00000567-0000-0010-8000-00AA006D2EA4


ADORecordsetConstruction 接口 (ADO)

ADO 2.5 API 参考

ADORecordsetConstruction 接口

ADORecordsetConstruction 接口用于在 C/C++ 应用程序中从 OLE DB Rowset 对象构造 ADO Recordset 对象。

此接口支持下列属性：

属性

Chapter | 读/写。 在此 ADO Recordset 对象上设置 OLE DB Chapter 对象，或从此 ADO Recordset 对象上获取 OLE DB Chapter 对象。
RowPosition | 读/写。 在此 ADO Recordset 对象上设置 OLE DB RowPosition 对象，或从此 ADO Recordset 对象上获取 OLE DB RowPosition 对象。
Rowset | 读/写。 在此 ADO Recordset 对象上设置 OLE DB Rowset 对象，或从此 ADO Recordset 对象上获取 OLE DB Rowset 对象。

方法

无。

事件

无。

说明

如果给出一个 OLE DB Rowset 对象 (pRowset)，那么 ADO Recordset 对象 (adoRs) 的构造可以归结为以下三个基本操作：

  1. 创建 ADO Recordset 对象：
    Recordset20Ptr adoRs;
adoRs.CreateInstance(__uuidof(Recordset));
  2. 在 Recordset 对象上查询 IADORecordsetConstruction 接口：
    adoRecordsetConstructionPtr adoRsConstruct=NULL;
adoRs->QueryInterface(__uuidof(ADORecordsetConstruction),
                     (void**)&adoRsConstruct);
  3. 调用 IADORecordsetConstruction::put_Rowset 属性方法在 ADO Recordset 对象上设置 OLE DB Rowset 对象：
    IUnknown *pUnk=NULL;
pRowset->QueryInterface(IID_IUnknown, (void**)&pUnk);
adoRsConstruct->put_Rowset(pUnk);

所得到的 adoRs 对象当前表示从 OLE DB Rowset 对象构造的 ADO Recordset 对象。

还可以从 OLE DB Chapter 或 RowPosition 对象构造 ADO Recordset 对象。

需求

版本：ADO 2.0 及更高版本

库：msado15.dll

UUID：00000283-0000-0010-8000-00AA006D2EA4

请参阅

Recordset 对象 | Rowset 属性


Command 对象 (ADO)

ADO 2.5 API 参考

Command 对象

定义要对数据源执行的特定命令。

说明

使用 Command 对象查询数据库并返回 Recordset 对象中的记录，以便执行大量操作或对数据库结构进行操作。在引用某些 Command 集合、方法或属性时可能会产生错误，这取决于提供者的功能。

用 Command 对象的集合、方法和属性可以执行下列操作：

  • 用 CommandText 属性定义命令（例如 SQL 语句）的可执行文本。
  • 用 Parameter 对象和 Parameters 集合定义参数化查询或存储过程参数。
  • 在适当时候，用 Execute 方法执行命令并返回 Recordset 对象。
  • 执行前用 CommandType 属性指定命令类型以优化性能。
  • 用 Prepared 属性控制执行前提供者是否保存准备好（或编译过）的命令版本。
  • 用 CommandTimeout 属性设置提供者等待命令执行的秒数。
  • 通过设置 ActiveConnection 属性使打开的连接与 Command 对象相关联。
  • 设置 Name 属性以便将 Command 对象标识为与之关联的 Connection 对象的方法。
  • 将 Command 对象传递给 Recordset 的 Source 属性以获取数据。
  • 使用 Properties 集合访问提供者特有的属性。
注意 要在不使用 Command 对象的情况下执行查询，请将查询字符串传递给 Connection 对象的 Execute 方法，或者传递给 Recordset 对象的 Open 方法。但是，当要持久保留并重新执行命令文本，或者要使用查询参数时，需要使用 Command 对象。

若要为先前定义的 Connection 对象单独创建一个 Command 对象，请将其 ActiveConnection 属性设置为有效的连接字符串。ADO 仍然创建 Connection 对象，但不将该对象分配给对象变量。不过，如果正在将多个 Command 对象与同一个连接相关联，则应显式地创建和打开 Connection 对象，这样就将 Connection 对象分配给一个对象变量。如果未将 Command 对象的 ActiveConnection 属性设置为此对象变量，即使使用同一个连接字符串，ADO 也将为每个 Command 对象创建一个新的 Connection 对象。

若要执行 Command，只需在相关联的 Connection 对象上通过 Name 属性调用 Command。必须将 Command 的 ActiveConnection 属性设置为 Connection 对象。如果 Command 有参数，请将其值作为参数传递给该方法。

如果在同一个连接上执行两个或多个 Command 对象，并且每个 Command 对象都是一个带输出参数的存储过程，将产生错误。若要执行每个 Command 对象，请使用单独连接或断开所有其他 Command 对象的连接。

Parameters 集合是 Command 对象的默认成员。因此，下列两个代码语句是等价的。

objCmd.Parameters.Item(0)
objCmd(0)

请参阅

Command 对象属性、方法和事件 | Connection 对象 | Parameters 集合 | Properties 集合 | 附录 A：提供者

© 1998-2002 Microsoft Corporation。保留所有权利。


属性、方法和事件

ADO 2.5 API 参考

Command 对象属性、方法和事件

属性/集合

ActiveConnection 属性

CommandText 属性

CommandTimeout 属性

CommandType 属性

Name 属性

Parameters 集合

Prepared 属性

Properties 集合

State 属性

方法

Cancel 方法

CreateParameter 方法

Execute 方法 (ADO Command)

事件

无。

请参阅

Command 对象

© 1998-2002 Microsoft Corporation。保留所有权利。


Connection 对象 (ADO)

ADO 2.5 API 参考

Connection 对象

表示到数据源的打开的连接。

说明

Connection 对象表示数据源的唯一会话。在使用客户端/服务器数据库系统的情况下，该对象可以等价于到服务器的实际网络连接。Connection 对象的某些集合、方法或属性可能无效，这取决于提供者支持的功能。

用 Connection 对象的集合、方法和属性可以执行下列操作：

  • 在打开连接前用 ConnectionString、ConnectionTimeout 和 Mode 属性配置连接。ConnectionString 是 Connection 对象的默认属性。
  • 将 CursorLocation 属性设置为客户端以调用支持批更新的 Microsoft Cursor Service for OLE DB。
  • 用 DefaultDatabase 属性设置连接的默认数据库。
  • 用 IsolationLevel 属性为在连接上打开的事务设置隔离级别。
  • 用 Provider 属性指定 OLE DB 提供者。
  • 用 Open 方法建立到数据源的物理连接，然后用 Close 方法断开连接。
  • 用 Execute 方法在连接上执行命令，用 CommandTimeout 属性配置命令的执行。
    注意 要在不使用 Command 对象的情况下执行查询，请将查询字符串传递给 Connection 对象的 Execute 方法。但是，当要持久保留并重新执行命令文本，或者要使用查询参数时，需要使用 Command 对象。
  • 用 BeginTrans、CommitTrans 和 RollbackTrans 方法和 Attributes 属性在打开的连接上管理事务，包括嵌套的事务（如果提供者支持）。
  • 用 Errors 集合检查从数据源返回的错误。
  • 用 Version 属性从 ADO 中读取使用的版本。
  • 用 OpenSchema 方法获取关于数据库的模式信息。

可以独立于先前定义的任何其他对象来创建 Connection 对象。

可以将命令或存储过程作为 Connection 对象的原生方法来执行，如下例所示。

将命令作为 Connection 对象的原生方法执行

若要执行命令，请用 Command 对象的 Name 属性指定命令的名称。将 Command 对象的 ActiveConnection 属性设置为连接。然后，在使用命令名称处发出一个语句（将其作为 Connection 对象的一个方法），后面可跟随任何参数，接着再跟随 Recordset 对象（如果返回了任何行）。设置 Recordset 属性以自定义产生的 Recordset。例如：

Dim cnn As New ADODB.Connection
Dim cmd As New ADODB.Command
Dim rst As New ADODB.Recordset
...
cnn.Open "..."
cmd.Name = "yourCommandName"
cmd.ActiveConnection = cnn
...
'Your command name, any parameters, and an optional Recordset.
cnn.yourCommandName "parameter", rst

将存储过程作为 Connection 对象的原生方法执行

要执行存储过程，请在使用存储过程名称处发出一个语句（将其作为 Connection 对象的一个方法），后面可跟随任何参数。ADO 将对参数类型作出“最佳判断”。例如：

Dim cnn As New ADODB.Connection
...
'Your stored procedure name and any parameters.
cnn.sp_yourStoredProcedureName "parameter"

请参阅

Connection 对象属性、方法和事件 | Command 对象 | Errors 集合 | Properties 集合 | Recordset 对象 | 附录 A：提供者

© 1998-2002 Microsoft Corporation。保留所有权利。


属性、方法和事件

ADO 2.5 API 参考

Connection 对象属性、方法和事件

属性/集合

Attributes 属性

CommandTimeout 属性

ConnectionString 属性

ConnectionTimeout 属性

CursorLocation 属性

DefaultDatabase 属性

Errors 集合

IsolationLevel 属性

Mode 属性

Properties 集合

Provider 属性

State 属性

Version 属性

方法

BeginTrans、CommitTrans 和 RollbackTrans 方法

Cancel 方法

Close 方法

Execute 方法 (ADO Connection)

Open 方法 (ADO Connection)

OpenSchema 方法

事件

BeginTransComplete、CommitTransComplete 和 RollbackTransComplete 事件

ConnectComplete 和 Disconnect 事件

ExecuteComplete 事件

InfoMessage 事件

WillConnect 事件

WillExecute 事件

请参阅

Connection 对象


Error 对象 (ADO)

ADO 2.5 API 参考

Error 对象

包含有关数据访问错误的详细信息，这些错误与涉及提供者的单个操作有关。

说明

任何涉及 ADO 对象的操作都可能产生一个或多个提供者错误。随着每个错误的发生，一个或多个 Error 对象被放在 Connection 对象的 Errors 集合中。当另一个 ADO 操作产生错误时，Errors 集合被清空，新的 Error 对象集被放在 Errors 集合中。

注意 每个 Error 对象都表示一个特定的提供者错误，而不是 ADO 错误。ADO 错误被记录到运行时例外处理机制中。例如，在 Microsoft Visual Basic 中，发生 ADO 特有的错误将引发 On Error 事件，并且出现在 Error 对象中。关于 ADO 错误的完整列表，请参阅 ErrorValueEnum 主题。

可以读取 Error 对象的属性以获取关于每个错误的特定细节，包括以下内容：

  • Description 属性，包含错误的文本。这是默认的属性。
  • Number 属性，包含错误常量的 Long 整数值。
  • Source 属性，标识产生错误的对象。在向数据源发出请求后，如果 Errors 集合中有多个 Error 对象，那么该属性将非常有用。
  • SQLState 和 NativeError 属性，提供来自 SQL 数据源的信息。

当发生提供者错误时，它被放在 Connection 对象的 Errors 集合中。ADO 支持通过单个 ADO 操作返回多个错误，以允许提供者特有的错误信息。若要在错误处理程序中获取更多此类错误信息，请使用相应的语言或所在工作环境下的错误捕获功能，然后使用嵌套的循环来枚举 Errors 集合中每一个 Error 对象的属性。

Microsoft Visual Basic 和 VBScript 用户 如果没有有效的 Connection 对象，则需要从 Error 对象中检索错误信息。

与提供者的操作一样，ADO 在进行可能产生新提供者错误的调用前将清空 OLE Error Info 对象。但是，只有当提供者产生新的错误或者调用 Clear 方法时，才能清空并预置 Connection 对象的 Errors 集合。

某些属性和方法返回警告，这些警告显示为 Errors 集合中的 Error 对象，但并不终止程序的执行。请先调用 Errors 集合的 Clear 方法，然后再调用 Recordset 对象的 Resync、UpdateBatch 或 CancelBatch 方法，调用 Connection 对象的 Open 方法，或设置 Recordset 对象的 Filter 属性。这样，就可以读取 Errors 集合的 Count 属性以测试返回的警告。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Error 对象属性、方法和事件 | Connection 对象 | Errors 集合 | Appendix A: Providers


属性、方法和事件

ADO 2.5 API 参考

Error 对象属性、方法和事件

属性

Description 属性

HelpContext 和 HelpFile 属性

NativeError 属性

Number 属性

Source 属性 (ADO Error)

SQLState 属性

方法

无。

事件

无。

请参阅

Error 对象


Field 对象 (ADO)

ADO 2.5 API 参考

Field 对象

表示公共数据类型的数据列。

说明

每个 Field 对象都对应于 Recordset 中的一列。使用 Field 对象的 Value 属性来设置或返回当前记录的数据。Field 对象的某些集合、方法或属性可能不可用，这取决于提供者提供的功能。

用 Field 对象的集合、方法和属性可以执行下列操作：

  • 用 Name 属性返回字段名。
  • 用 Value 属性查看或更改字段中的数据。Value 为 Field 对象的默认属性。
  • 用 Type、Precision 和 NumericScale 属性返回字段的基本特性。
  • 用 DefinedSize 属性返回已声明的字段大小。
  • 用 ActualSize 属性返回给定字段中的数据的实际大小。
  • 用 Attributes 属性和 Properties 集合确定给定字段支持的功能类型。
  • 用 AppendChunk 和 GetChunk 方法对包含长二进制或长字符数据的字段值进行操作。
  • 如果提供者支持批更新，请用 OriginalValue 和 UnderlyingValue 属性在批更新过程中解决字段值之间的差异。

在打开 Field 对象的 Recordset 之前，所有元数据属性（Name、Type、DefinedSize、Precision 和 NumericScale）都有效。此时对它们进行设置将有助于动态构造格式。

请参阅

Field 对象属性、方法和事件 | Fields 集合 | Properties 集合 | Recordset 对象


属性、方法和事件

ADO 2.5 API 参考

Field 对象属性、方法和事件

属性/集合

ActualSize 属性

Attributes 属性

DefinedSize 属性

Name 属性

NumericScale 属性

OriginalValue 属性

Precision 属性

Properties 集合

Status 属性 (ADO Field)

Type 属性

UnderlyingValue 属性

Value 属性

方法

AppendChunk 方法

GetChunk 方法

事件

无。

请参阅

Field 对象


Parameter 对象 (ADO)

ADO 2.5 API 参考

Parameter 对象

表示与基于参数化查询或存储过程的 Command 对象相关联的参数。

说明

许多提供者均支持参数化命令。所需操作在这些命令中只定义一次，但可以用变量（或参数）来改变命令的某些细节。例如，SQL SELECT 语句可以用一个参数定义 WHERE 子句的匹配标准，而用另一个参数定义 SORT BY 子句的列名称。

Parameter 对象表示与参数化查询相关联的参数，或表示输入/输出参数和存储过程的返回值。Parameter 对象的某些集合、方法或属性可能不可用，这取决于提供者的功能。

用 Parameter 对象的集合、方法和属性可以执行下列操作：

  • 用 Name 属性设置或返回参数的名称。
  • 用 Value 属性设置或返回参数的值。Value 为 Parameter 对象的默认属性。
  • 用 Attributes、Direction、Precision、NumericScale、Size 和 Type 属性设置或返回参数特性。
  • 用 AppendChunk 方法将长二进制或字符数据传递给参数。
  • 使用 Properties 集合访问提供者特有的属性。

如果知道与要调用的存储过程或参数化查询相关联的参数的名称和属性，就可以用 CreateParameter 方法来创建具有适当属性设置的 Parameter 对象，并用 Append 方法将它们添加到 Parameters 集合中。这样便可以设置并返回参数值，而不必对 Parameters 集合调用 Refresh 方法检索来自提供者的参数信息，从而避免了潜在的资源密集型操作。

请参阅

Parameter 对象属性、方法和事件 | Command 对象 | CreateParameter 方法 | Parameters 集合 | Properties 集合


属性、方法和事件

ADO 2.5 API 参考

Parameter 对象属性、方法和事件

属性/集合

Attributes 属性

Direction 属性

Name 属性

NumericScale 属性

Precision 属性

Properties 集合

Size 属性

Type 属性

Value 属性

方法

AppendChunk 方法

事件

无。

请参阅

Parameter 对象


Property 对象 (ADO)

ADO 2.5 API 参考

Property 对象

表示由提供者定义的 ADO 对象的动态特性。

说明

ADO 对象有两种类型的属性：内置属性和动态属性。

内置属性是在 ADO 中实现的属性，任何新对象都可以用 MyObject.Property 语法立即访问这些属性。在对象的 Properties 集合中，它们并不显示为 Property 对象。因此，尽管可以更改它们的值，但却不能修改它们的特性。

动态属性由基本数据提供者定义，并显示在适当的 ADO 对象的 Properties 集合中。例如，提供者特有的属性可能会指示 Recordset 对象是支持事务还是支持更新。这些附加属性在该 Recordset 对象的 Properties 集合中将显示为 Property 对象。只有通过该集合使用 MyObject.Properties(0) 或 MyObject.Properties("Name") 语法才能引用动态属性。

这两种属性都无法删除。

动态 Property 对象自身有四个内置属性：

  • Name 属性是一个用于标识属性的字符串。
  • Type 属性是一个用于指定属性数据类型的整数。
  • Value 属性是一个包含属性设置的变体。Value 是 Property 对象的默认属性。
  • Attributes 属性是一个 Long 值，用于指示提供者特有的属性特性。

请参阅

Property 对象属性、方法和事件 | Command 对象 | Connection 对象 | Field 对象 | Properties 集合 | Recordset 对象


属性、方法和事件

ADO 2.5 API 参考

Property 对象属性、方法和事件

属性

Attributes 属性

Name 属性

Type 属性

Value 属性

方法

无。

事件

无。

请参阅

Property 对象


Record 对象 (ADO)

ADO 2.5 API 参考

Record 对象

表示 Recordset 或数据提供者中的行，或者半结构化数据提供者返回的对象，如文件或目录。

说明

Record 对象表示一行数据，与单行 Recordset 具有一些概念上的类似之处。根据提供者的能力不同，可以直接从提供者（而不是从单行 Recordset）返回 Record 对象，例如，执行仅选择了一行的 SQL 查询时。或者，可以直接从 Recordset 对象获得 Record 对象。或者，可以直接从半结构化数据提供者返回 Record，如 Microsoft Exchange OLE DB Provider。

通过 Record 对象上的 Fields 集合，可以查看与 Record 对象相关联的字段。ADO 允许值为对象的列，包括 Recordset、SafeArray 和 Record 对象的 Fields 集合中的标量值。

如果 Record 对象表示 Recordset 中的行，那么它有可能使用 Source 属性返回原来的 Recordset。

半结构化数据提供者（如 Microsoft OLE DB Provider for Internet Publishing）还可以使用 Record 对象模仿树状结构的名称空间。树上的每一个节点都是一个具有相关列的 Record 对象。这些列可以表示该节点的属性和其他相关信息。在该树状结构中，Record 对象既可以表示叶节点也可表示非叶节点。非叶节点可将其他节点作为内容，而叶节点没有这样的内容。通常，叶节点包含数据的二进制流，而非叶节点也可能有与其相关联的默认二进制流。Record 对象的属性标识节点的类型。

Record 对象还表示用于定位分级结构数据的替换方法。可以创建一个 Record 对象来表示大的树状结构中特定子树的根。可以打开新的 Record 对象，用它们表示子节点。

资源（例如，文件或目录）可以由绝对 URL 唯一标识。当用绝对 URL 打开 Record 时，将显式地创建 Connection 对象并将其设置为 Record 对象。通过 ActiveConnection 属性可以将 Connection 对象显式设置为 Record 对象。可通过 Connection 对象访问的文件和目录定义可在其中发生 Record 操作的“上下文”。

Record 对象上的数据修改和定位方法还接受相对 URL，它使用绝对 URL 或 Connection 对象上下文为起点定位资源。

注意 使用 http 模式的 URL 将自动调用 Microsoft OLE DB Provider for Internet Publishing。有关详细信息，请参阅绝对和相对 URL。

Connection 对象与每一个 Record 对象相关联。因此，通过调用 Connection 对象事务方法，可将 Record 对象操作看作事务的一部分。

Record 对象不支持 ADO 事件，因此不响应通知。

用 Record 对象的方法和属性可以执行下列操作：

  • 用 ActiveConnection 属性设置或返回相关联的 Connection 对象。
  • 用 Mode 属性指示访问权限。
  • 用 ParentURL 属性返回目录的 URL（如果有），该目录中包含 Record 表示的资源。
  • 用 Source 属性指示绝对 URL、相对 URL 或可从中导出 Record 的 Recordset。
  • 用 State 属性指示 Record 的当前状态。
  • 用 RecordType 属性指示 Record 的类型 —简单文档、集合文档 或 结构化文档。
  • 用 Cancel 方法终止执行异步操作。
  • 用 Close 方法断开 Record 与数据源的关联。
  • 用 CopyRecord 方法将 Record 表示的文件或目录复制到另一位置。
  • 用 DeleteRecord 方法删除 Record 表示的文件或目录（及其子目录）。
  • 用 GetChildren 方法打开包含行的 Recordset，这些行表示项目的子目录和文件，项目由 Record 表示。
  • 用 MoveRecord 方法将由 Record 表示的文件或目录（及其子目录）移动到另一位置，或者将其重命名。
  • 用 Open 方法将 Record 与现有的数据源相关联，或者创建一个新文件或目录。

请参阅

Visual Basic 范例 | Visual Basic 范例

Record 对象属性、方法和事件 | Fields 集合 | Properties 集合 | Chapter 10: Records and Streams | Recordset 对象


属性、方法和事件

ADO 2.5 API 参考

Record 对象属性、方法和事件

属性/集合

ActiveConnection 属性

Fields 集合

Mode 属性

ParentURL 属性

Properties 集合

RecordType 属性

Source 属性 (ADO Record)

State 属性

方法

Cancel 方法

Close 方法

CopyRecord 方法

DeleteRecord 方法

GetChildren 方法

MoveRecord 方法

Open 方法 (ADO Record)

事件

无。

请参阅

Record 对象


Recordset 对象 (ADO)

ADO 2.5 API 参考

Recordset 对象

表示基本表或命令执行结果的记录全集。任何时候 Recordset 都只将集合中的单个记录作为当前记录引用。

说明

用 Recordset 对象对来自提供者的数据进行操作。使用 ADO 时，将几乎全部使用 Recordset 对象来对数据进行操作。所有 Recordset 对象均由记录（行）和字段（列）组成。某些 Recordset 方法或属性可能不可用，这取决于提供者支持的功能。

ADODB.Recordset 是 ProgID，应当用它来创建 Recordset 对象。引用过期的 ADOR.Recordset ProgID 的现有应用程序将继续工作而无需重新编译，但新开发的应用程序应引用 ADODB.Recordset。

ADO 中定义了四种不同的游标类型：

  • 动态游标 — 用于查看其他用户所做的添加、更改和删除；用于 Recordset（不依赖于书签）中的所有移动类型；如果提供者支持，还可用于书签。
  • 键集游标 — 其行为类似动态游标，不同的只是它禁止查看其他用户添加的记录，并且禁止访问其他用户删除的记录。其他用户所做的数据更改依然可见。它始终支持书签，因此允许 Recordset 中的所有移动类型。
  • 静态游标 — 提供记录集的静态副本，可用来查找数据或生成报告；它始终支持书签，因此允许 Recordset 中的所有移动类型。其他用户所做的添加、更改或删除将不可见。当打开客户端 Recordset 对象时，这是唯一允许的游标类型。
  • 仅向前游标 — 只允许在 Recordset 中向前滚动。其他用户所做的添加、更改或删除将不可见。当只需要对 Recordset 进行一次传递时，可以提高性能。

打开 Recordset 之前请先设置 CursorType 属性以选择游标类型，或者用 Open 方法传递 CursorType 参数。某些提供者并不支持所有类型的游标。请检查提供者的文档。如果未指定游标类型，ADO 将默认打开仅向前游标。

如果将 CursorLocation 属性设置为 adUseClient 以打开 Recordset，则 Field 对象的 UnderlyingValue 属性在返回的 Recordset 对象中将不可用。如果与某些提供者（如 Microsoft ODBC Provider for OLE DB 和 Microsoft SQL Server）配合使用，便可用 Open 方法传递连接字符串来单独创建先前定义的 Connection 对象的 Recordset 对象。ADO 仍然创建 Connection 对象，但不将该对象分配给对象变量。但是，如果正在通过同一个连接打开多个 Recordset 对象，应显式地创建和打开 Connection 对象，由此将 Connection 对象分配给对象变量。如果打开 Recordset 对象时未使用此对象变量，那么即使传递同一个连接字符串，ADO 也将为每个新的 Recordset 创建一个新的 Connection 对象。

可以根据需要创建任意多个 Recordset 对象。

当打开 Recordset 时，当前记录位于第一个记录（如果有），BOF 和 EOF 属性设置为 False。如果没有记录，BOF 和 EOF 属性被设置为 True。

假定提供者支持相关的功能，则可以使用 MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法，Move 方法，以及 AbsolutePosition、AbsolutePage 和 Filter 属性来重新定位当前记录。仅向前的 Recordset 对象只支持 MoveNext 方法。当使用 Move 方法访问每个记录（或枚举 Recordset）时，可以使用 BOF 和 EOF 属性来确定移动是否已经超出了 Recordset 的开始或结尾。

Recordset 对象支持两种类型的更新：立即更新和批更新。使用立即更新时，一旦调用 Update 方法，对数据所做的所有更改便被立即写入基本数据源。也可以用 AddNew 和 Update 方法将值的数组作为参数传递，同时更新记录中的多个字段。

如果提供者支持批更新，可以让提供者把对多个记录所做的更改存入缓存，然后用 UpdateBatch 方法在单个调用中将它们传送到数据库。这种情况适用于用 AddNew、Update 和 Delete 方法进行的更改。调用 UpdateBatch 方法之后，可以用 Status 属性检查数据冲突并加以解决。

注意 要在不使用 Command 对象的情况下执行查询，请将查询字符串传递给 Recordset 对象的 Open 方法。但是，当要持久保留并重新执行命令文本，或者要使用查询参数时，需要使用 Command 对象。

Mode 属性控制访问权限。

Fields 集合是 Recordset 对象的默认成员。因此，下面两个代码语句是等价的。

Debug.Print objRs.Fields.Item(0)  ' Both statements print
Debug.Print objRs(0)              '  the Value of Item(0).

请参阅

Recordset 对象属性、方法和事件 | Connection 对象 | Fields 集合 | Properties 集合 | Appendix A: Providers


属性、方法和事件

ADO 2.5 API 参考

Recordset 对象属性、方法和事件

属性/集合

AbsolutePage 属性

AbsolutePosition 属性

ActiveCommand 属性

ActiveConnection 属性

BOF 和 EOF 属性

Bookmark 属性

CacheSize 属性

CursorLocation 属性

CursorType 属性

DataMember 属性

DataSource 属性

EditMode 属性

Fields 集合

Filter 属性

Index 属性

LockType 属性

MarshalOptions 属性

MaxRecords 属性

PageCount 属性

PageSize 属性

Properties 集合

RecordCount 属性

Sort 属性

Source 属性 (ADO Recordset)

State 属性

Status 属性 (ADO Recordset)

StayInSync 属性

方法

AddNew 方法

Cancel 方法

CancelBatch 方法

CancelUpdate 方法

Clone 方法

Close 方法

CompareBookmarks 方法

Delete 方法 (ADO Recordset)

Find 方法

GetRows 方法

GetString 方法

Move 方法

MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法

NextRecordset 方法

Open 方法 (ADO Recordset)

Requery 方法

Resync 方法

Save 方法

Seek 方法

Supports 方法

Update 方法

UpdateBatch 方法

事件

EndOfRecordset 事件

FetchComplete 事件

FetchProgress 事件

WillChangeField 和 FieldChangeComplete 事件

WillChangeRecord 和 RecordChangeComplete 事件

WillChangeRecordset 和 RecordsetChangeComplete 事件

WillMove 和 MoveComplete 事件

请参阅

Recordset 对象


Stream 对象 (ADO)

ADO 2.5 API 参考

Stream 对象

表示二进制数据或文本的流。

说明

在诸如文件系统或电子邮件系统这样的树状分级结构中，Record 可能有一个与之相关联的位的默认二进制流，其中包含文件或电子邮件的内容。Stream 对象可用于对包含这些数据流的字段或记录进行操作。可以通过下列方式获取 Stream 对象：

  • 通过指向包含二进制或文本数据的对象（通常是文件）的 URL。此对象可以是简单的文档、表示结构化文档的 Record 对象或文件夹。
  • 通过打开与 Record 对象相关联的默认 Stream 对象。打开 Record 时便可获取与 Record 对象相关联的默认流。只需打开该流便可删除一个往返过程。
  • 通过将 Stream 对象实例化。这些 Stream 对象可用来存储用于应用程序的数据。跟与 URL 相关联的 Stream 或 Record 的默认 Stream 不同，实例化的 Stream 在默认情况下与基本源没有关联。

用 Stream 对象的方法和属性可以执行下列操作：

  • 用 Open 方法从 Record 或 URL 打开 Stream 对象。
  • 用 Close 方法关闭 Stream。
  • 用 Write 和 WriteText 方法向 Stream 中输入字节或文本。
  • 用 Read 和 ReadText 方法从 Stream 中读取字节。
  • 用 Flush 方法将仍在 ADO 缓冲区中的任何 Stream 数据写入基本对象。
  • 用 CopyTo 方法将 Stream 的内容复制到另一 Stream。
  • 用 SkipLine 方法和 LineSeparator 属性控制从源文件中读取行的方式。
  • 用 EOS 属性和 SetEOS 方法确定流位置的结尾。
  • 用 SaveToFile 和 LoadFromFile 方法保存和恢复文件中的数据。
  • 用 Charset 属性指定用于存储 Stream 的字符集。
  • 用 Cancel 方法终止异步 Stream 操作。
  • 用 Size 属性确定 Stream 中的字节数。
  • 用 Position 属性控制 Stream 中的当前位置。
  • 用 Type 属性确定 Stream 中的数据类型。
  • 用 State 属性确定 Stream 的当前状态（已打开、关闭或正在执行）。
  • 用 Mode 属性指定 Stream 的访问模式。
注意 使用 http 模式的 URL 将自动调用 Microsoft OLE DB Provider for Internet Publishing。有关详细信息，请参阅绝对和相对 URL。

请参阅

Visual Basic 范例

Stream 对象属性、方法和事件 | Chapter 10: Records and Streams


属性、方法和事件

ADO 2.5 API 参考

Stream 对象属性、方法和事件

属性

Charset 属性

EOS 属性

LineSeparator 属性

Mode 属性

Position 属性

Size 属性 (ADO Stream)

State 属性

Type 属性 (ADO Stream)

方法

Cancel 方法

Close 方法

CopyTo 方法

Flush 方法

LoadFromFile 方法

Open 方法 (ADO Stream)

Read 方法

ReadText 方法

SaveToFile 方法

SetEOS 方法

SkipLine 方法

Stat 方法

Write 方法

WriteText 方法

事件

无。

请参阅

Stream 对象


ADO 集合

这些集合与 ADO 对象之间的关系表示在 ADO 对象模型中。

每个集合可包含其对应的对象。例如，Error 对象可包含在 Errors 集合中。有关对象的详细信息，请参阅 ADO 对象或特定的对象主题。

错误 | 包含为响应单个提供者相关失败而创建的所有 Error 对象。
Fields | 包含 Recordset 对象的所有 Field 对象。
Parameters | 包含 Command 对象的所有 Parameter 对象。
Properties | 包含对象特定实例的所有 Property 对象。

请参阅

ADO API 参考 | ADO 动态属性 | ADO 枚举常量 | 附录 B：ADO 错误 | ADO 事件 | ADO 方法 | ADO 对象模型 | ADO 对象 | ADO 属性


Errors 集合 (ADO)

ADO 2.5 API 参考

Errors 集合

包含为响应单个提供者相关失败而创建的 Error 对象。

说明

任何涉及 ADO 对象的操作都可能产生一个或多个提供者错误。在每个错误发生时，一个或多个 Error 对象将被放到 Connection 对象的 Errors 集合中。当另一个 ADO 操作产生错误时，Errors 集合被清空，Error 对象的新集合被放到 Errors 集合中。

每个 Error 对象都表示一个特定的提供者错误，而不是 ADO 错误。ADO 错误被记载到运行时例外处理机制中。例如，在 Microsoft Visual Basic 中，发生 ADO 特有的错误将触发 onError 事件，并且出现在 Error 对象中。

不产生错误的 ADO 操作对 Errors 集合没有影响。使用 Clear 方法手动清除 Errors 集合。

Errors 集合中的 Error 对象集合描述为响应单个语句而发生的所有错误。枚举 Errors 集合中的特定错误可使错误处理例程更精确地判断产生错误的原因和来源，并采取适当的步骤恢复。

某些属性和方法返回警告，这些警告显示为 Errors 集合中的 Error 对象，但并不终止执行程序。先调用 Errors 集合的 Clear 方法，然后再调用 Recordset 对象的 Resync、UpdateBatch 或 CancelBatch 方法，Connection 对象的 Open 方法，或设置 Recordset 对象的 Filter 属性。这样，就可以读取 Errors 集合的 Count 属性以测试返回的警告。

注意 有关单个 ADO 操作可产生多个错误的方式的详细说明，请参阅 Error 对象主题。

请参阅

Errors 集合的属性、方法和事件 | Error 对象 | 附录 A：提供者


Errors 集合的属性、方法和事件

属性

Count 属性

Item 属性

方法

Clear 方法

Refresh 方法

事件

无。

请参阅

Errors 集合


Fields 集合 (ADO)

ADO 2.5 API 参考

Fields 集合

包含 Recordset 或 Record 对象的所有 Field 对象。

说明

Recordset 对象包含一个由 Field 对象组成的 Fields 集合。每个 Field 对象对应于 Recordset 中的一列。打开 Recordset 之前可以调用 Fields 集合的 Refresh 方法来预置该集合。

注意 有关如何使用 Field 对象的详细说明，请参阅 Field 对象主题。

Fields 集合包含 Append 方法和 Update 方法，Append 方法在集合中临时创建和添加 Field 对象，而 Update 方法完成所有的添加和删除。

Record 对象包含两个可以用 FieldEnum 常量进行索引的特殊字段。一个常量访问包含 Record 的默认流的字段，另一个常量访问包含 Record 的绝对 URL 字符串的字段。

某些提供者（例如，Microsoft OLE DB Provider for Internet Publishing）可能会用 Record 或 Recordset 的可用字段的子集来预置 Fields 集合。其他字段只能在按名称引用或按代码索引以后才添加到集合中。

如果试图按名称引用不存在的字段，则新的 Field 对象将通过 adFieldPendingInsert 的 Status 追加到 Fields 集合中。当调用 Update 时，如果提供者允许，ADO 将在数据源中创建一个新字段。

请参阅

Fields 集合的属性、方法和事件 | Field 对象


Fields 集合的属性、方法和事件

属性

Count 属性

Item 属性

方法

Append 方法

CancelUpdate 方法

Delete 方法（ADO Fields 集合）

Refresh 方法

Resync 方法

Update 方法

事件

无。

请参阅

Fields 集合


Parameters 集合 (ADO)

ADO 2.5 API 参考

Parameters 集合

包含 Command 对象的所有 Parameter 对象。

说明

Command 对象包含一个由 Parameter 对象组成的 Parameters 集合。

使用 Command 对象的 Parameters 集合的 Refresh 方法检索存储过程的提供者参数信息，或者检索 Command 对象中指定的参数化查询。某些提供者不支持存储过程调用或参数化查询；使用这些提供者时，调用 Parameters 集合的 Refresh 方法将返回错误。

如果调用 Refresh 方法前没有定义自己的 Parameter 对象而访问 Parameters 集合，ADO 将自动为您调用该方法并预置该集合。

如果知道与要调用的存储过程或参数化查询相关联的参数的属性，便可以最小化对提供者的调用以提高性能。使用 CreateParameter 方法创建带适当属性设置的 Parameter 对象，并使用 Append 方法将它们添加到 Parameters 集合中。这使用户可以设置和返回参数值，而不必调用提供者来获得参数信息。如果正在写给不支持参数信息的提供者，那么必须使用此方法手动预置 Parameters 集合后才能使用参数。必要时可以使用 Delete 方法从 Parameters 集合中删除 Parameter 对象。

Recordset 关闭时，Recordset 的 Parameters 集合中的对象将超出范围（成为不可用参数）。

请参阅

Parameters 集合的属性、方法和事件 | Append 方法 | CreateParameter 方法 | Parameter 对象


Parameters 集合的属性、方法和事件

属性

Count 属性

Item 属性

方法

Append 方法

Delete 方法（ADO Parameters 集合）

Refresh 方法

事件

无。

请参阅

Parameters 集合


Properties 集合 (ADO)

ADO 2.5 API 参考

Properties 集合

包含对象特定实例的所有 Property 对象。

说明

某些 ADO 对象包含由 Property 对象组成的 Properties 集合。每个 Property 对象对应于提供者特有的 ADO 对象的特性。

注意 有关如何使用 Property 对象的详细说明，请参阅 Property 对象主题。

Recordset 关闭时，Recordset 对象的 Dynamic Properties 超出范围（成为不可用参数）。

请参阅

Properties 集合的属性、方法和事件 | Property 对象 | 附录 A：提供者


Properties 集合的属性、方法和事件

属性

Count 属性

Item 属性

方法

Refresh 方法

事件

无。

请参阅

Properties 集合


ADO 属性

AbsolutePage | 指示当前记录所在的页。
AbsolutePosition | 指示 Recordset 对象的当前记录的序号位置。
ActiveCommand | 指示 Command 对象，用于创建相关联的 Recordset 对象。
ActiveConnection | 指示指定的 Command、Recordset 或 Record 对象当前所属的 Connection 对象。
ActualSize | 指示字段的值的实际长度。
Attributes | 指示对象的一项或多项特性。
BOF 和 EOF | BOF — 指示当前记录位置位于 Recordset 对象的第一个记录之前。 EOF — 指示当前记录位置位于 Recordset 对象的最后一个记录之后。
Bookmark | 指示唯一标识 Recordset 对象中的当前记录的书签，或者将 Recordset 对象的当前记录设置为由有效书签标识的记录。
CacheSize | 指示在内存中本地缓存的 Recordset 对象的记录数目。
子集 | 从 ADORecordsetConstruction 对象中或在该对象上获得或设置 OLE DB Chapter 对象。
CharSet | 指示用于转换文本 Stream 内容的字符集。
CommandText | 指示要根据提供者发出的命令文本。
CommandTimeout | 指示执行命令期间在终止尝试和产生错误之前需等待的时间。
CommandType | 指示 Command 对象的类型。
ConnectionString | 指示用于建立到数据源的连接的信息。
ConnectionTimeout | 指示建立连接期间在终止尝试和产生错误之前需要等待的时间。
Count | 指示集合中对象的数目。
CursorLocation | 指示游标服务的位置。
CursorType | 指示 Recordset 对象中所用游标的类型。
DataMember | 指示要从 DataSource 属性所引用的对象中检索的数据成员的名称。
DataSource | 指示对象，其中包含要被表示为 Recordset 对象的数据。
DefaultDatabase | 指示 Connection 对象的默认数据库。
DefinedSize | 指示 Field 对象的数据容量。
Description | 描述 Error 对象。
Direction | 指示 Parameter 表示输入参数、输出参数还是两者都表示，或者指示该参数是否是从存储过程返回的值。
EditMode | 指示当前记录的编辑状态。
EOS | 指示当前位置是否在流的结尾处。
Filter | 指示 Recordset 中的数据的过滤器。
HelpContext 和 HelpFile | 指示与 Error 对象相关联的帮助文件和主题。 HelpContextID — 以 Long 值返回帮助文件中的主题的上下文 ID。 HelpFile — 返回 String 值，用于计算帮助文件的完整解析路径。
Index | 指示对 Recordset 对象当前生效的索引的名称。
IsolationLevel | 指示 Connection 对象的隔离级别。
Item | 按名称或序号指示集合的特定成员。
LineSeparator | 指示要在文本 Stream 对象中用作分行符的二进制字符。
LockType | 指示编辑过程中记录上的锁定类型。
MarshalOptions | 指示要调度回服务器的记录。
MaxRecords | 指示由查询返回给 Recordset 的最大记录数目。
Mode | 指示在 Connection、Record 或 Stream 对象中修改数据的有效权限。
Name | 指示对象的名称。
NativeError | 指示给定 Error 对象的提供者特有的错误代码。
Number | 指示唯一标识 Error 对象的数字。
NumericScale | 指示 Parameter 或 Field 对象中数字值的范围。
OriginalValue | 指示发生任何更改前记录中已经存在的 Field 的值。
PageCount | 指示 Recordset 对象包含的数据页数。
PageSize | 指示 Recordset 中一页包含的记录数目。
ParentRow | 设置 ADORecordConstruction 对象上 OLE DB Row 对象的容器，以便将父行放入到 ADO Record 对象中。
ParentURL | 指示指向当前 Record 对象的父 Record 的绝对 URL 字符串。
Position | 指示在 Stream 对象中的当前位置。
Precision | 指示 Parameter 对象中的数字值的精度或数字型 Field 对象的精度。
Prepared | 指示执行前是否保存命令的编译版本。
Provider | 指示 Connection 对象的提供者的名称。
RecordCount | 指示 Recordset 对象中的记录数目。
RecordType | 指示 Record 对象的类型。
Row | 从 ADORecordConstruction 对象中或在该对象上获得或设置 OLE DB Row 对象。
RowPosition | 从 ADORecordsetConstruction 对象中或在该对象上获得或设置 OLE DB RowPosition。
Rowset | 从 ADORecordsetConstruction 对象中或在该对象上获得或设置 OLE DB Rowset 对象。
Size | 指示 Parameter 对象的最大字节或字符大小。
Size (ADO Stream) | 指示的流的总字节数。
Sort | 指示一个或多个作为 Recordset 排序基准的字段名，并指示按升序还是降序对每个字段进行排序。
Source (ADO Error) | 指示最初产生错误的对象或应用程序的名称。
Source (ADO Record) | 指示由 Record 对象表示的项目。
Source (ADO Recordset) | 指示 Recordset 对象中的数据源。
SQLState | 指示给定 Error 对象的 SQL 状态。
State | 对所有适用的对象，指示该对象状态是打开的还是关闭的。 对执行异步方法的所有适用的对象，指示对象的当前状态是正在连接、正在执行还是正在检索。
Status (ADO Field) | 指示 Field 对象的状态。
Status (ADO Recordset) | 指示有关批更新或其他大量操作的当前记录的状态。
StayInSync | 指示在分级 Recordset 对象中，当父行位置更改时，对基本子记录（即“子集”）的引用是否会更改。
Type | 指示 Parameter、Field 或 Property 对象的可操作类型或数据类型。
Type (ADO Stream) | 指示 Stream 中包含的数据的类型（二进制或文本）。
UnderlyingValue | 指示数据库中 Field 对象的当前值。
Value | 指示分配给 Field、Parameter 或 Property 对象的值。
Version | 指示 ADO 版本号。

请参阅

ADO API 参数 | ADO 集合 | ADO 动态属性 | ADO 枚举常量 | 附录 B：ADO 错误 | ADO 事件 | ADO 方法 | ADO 对象模型 | ADO 对象

© 1998-2002 Microsoft Corporation。保留所有权利。


AbsolutePage 属性 (ADO)

ADO 2.5 API 参考

AbsolutePage 属性

指示当前记录所在的页。

设置和返回值

设置或返回从 1 到 Recordset 对象所含页数 (PageCount) 的 Long 值，或者返回一个 PositionEnum 值。

说明

可以使用此属性标识当前记录所在的页码。它使用 PageSize 属性将 Recordset 对象的行集合总数逻辑划分为一系列的页，每一页的记录数都等于 PageSize（最后一页除外，因为它的记录数可能较少）。提供者必须支持相应的功能才能使用此属性。

获得或设置 AbsolutePage 属性时，ADO 按如下方式配合使用 AbsolutePosition 属性和 PageSize 属性：

  • 要获得 AbsolutePage，ADO 首先检索 AbsolutePosition，然后按 PageSize 进行划分。
  • 要设置 AbsolutePage，ADO 按如下方式移动 AbsolutePosition：它用新的 AbsolutePage 值乘 PageSize，然后将得到的值加 1。其结果是，成功设置 AbsolutePage 之后，Recordset 中的当前位置是该页中的第一个记录。

与 AbsolutePosition 属性一样，AbsolutePage 也是从 1 开始，并且当前记录是 Recordset 的第一个记录时等于 1。设置此属性以移动到某一页的第一个记录。通过 PageCount 属性获得总页数。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

AbsolutePosition 属性 | PageCount 属性 | PageSize 属性

适用于：Recordset 对象

© 1998-2002 Microsoft Corporation。保留所有权利。


AbsolutePosition 属性 (ADO)

ADO 2.5 API 参考

AbsolutePosition 属性

指示 Recordset 对象的当前记录的序号位置。

设置和返回值

设置或返回从 1 到 Recordset 对象 (PageCount) 中的记录数的 Long 值，或者返回一个 PositionEnum 值。

说明

要设置 AbsolutePosition 属性，ADO 要求您正在使用的 OLE DB 提供者实现 IRowsetLocate 接口。

访问用仅向前或动态游标打开的 Recordset 的 AbsolutePosition 属性将产生错误 adErrFeatureNotAvailable。使用其他游标类型时，只要提供者支持 IRowsetScroll 接口，就会返回正确的位置。如果提供者不支持 IRowsetScroll 接口，该属性将被设置为 adPosUnknown。要确定您的提供者是否支持 IRowsetScroll，请参阅提供者的文档。

使用 AbsolutePosition 属性根据在 Recordset 对象中的序号位置移动到某一记录，或确定当前记录的序号位置。提供者必须支持相应的功能才能使用此属性。

与 AbsolutePage 属性一样，AbsolutePosition 也是从 1 开始，并且当前记录是 Recordset 的第一个记录时等于 1。可以通过 RecordCount 属性获取 Recordset 对象中记录的总数目。

设置 AbsolutePosition 属性时，即使该属性指向当前缓存中的记录，ADO 也将使用以用户指定的记录开始的新记录组来重载缓存。CacheSize 属性决定此记录组的大小。

注意 不应将 AbsolutePosition 属性作为替代的记录编号使用。删除前面的记录时，给定记录的位置将发生更改。如果重新查询或重新打开 Recordset 对象，则无法保证给定的记录会有相同的 AbsolutePosition。书签仍然是保持和返回给定位置的建议方式，并且是跨越 Recordset 对象的所有类型定位的唯一方式。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

AbsolutePage 属性 | RecordCount 属性

适用于：Recordset 对象

© 1998-2002 Microsoft Corporation。保留所有权利。


ActiveCommand 属性 (ADO)

ADO 2.5 API 参考

ActiveCommand 属性

指示 Command 对象，用于创建相关联的 Recordset 对象。

返回值

返回 Variant，其中包含 Command 对象。默认值是 Null 对象引用。

说明

ActiveCommand 属性为只读。

如果没有使用 Command 对象创建当前 Recordset，将返回一个 Null 对象引用。

如果只给出了所产生的 Recordset 对象，请使用此属性查找相关联的 Command 对象。

请参阅

Visual Basic 范例 |JScript 范例 | VC++ 范例 | VJ++ 范例

Command 对象

适用于：Recordset 对象


ActiveConnection 属性 (ADO)

ADO 2.5 API 参考

ActiveConnection 属性

指示指定的 Command、Recordset 或 Record 对象当前所属的 Connection 对象。

设置和返回值

设置或返回 String 值或 Variant，如果连接被关闭，则 String 值包含连接的定义。如果连接打开，则 Variant 包含当前 Connection 对象。默认值是 Null 对象引用。请参阅 ConnectionString 属性。

说明

用 ActiveConnection 属性确定 Connection 对象，将在该对象上执行指定的 Command 对象或打开指定的 Recordset。

Command

对于 Command 对象，ActiveConnection 属性为读/写。

在将此属性设置为打开的 Connection 对象或有效的连接字符串之前，如果试图调用 Command 对象的 Execute 方法，将产生错误。

Microsoft Visual Basic 将 ActiveConnection 属性设置为 Nothing 将断开 Command 对象与当前 Connection 的关联，并导致提供者释放数据源上所有相关联的资源。然后，可以将 Command 对象与相同的或另一个 Connection 对象相关联。某些提供者允许将属性设置从一个 Connection 更改为另一个，而不必先将该属性设置为 Nothing。
如果 Command 对象的 Parameters 集合包含由提供者提供的参数，那么当把 ActiveConnection 属性设置为 Nothing 或另一个 Connection 对象时，集合将被清空。如果手动创建 Parameter 对象并用这些对象填充 Command 对象的 Parameters 集合，则将 ActiveConnection 属性设置为 Nothing 或另一个 Connection 不会影响 Parameters 集合。
关闭与 Command 对象相关联的 Connection 对象可将 ActiveConnection 属性设置为 Nothing。将此属性设置为已关闭的 Connection 对象将产生错误。

Recordset

对于打开的 Recordset 对象或其 Source 属性被设置为有效的 Command 对象的 Recordset 对象，ActiveConnection 属性为只读。否则，该属性为读/写。

可将此属性设置为有效的 Connection 对象或有效的连接字符串。在这种情况下，提供者将用此定义创建新的 Connection 对象并打开连接。另外，提供者可以将此属性设置为新的 Connection 对象，以向您提供访问扩展错误信息的 Connection 对象或执行其他命令的方法。

如果使用 Open 方法的 ActiveConnection 参数打开 Recordset 对象，ActiveConnection 属性将继承该参数的值。

如果将 Recordset 对象的 Source 属性设置为有效的 Command 对象变量，Recordset 的 ActiveConnection 属性将继承 Command 对象的 ActiveConnection 属性的设置。

远程数据服务用法 当在客户端 Recordset 对象上使用时，只能将此属性设置为连接字符串或 Nothing（在 Microsoft Visual Basic 或 Visual Basic Scripting Edition 中）。

Record

当 Record 对象关闭时，此属性为读/写，并可包含连接字符串或对打开的 Connection 对象的引用。当 Record 对象打开时，此属性为只读，并包含对打开的 Connection 对象的引用。

当用 URL 打开 Record 对象时，将隐式地创建 Connection 对象。通过为此属性分配 Connection 对象或将 Connection 对象用作 Open 方法调用中的参数，可以用现有的打开的 Connection 对象来打开 Record。如果从现有的 Record 或 Recordset 打开 Record，它将自动与该 Record 或 Recordset 对象的 Connection 对象相关联。

注意 使用 http 模式的 URL 将自动调用 Microsoft OLE DB Provider for Internet Publishing。有关详细信息，请参阅绝对和相对 URL。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例 | JScript 范例

Connection 对象 | ConnectionString 属性

适用于：Command 对象 | Record 对象 | Recordset 对象


ActualSize 属性 (ADO)

ADO 2.5 API 参考

ActualSize 属性

指示字段的值的实际长度。

设置和返回值

返回 Long 值。某些提供者允许设置此属性以便为 BLOB 数据预留空间，在此情况下，默认值为 0。

说明

用 ActualSize 属性返回 Field 对象的值的实际长度。对于所有字段，ActualSize 属性均为只读。如果 ADO 无法确定 Field 对象的值的长度，ActualSize 属性将返回 adUnknown。

ActualSize 与 DefinedSize 属性有所不同，其区别如下例所示。声明为 adVarChar 类型、最大长度为 50 个字符的 Field 对象返回的 DefinedSize 属性值为 50，但它返回的 ActualSize 属性值为存储在当前记录的字段中的数据长度。DefinedSize 超过 255 字节的 Fields 被视为变长列。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

DefinedSize 属性

适用于：Field 对象


Attributes 属性 (ADO)

ADO 2.5 API 参考

Attributes 属性

指示对象的一项或多项特性。

设置和返回值

设置或返回 Long 值。

对于 Connection 对象，Attributes 属性为读/写，并且其值可以是一个或多个 XactAttributeEnum 值的和。默认值为零 (0)。

对于 Parameter 对象，Attributes 属性为读/写，并且其值可以是任意一个或多个 ParameterAttributesEnum 值的和。默认值为 adParamSigned。

对于 Field 对象，Attributes 属性可以是一个或多个 FieldAttributeEnum 值的和。通常情况下该属性为只读，但是，对于已追加到 Record 的 Fields 集合中的新 Field 对象，只有当已指定 Field 的 Value 属性并且数据提供者通过调用 Fields 集合的 Update 方法已成功添加了新的 Field 时，Attributes 才为读/写。

对于 Property 对象，Attributes 属性为只读，并且其值可以是任意一个或多个 PropertyAttributesEnum 值的和。

说明

使用 Attributes 属性设置或返回 Connection 对象、Parameter 对象、Field 对象或 Property 对象的特性。

设置多个属性时，可以将适当的常量相加。如果将属性值设置为包括不兼容常量的和，将会发生错误。

远程数据服务用法 此属性在客户端 Connection 对象上不可用。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

AppendChunk 方法 | BeginTrans、CommitTrans 和 RollbackTrans 方法 | GetChunk 方法

适用于：Connection 对象 | Field 对象 | Parameter 对象 | Property 对象


BOF 和 EOF 属性 (ADO)

ADO 2.5 API 参考

BOF 和 EOF 属性

  • BOF — 指示当前记录位置位于 Recordset 对象的第一个记录之前。
  • EOF — 指示当前记录的位置在 Recordset 对象的最后一个记录之后。

返回值

BOF 和 EOF 属性返回 Boolean 值。

说明

使用 BOF 和 EOF 属性确定 Recordset 对象是否包含记录，或者从一个记录移动到另一个记录时是否超出 Recordset 对象的限制。

如果当前记录位于第一个记录之前，则 BOF 属性返回 True (-1)。如果当前记录是第一个记录或位于第一个记录之后，则返回 False (0)。

如果当前记录位于最后一个记录之后，则 EOF 属性返回 True。如果当前记录是最后一个记录或位于最后一个记录之前，则返回 False。

如果 BOF 或 EOF 属性为 True，则没有当前记录。

如果打开不包含记录的 Recordset 对象，则 BOF 和 EOF 属性被设置为 True（有关此状态的 Recordset 的详细信息，请参阅 RecordCount 属性）。当打开至少包含一个记录的 Recordset 对象时，第一个记录是当前记录，并且 BOF 和 EOF 属性均为 False。

如果删除 Recordset 对象中保留的最后一个记录，BOF 和 EOF 属性将保持 False，直到重新定位当前记录为止。

下表说明对 BOF 和 EOF 属性的不同组合所允许的 Move 方法。

 | MoveFirst MoveLast | MovePrevious Move < 0 | Move 0 | MoveNext Move > 0
BOF=True EOF=False | 允许 | 错误 | 错误 | 允许
BOF=False EOF=True | 允许 | 允许 | 错误 | 错误
均为 True | 错误 | 错误 | 错误 | 错误
均为 False | 允许 | 允许 | 允许 | 允许

允许使用 Move 方法但不能保证该方法可成功定位记录，只表明调用指定的 Move 方法不会产生错误。

下表显示当调用多个 Move 方法但未能成功定位记录时，BOF 和 EOF 属性设置所发生的情况。

 | BOF | EOF
MoveFirst、MoveLast | 设置为 True | 设置为 True
Move 0 | 没有变化 | 没有变化
MovePrevious、Move < 0 | 设置为 True | 没有变化
MoveNext、Move > 0 | 没有变化 | 设置为 True

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

适用于：Recordset 对象


Bookmark 属性 (ADO)

ADO 2.5 API 参考

Bookmark 属性

指示唯一标识 Recordset 对象中的当前记录的书签，或者将 Recordset 对象的当前记录设置为由有效书签标识的记录。

设置和返回值

设置或返回计算有效书签的 Variant 表达式。

说明

用 Bookmark 属性保存当前记录的位置并随时返回到该记录。只有在支持书签功能的 Recordset 对象中，书签才可用。

打开 Recordset 对象时，它的每个记录都有一个唯一的书签。若要保存当前记录的书签，请将 Bookmark 属性的值分配给一个变量。若要在移动到不同的记录后能随时快速返回到该记录，请将 Recordset 对象的 Bookmark 属性设置为该变量的值。

用户可能无法查看书签的值。也无法对书签直接比较，因为引用同一记录的两个书签可能有不同的值。

如果用 Clone 方法创建一个 Recordset 对象的副本，那么原始的和重复的 Recordset 对象的 Bookmark 属性设置相同，可以互换使用。但是，不能将不同 Recordset 对象的书签互换使用，即使这些书签是通过相同的源或命令创建的。

远程数据服务用法 当在客户端 Recordset 对象上使用时，Bookmark 属性始终有效。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Supports 方法

适用于：Recordset 对象


CacheSize 属性 (ADO)

ADO 2.5 API 参考

CacheSize 属性

指示在内存中本地缓存的 Recordset 对象的记录数目。

设置和返回值

设置或返回必须大于 0 的 Long 值。默认值为 1。

说明

用 CacheSize 属性控制提供者一次检索到本地内存中的记录数目。例如，如果 CacheSize 为 10，首次打开 Recordset 对象后，提供者将前 10 个记录检索到本地内存。当在 Recordset 对象中移动时，提供者从本地内存缓冲区返回数据。一旦移动超过缓存中的最后一个记录，提供者便将数据源中随后的 10 个记录检索到缓存中。

注意 CacheSize 是基于 Maximum Open Rows 的提供者特有的属性（位于 Recordset 对象的 Properties 集合中）。不能将 CacheSize 设置为大于 Maximum Open Rows 的值。要修改提供者可以打开的行数，请设置 Maximum Open Rows。

可以在Recordset 对象的存活期内调整 CacheSize 的值，但是更改此值只影响随后从数据源检索到缓存的记录数。只更改属性值将不会更改缓存中的当前内容。

如果要检索的记录比 CacheSize 指定的少，提供者将返回剩余的记录而不会产生错误。

不允许将 CacheSize 设置为零，否则将返回错误。

从缓存检索到的记录不反映其他用户对数据源所做的并发更改。若要强行更新所有缓存数据，请使用 Resync 方法。

如果 CacheSize 设置的值大于一，在检索记录之后进行删除时，定位方法（Move、MoveFirst、MoveLast、MoveNext 和 MovePrevious）可能会定位到已删除的记录。当完成最初的提取后，随后的删除将不会反映到数据缓存中，除非试图访问已删除的行中的数据值。但是，因为无法提取已删除的行，所以将 CacheSize 设置为 1 便可消除此问题。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例 | Jscript 范例

适用于：Recordset 对象


Chapter 属性 (ADO)

ADO 2.5 API 参考

Chapter 属性

从/在 ADORecordsetConstruction 对象上获得或设置 OLE DB Chapter 对象。使用 put_Chapter 设置 Chapter 对象时，将把行的子集转变成 ADO Recordset 对象。这样就可以设置 Rowset object 的当前子集。

读/写。语法

HRESULT get_Chapter([out, retval] long* plChapter);
HRESULT put_Chapter([in] long lChapter);

参数

plChapter
指针，指向子集句柄。
LChapter
子集句柄。

返回值

此属性方法返回标准的 HRESULT 值，包括 S_OK 和 E_FAIL。

适用于

ADORecordsetConstruction


Charset 属性 (ADO)

ADO 2.5 API 参考

Charset 属性

指示用于转换文本 Stream 内容的字符集，以将其存储在 Stream 对象的内部缓冲区中。

设置和返回值

设置或返回 String 值，该值指定用于转换 String 内容的字符集。默认值为“Unicode”。所允许的值是作为 Internet 字符集字符串（例如，“iso-8859-1”，“Windows-1252”等）被传递到接口的典型字符串。有关系统支持的字符集字符串的列表，请参阅 Windows 注册表中 HKEY_CLASSES_ROOT\MIME\Database\Charset 的子键。

说明

在文本 Stream 对象中，文本数据存储在 Charset 属性指定的字符集中。默认值为 Unicode。Charset 属性用于将数据转换为输入 Stream 或从 Stream 中输出。例如，如果 Stream 包含 ISO-8859-1 数据，并将该数据复制到 BSTR，Stream 对象将把该数据转换为 Unicode。反之亦然。

对于打开的 Stream，其当前 Position 必须位于 Stream (0) 的开始处，这样才能设置 Charset。

Charset 只能与文本 Stream 对象（Type 为 adTypeText）一起使用。如果 Type 为 adTypeBinary，则忽略此属性。

请参阅

Visual Basic 范例

适用于：Stream 对象


CommandText 属性 (ADO)

ADO 2.5 API 参考

CommandText 属性

指示要根据提供者发出的命令文本。

设置和返回值

设置或返回 String 值，该值包含提供者命令，如 SQL 语句、表名、相对 URL 或存储过程调用。默认值为零 ""（零长度字符串）。

说明

用 CommandText 属性设置或返回由 Command 对象表示的命令文本。此文本通常为 SQL 语句，但也可以是提供者能识别的任何其他类型的命令语句，如存储过程调用。SQL 语句必须是提供者的查询处理器所支持的特定方言或版本。

如果将 Command 对象的 Prepared 属性设置为 True 并在设置 CommandText 属性时将 Command 对象绑定到打开的连接上，那么当调用 Execute 或 Open 方法时，ADO 将准备查询（即提供者存储的查询的编译格式）。

ADO 可能改变 CommandText 属性，这取决于 CommandType 属性设置。随时都可读取 CommandText 属性以查看 ADO 在执行过程中使用的实际命令文本。

用 CommandText 属性设置或返回相对 URL，该 URL 用于指定诸如文件或目录类型的资源。资源是相对于绝对 URL 显式指定的位置而言，或相对于打开的 Connection 对象隐式指定的位置而言。

注意 使用 http 模式的 URL 将自动调用 Microsoft OLE DB Provider for Internet Publishing。有关详细信息，请参阅绝对和相对 URL。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Requery 方法 | JScript 范例

适用于：Command 对象


CommandTimeout 属性 (ADO)

ADO 2.5 API 参考

CommandTimeout 属性

指示执行命令期间在终止尝试和产生错误之前需等待的时间。

设置和返回值

设置或返回 Long 值，该值指示等待命令执行的秒数。默认值为 30。

说明

用 Connection 对象或 Command 对象的 CommandTimeout 属性来允许因网络拥挤或服务器负载过重产生的延迟而取消 Execute 方法调用。如果在 CommandTimeout 属性设置的时间间隔内未执行完命令，将产生错误，并且 ADO 取消该命令。如果将属性设置为零，ADO 将一直等待到命令执行完毕。请确保正在为其编写代码的提供者和数据源支持 CommandTimeout 功能。

Connection 对象的 CommandTimeout 设置对同一 Connection 中 Command 对象上的 CommandTimeout 设置没有影响，即 Command 对象的 CommandTimeout 属性不继承 Connection 对象的 CommandTimeout 值。

在 Connection 对象上，打开 Connection 后，CommandTimeout 属性将保持为读/写。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例 | JScript 范例

ConnectionTimeout 属性

适用于：Command 对象 | Connection 对象


CommandType 属性 (ADO)

ADO 2.5 API 参考

CommandType 属性

指示 Command 对象的类型。

设置和返回值

设置或返回一个或多个 CommandTypeEnum 值。

注意 不要将 adCmdFile 或 adCmdTableDirect 的 CommandTypeEnum 值与 CommandType 一起使用。仅在使用 Recordset 的 Open 和 Requery 方法时可以将这些值用作选项。

说明

用 CommandType 属性优化 CommandText 属性的计算。

如果 CommandType 属性值等于 adCmdUnknown（默认值），系统性能将会降低，因为 ADO 必须调用提供者来确定 CommandText 属性是 SQL 语句、存储过程还是表名。如果知道正在使用的命令的类型，设置 CommandType 属性可以提示 ADO 直接转入相关代码。如果 CommandType 属性与 CommandText 属性中的命令类型不匹配，那么在调用 Execute 方法时将产生错误。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例 | JScript 范例

适用于：Command 对象


ConnectionString 属性 (ADO)

ADO 2.5 API 参考

ConnectionString 属性

指示用于建立到数据源的连接的信息。

设置和返回值

设置或返回 String 值。

说明

使用 ConnectionString 属性通过传递详细的连接字符串来指定数据源，这些字符串中包含一系列由分号分隔的 argument = value 语句。

ADO 支持 ConnectionString 属性的五个参数，任何其他参数将直接传递到提供者，而 ADO 不作任何处理。ADO 支持的参数如下。

参数 | 说明
Provider= | 指定用于连接的提供者的名称。
File Name= | 指定提供者特有的文件（例如，持久保留的数据源对象）的名称，这些文件中包含预置的连接信息。
Remote Provider= | 指定当打开客户端连接时使用的提供者的名称。（仅限于远程数据服务。）
Remote Server= | 指定当打开客户端连接时使用的服务器的路径名称。（仅限于远程数据服务。）
URL= | 指定连接字符串为标识资源（如文件或目录）的绝对 URL。

设置 ConnectionString 属性并打开 Connection 对象后，提供者可以更改属性的内容，例如通过将 ADO 定义的参数名映射到其等价的提供者来更改。

ConnectionString 属性将自动继承用于 Open 方法的 ConnectionString 参数的值，以便在 Open 方法调用期间覆盖当前的 ConnectionString 属性。

由于 File Name 参数导致 ADO 加载相关联的提供者，因此无法传递 Provider 和 File Name 参数。

ConnectionString 属性在连接关闭时为读/写，在连接打开时为只读。

ConnectionString 属性中的参数副本被忽略。使用任意参数的最后一个实例。

远程数据服务用法 当在客户端 Connection 对象上使用时，ConnectionString 属性只包括 Remote Provider 和 Remote Server 参数。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Appendix A: Providers

适用于：Connection 对象


ConnectionTimeout 属性 (ADO)

ADO 2.5 API 参考

ConnectionTimeout 属性

指示建立连接期间在终止尝试和产生错误之前需要等待的时间。

设置和返回值

设置或返回 Long 值，该值指示等待连接打开的秒数。默认值为 15。

说明

如果由于网络拥挤或服务器负载过重引起的延迟而有必要取消连接尝试，请使用 Connection 对象的 ConnectionTimeout 属性。如果在 ConnectionTimeout 属性设置的时间内未打开连接，将产生错误，并且 ADO 取消该尝试。如果将该属性设置为零，ADO 将一直等待到连接打开。请确保正在为其编写代码的提供者支持 ConnectionTimeout 功能。

ConnectionTimeout 属性在连接关闭时为读/写，在连接打开时为只读。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

CommandTimeout 属性

适用于：Connection 对象


Count 属性 (ADO)

ADO 2.5 API 参考

Count 属性

指示集合中对象的数目。

返回值

返回 Long 值。

说明

使用 Count 属性确定在给定集合中有多少对象。

因为集合成员的编号从零开始，因此应该始终以零成员开始并以 Count 属性值减 1 结束来编写循环代码。如果正在使用 Microsoft Visual Basic 并想在不检查 Count 属性的情况下循环集合的成员，请使用 For Each...Next 命令。

如果 Count 属性为零，说明此集合中没有对象。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Refresh 方法

适用于：Axes 集合 | Columns 集合 | CubeDefs 集合 | Dimensions 集合 | Errors 集合 | Fields 集合 | Groups 集合 | Hierarchies 集合 | Indexes 集合 | Keys 集合 | Levels 集合 | Members 集合 | Parameters 集合 | Positions 集合 | Procedures 集合 | Properties 集合 | Tables 集合 | Users 集合 | Views 集合


CursorLocation 属性 (ADO)

ADO 2.5 API 参考

CursorLocation 属性

指示游标服务的位置。

设置和返回值

设置或返回 Long 值，可将该值设置为一个 CursorLocationEnum 值。

说明

此属性允许在可以访问提供者的多个游标库之间选择。通常情况下，可以选择客户端游标库中的游标或者选择位于服务器上的游标。

只有在设置了属性后，此属性设置才会影响所建立的连接。更改 CursorLocation 属性不会影响现有的连接。

Execute 返回的游标继承此设置。Recordset 对象将从与它们相关联的连接上自动继承此设置。

此属性在 Connection 或已关闭的 Recordset 上为读/写，在打开的 Recordset 上为只读。

远程数据服务用法 当在客户端 Recordset 或 Connection 对象上使用时，CursorLocation 属性只能设置为 adUseClient。

请参阅

Appendix A: Providers

适用于：Connection 对象 | Recordset 对象


CursorType 属性 (ADO)

ADO 2.5 API 参考

CursorType 属性

指示 Recordset 对象中使用的游标的类型。

设置和返回值

设置或返回 CursorTypeEnum 值。默认值为 adOpenForwardOnly。

说明

用 CursorType 属性指定打开 Recordset 对象时使用的游标类型。

如果 CursorLocation 属性设置为 adUseClient，则只支持 adOpenStatic 设置。如果设置了不支持的值，不会产生错误，而会使用所支持的最近似的 CursorType。

如果提供者不支持请求的游标类型，它将返回另一个游标类型。当 Recordset 对象打开时，CursorType 属性将发生改变以同正在使用的实际游标类型相匹配。若要验证返回的游标的特定功能，请使用 Supports 方法。关闭 Recordset 后，CursorType 属性将恢复其初始设置。

下表说明每个游标类型所需的提供者功能（由 Supports 方法常量标识）。

针对本 CursorType 的 Recordset | 对于所有这些常量，Supports 方法必须返回 True
adOpenForwardOnly | 无
adOpenKeyset | adBookmark、adHoldRecords、adMovePrevious 和 adResync
adOpenDynamic | adMovePrevious
adOpenStatic | adBookmark、adHoldRecords、adMovePrevious 和 adResync
注意 尽管对于动态游标和仅向前游标，Supports(adUpdateBatch) 可能为 True，但对于批更新还是应使用键集游标或静态游标。将 LockType 属性设置为 adLockBatchOptimistic，将 CursorLocation 属性设置为 adUseClient，以启用批更新所需的 OLE DB 的 Cursor Service。

CursorType 属性在 Recordset 关闭时为读/写，在 Recordset 打开时为只读。

远程数据服务用法 当在客户端 Recordset 对象上使用时，CursorType 属性只能设置为 adOpenStatic。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Supports 方法

适用于：Recordset 对象


DataMember 属性 (ADO)

ADO 2.5 API 参考

DataMember 属性

指示要从 DataSource 属性所引用的对象中检索的数据成员的名称。

设置和返回值

设置或返回 String 值。名称不区分大小写。

说明

此属性用于通过 Data Environment 创建数据绑定控件。Data Environment 保存数据集合（数据源），数据集合中包含将被表示为 Recordset 对象的命名对象（数据成员）。

DataMember 和 DataSource 属性必须一起使用。

DataMember 属性确定由 DataSource 属性指定的哪个对象将被表示为 Recordset 对象。设置此属性前必须关闭 Recordset 对象。如果设置 DataSource 属性前没有设置 DataMember 属性，或者在 DataSource 属性中指定的对象不能识别 DataMember 名称，都将产生错误。

用法

Dim rs as New ADODB.Recordset
rs.DataMember = "Command"     'Name of the rowset to bind to
Set rs.DataSource = myDE      'Name of the object containing an IRowset

请参阅

DataSource 属性

适用于：Recordset 对象


DataSource 属性 (ADO)

ADO 2.5 API 参考

DataSource 属性

指示对象，其中包含要被表示为 Recordset 对象的数据。

说明

此属性用于通过 Data Environment 创建数据绑定控件。Data Environment 保存数据集合（数据源），数据集合中包含将被表示为 Recordset 对象的命名对象（数据成员）。

DataMember 和 DataSource 属性必须一起使用。

所引用的对象必须实现 IDataSource 接口，并且必须包含 IRowset 接口。

用法

Dim rs as New ADODB.Recordset
rs.DataMember = "Command"     'Name of the rowset to bind to
Set rs.DataSource = myDE      'Name of the object containing an IRowset

请参阅

DataMember 属性

适用于：Recordset 对象


DefaultDatabase 属性 (ADO)

ADO 2.5 API 参考

DefaultDatabase 属性

指示 Connection 对象的默认数据库。

设置和返回值

设置或返回 String 值，该值计算可从提供者处获得的数据库的名称。

说明

用 DefaultDatabase 属性设置或返回特定 Connection 对象上的默认数据库的名称。

如果有默认数据库，SQL 字符串将使用无限制的语法访问该数据库中的对象。若要访问未在 DefaultDatabase 属性中指定的数据库中的对象，对象名称必须与所需数据库的名称相匹配。连接时，提供者将把默认数据库信息写入 DefaultDatabase 属性。某些提供者对每个连接只允许一个数据库，在此情况下无法更改 DefaultDatabase 属性。

某些数据源和提供者可能不支持此项功能，并可能返回错误或空字符串。

远程数据服务用法 此属性在客户端 Connection 对象上不可用。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

适用于：Connection 对象


DefinedSize 属性 (ADO)

ADO 2.5 API 参考

DefinedSize 属性

指示 Field 对象的数据容量。

返回值

返回 Long 值，反映字段定义的字节大小。

说明

用 DefinedSize 属性确定 Field 对象的数据容量。

DefinedSize 与 ActualSize 属性不同。例如，假设 Field 对象声明类型为 adVarChar，DefinedSize 属性值为 50，并包含单个字符。该对象返回的 ActualSize 属性值为单个字符的字节长度。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

ActualSize 属性

适用于：Field 对象


Description 属性 (ADO)

ADO 2.5 API 参考

Description 属性

描述 Error 对象。

返回值

返回 String 值，包含错误的描述。

说明

用 Description 属性获取简短的错误描述。显示此属性向用户警告您不能或不想处理的错误。该字符串将来自 ADO 或提供者。

提供者负责向 ADO 传递特定的错误文本。对于接收到的每一个提供者错误或警告，ADO 都会向 Errors 集合中添加一个 Error 对象。枚举 Errors 集合以跟踪提供者传递的错误。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

HelpContext 和 HelpFile 属性 | Number 属性 | Source 属性 (ADO Error)

适用于：Error 对象


Direction 属性 (ADO)

ADO 2.5 API 参考

Direction 属性

指示 Parameter 所表示的是输入参数、输出参数还是两者都表示，或者指示参数是否是存储过程的返回值。

设置和返回值

设置或返回 ParameterDirectionEnum 值。

说明

用 Direction 属性指定将参数传递到过程或从过程传递参数的方式。Direction 属性为读/写，它允许用户使用不返回此信息的提供者，或者在不希望 ADO 为检索参数信息而额外调用提供者时设置此信息。

并非所有提供者都能在其存储过程中确定参数的方向。在这种情况下，必须在执行查询前设置 Direction 属性。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例 | JScript 范例

适用于：Parameter 对象


EditMode 属性 (ADO)

ADO 2.5 API 参考

EditMode 属性

指示当前记录的编辑状态。

返回值

返回 EditModeEnum 值。

说明

ADO 保存与当前记录相关联的编辑缓冲区。此属性指示是否已对此缓冲区进行了更改，或者指示是否已创建了新记录。用 EditMode 属性确定当前记录的编辑状态。如果编辑进程被中断，可以对挂起更改进行测试，并确定是否需要使用 Update 或 CancelUpdate 方法。

有关不同编辑条件下 EditMode 属性的详细说明，请参阅 AddNew 方法。

如果调用 Delete 不能成功删除数据源中的记录（例如，由于违反引用完整性），Recordset 将仍处于编辑模式下（EditMode = adEditInProgress）。这意味着必须在删除当前记录之前调用 CancelUpdate（例如，使用 Move、NextRecordset 或 Close）。

注意 EditMode 只有存在当前记录时才返回有效值。如果 BOF 或 EOF 为 True 或当前记录已被删除，EditMode 将返回错误。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

AddNew 方法 | CancelUpdate 方法 | Update 方法

适用于：Recordset 对象


EOS 属性 (ADO)

ADO 2.5 API 参考

EOS 属性

指示当前位置是否在流的结尾处。

返回值

返回 Boolean 值，指示当前位置是否在流的结尾处。如果流中没有其他字节，则 EOS 返回 True；如果当前位置后还有其他字节，则返回 False。

若要设置流的结尾位置，请使用 SetEOS 方法。若要确定当前位置，请使用 Position 属性。

请参阅

Visual Basic 范例

适用于：Stream 对象


Filter 属性 (ADO)

ADO 2.5 API 参考

Filter 属性

指示 Recordset 中的数据的过滤器。

设置和返回值

设置或返回 Variant 值，该值包含下列内容之一：

  • 条件字符串 — 由一个或多个用 AND 或 OR 操作符连接的单个子句组成的字符串。
  • 书签数组 — 指向 Recordset 对象中的记录的唯一书签值数组。
  • FilterGroupEnum 值。

说明

用 Filter 属性选择性地屏蔽 Recordset 对象中的记录。已过滤的 Recordset 成为当前游标。基于当前游标返回值的其他属性将受到影响，如 AbsolutePosition、AbsolutePage、RecordCount 及 PageCount。这是因为将 Filter 属性设置为特定值可将当前记录移动到满足新值的第一个记录。

条件字符串由 FieldName-Operator-Value 格式（如“LastName = 'Smith'”）子句组成。通过连接单独的 AND（如“LastName = 'Smith' AND FirstName = 'John'”）或 OR（如“LastName = 'Smith' OR LastName = 'Jones'”）子句可以创建复合子句。关于条件字符串，请遵循以下规则：

  • FieldName 必须是 Recordset 中有效的字段名。如果字段名包含空格，必须将字段名括在方括号中。
  • Operator 必须是下列字符串之一：<、>、<=、>=、<>、= 或 LIKE。
  • Value 是用于与字段值进行比较的值（如 'Smith'、#8/24/95#、12.345 或 $50.00）。字符串使用单引号，日期使用磅符号 (#)。数字可以使用小数点、美元符号和科学符号。如果 Operator 为 LIKE，则 Value 可以使用通配符。只允许使用星号 (*) 和百分号 (%) 通配符，而且必须是字符串的尾字符。Value 不能为 Null。
    注意 若要在过滤 Value 中包括单引号 (')，请用两个单引号表示一个引号。例如，若要过滤 O'Malley，则条件字符串应为“col1 = 'O''Malley'”。若要在过滤值的开始和结尾处都包括单引号，请用磅符号 (#) 将字符串括起来。例如，若要过滤“'1'”，则条件字符串应为“col1 = #'1'#”。
  • AND 和 OR 在级别上没有先后之分。可用括号将子句分组。但不能象下例所示那样先将由 OR 连接的子句分组，然后再用 AND 将该组连接到其他子句：
    (LastName = 'Smith' OR LastName = 'Jones') AND FirstName = 'John'
  • 与之相反，可将此过滤构造为
    (LastName = 'Smith' AND FirstName = 'John') OR (LastName = 'Jones' AND FirstName = 'John')
  • 在 LIKE 子句中，可在模式的开头和结尾使用通配符（如 LastName Like '*mit*'），或者只在模式的结尾使用通配符（如 LastName Like 'Smit*'）。

通过仅允许查看诸如上次调用 UpdateBatch 方法时受到影响的记录，过滤常量可以更容易地解决在批更新模式中发生的单个记录冲突。

由于与基本数据冲突（例如，记录已被另一用户删除），设置 Filter 属性本身可能会失败。在这种情况下，提供者向 Errors 集合返回警告但并不终止程序执行。只有在所有提出请求的记录上都发生冲突时才会发生运行时错误。用 Status 属性定位有冲突的记录。

将 Filter 属性设置为零长度字符串 ("") 与使用 adFilterNone 常量具有相同效果。

只要设置了 Filter 属性，当前记录位置都将移动到 Recordset 中已过滤记录子集的第一个记录处。同样，当 Filter 属性被清空时，当前记录位置都将移动到 Recordset 的第一个记录处。

通过书签值可以构造一个与 Filter 属性配合使用的数组，有关书签值的解释，请参阅 Bookmark 属性。

仅条件字符串形式的 Filters（例如 OrderDate > '12/31/1999'）影响持久保留的 Recordset 的内容。使用 Bookmarks 数组或使用 FilterGroupEnum 中的值创建的 Filters 对持久保留的 Recordset 的内容没有影响。这些值适用于使用客户端或服务器端游标创建的 Recordset。

注意 在批更新模式下将 adFilterPendingRecords 标志应用到已过滤和已修改的 Recordset 时，如果过滤是基于单键表中的键字段进行的，并且修改是针对键字段的值进行的，那么所得到的 Recordset 将是空的。如果下列任一条件为 True，那么所得到的 Recordset 将是非空的：
  • 过滤是基于单键表中的非键字段进行的。
  • 过滤是基于多键表中的任意字段进行的。
  • 修改是针对单键表中的非键字段进行的。
  • 修改是针对多键表中的任意字段进行的。
下表总结了在不同的过滤和修改组合情况下 adFilterPendingRecords 产生的结果。左列所示为可能的修改情况；修改可以是针对非键字段中的任何字段、单键表中的键字段或多键表中的任何键字段进行的。顶行所示为过滤条件；修改可以是针对非键字段中的任何字段、单键表中的键字段或多键表中的任何键字段进行的。交叉的单元格中所示为结果：+ 表示在非空的 Recordset 中应用 adFilterPendingRecords 结果；- 表示空的 Recordset。
 | 非键 | 单键 | 多键
非键 | + | + | +
单键 | + | - | N/A
多键 | + | N/A | +

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Clear 方法 | Optimize 动态属性 (ADO)

适用于：Recordset 对象


HelpContext 和 HelpFile 属性 (ADO)

ADO 2.5 API 参考

HelpContext 和 HelpFile 属性

指示与 Error 对象相关联的帮助文件和主题。

返回值

  • HelpContextID — 以 Long 值返回帮助文件中的主题的上下文 ID。
  • HelpFile — 返回 String 值，用于计算帮助文件的完整解析路径。

说明

如果在 HelpFile 属性中指定帮助文件，则 HelpContext 属性将用于自动显示它所标识的帮助主题。如果没有可用的相关帮助主题，HelpContext 属性将返回零，HelpFile 属性将返回零长度字符串 ("")。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Description 属性 | Number 属性 | Source 属性 (ADO Error)

适用于：Error 对象


Index 属性 (ADO)

ADO 2.5 API 参考

Index 属性

指示对 Recordset 对象当前生效的索引的名称。

设置和返回值

设置或返回 String 值，该值为索引的名称。

说明

由 Index 属性命名的索引必须已在 Recordset 对象的基本表上事先声明过。即索引必须已经在程序中声明为 ADOX Index 对象，或者在创建基本表时声明。

如果未设置索引，将发生运行时错误。下列情况下无法设置 Index 属性：

  • 在 WillChangeRecordset 或 RecordsetChangeComplete 事件处理程序中。
  • 如果 Recordset 仍在执行某项操作（由 State 属性确定）。
  • 如果已经用 Filter 属性在 Recordset 中设置了过滤。

Recordset 关闭时，始终可以成功设置 Index 属性。但如果基本提供者不支持索引，Recordset 将不能成功打开，或者索引将不可用。

如果可以设置索引，则当前行的位置可能发生更改。这将导致对 AbsolutePosition 属性的更新，以及发生 WillChangeRecordset、RecordsetChangeComplete、WillMove 和 MoveComplete 事件。

如果可以设置索引并且 LockType 属性为 adLockPessimistic 或 adLockOptimistic，则将执行隐式的 UpdateBatch 操作。这将释放当前组和受影响的组。所有现有的过滤器也将被释放，当前行的位置将被更改为经过重新排序的 Recordset 的第一行。

Index 属性与 Seek 方法一起使用。如果基本提供者不支持 Index 属性，由此也不支持 Seek 方法，请考虑使用 Find 方法。确定 Recordset 对象是否支持索引与 Supports (adIndex) 方法一起使用。

尽管二者均处理索引，但内置 Index 属性与动态的 Optimize 属性无关。

请参阅

Visual Basic 范例

Index 对象 | Seek 方法

适用于：Recordset 对象


IsolationLevel 属性 (ADO)

ADO 2.5 API 参考

IsolationLevel 属性

指示 Connection 对象的隔离级别。

设置和返回值

设置或返回 IsolationLevelEnum 值。默认值为 adXactChaos。

说明

用 IsolationLevel 属性设置 Connection 对象的隔离级别。该设置直到下次调用 BeginTrans 方法时才生效。如果请求的隔离级别不可用，提供者可能返回下一个更高的隔离级别。

IsolationLevel 属性为读/写。

远程数据服务用法 当在客户端 Connection 对象上使用时，IsolationLevel 属性只能设置为 adXactUnspecified。
由于用户正在使用客户端缓存中已断开连接的 Recordset 对象，因此可能出现多用户问题。例如，当两个用户试图更新同一个记录时，远程数据服务只允许先更新该记录的用户进行更新操作。第二个用户的请求将失败并产生错误。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

适用于：Connection 对象


Item 属性 (ADO)

ADO 2.5 API 参考

Item 属性

按名称或序号指示集合的特定成员。

语法

Set object = collection.Item ( Index )

返回值

返回对象引用。

参数

Index
Variant 表达式，计算集合中对象的名称或序号。

说明

使用 Item 属性返回集合中的特定对象。如果 Item 属性未能在集合中找到与 Index 参数相对应的对象，将产生错误。同时，一些集合不支持命名的对象。对于这些集合，必须使用序号引用。

Item 属性是所有集合的默认属性。因此，下列语法形式可互换：

collection.Item (Index)
collection (Index)

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

适用于：Axes 集合 | Columns 集合 | CubeDefs 集合 | Dimensions 集合 | Errors 集合 | Fields 集合 | Groups 集合 | Hierarchies 集合 | Indexes 集合 | Keys 集合 | Levels 集合 | Members 集合 | Parameters 集合 | Positions 集合 | Procedures 集合 | Properties 集合 | Tables 集合 | Users 集合 | Views 集合


LineSeparator 属性 (ADO)

ADO 2.5 API 参考

LineSeparator 属性

指示要在文本 Stream 对象中用作分行符的二进制字符。

设置和返回值

设置或返回 LineSeparatorsEnum 值，指示用在 Stream 中的分行符。默认值为 adCRLF。

说明

读取文本 Stream 的内容时，LineSeparator 用于解释行。可以用 SkipLine 方法跳过行。

LineSeparator 只能与文本 Stream 对象（Type 为 adTypeText）一起使用。如果 Type 为 adTypeBinary，则忽略此属性。

请参阅

适用于：Stream 对象


LockType 属性 (ADO)

ADO 2.5 API 参考

LockType 属性

指示编辑过程中记录上的锁定类型。

设置和返回值

设置或返回 LockTypeEnum 值。默认值为 adLockReadOnly。

说明

打开 Recordset 之前先设置 LockType 属性，以指定提供者打开它时使用的锁定类型。读取该属性以返回打开的 Recordset 对象中使用的锁定类型。

提供者可能不支持所有锁定类型。如果提供者不支持请求的 LockType 设置，则替换为另一种锁定类型。要确定 Recordset 对象中实际可用的锁定功能，请将 Supports 方法和 adUpdate 及 adUpdateBatch 一起使用。

如果 CursorLocation 属性设置为 adUseClient，则不支持 adLockPessimistic 设置。如果设置了不支持的值，将不产生错误，而使用所支持的最近似的 LockType。

LockType 属性在 Recordset 关闭时为读/写，而在 Recordset 打开时为只读。

远程数据服务用法 当在客户端的 Recordset 对象上使用时，LockType 属性只能设置为 adLockBatchOptimistic。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

CancelBatch 方法 | UpdateBatch 方法

适用于：Recordset 对象


MarshalOptions 属性 (ADO)

ADO 2.5 API 参考

MarshalOptions 属性

指示要调度回服务器的记录。

设置和返回值

设置或返回 MarshalOptionsEnum 值。默认值为 adMarshalAll。

说明

当使用客户端的 Recordset 时，客户端上修改的记录将通过称作调度的技术写回中间层或 Web 服务器，调度是指跨越线程或进程边界将接口方法参数打包并发送的进程。当修改过的远程数据通过调度被更新回中间层或 Web 服务器时，设置 MarshalOptions 属性可以提高性能。

远程数据服务用法 此属性只能在客户端的 Recordset 上使用。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

适用于：Recordset 对象


MaxRecords 属性 (ADO)

ADO 2.5 API 参考

MaxRecords 属性

指示由查询返回给 Recordset 的最大记录数目。

设置和返回值

设置或返回 Long 值，指示要返回的最大记录数目。默认值为零（无限制）。

说明

使用 MaxRecords 属性以限制提供者从数据源返回的记录数目。此属性的默认设置为零，表示提供者返回所有请求的记录。

MaxRecords 属性在 Recordset 关闭时为读写，而在 Recordset 打开时为只读。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

适用于：Recordset 对象


Mode 属性 (ADO)

ADO 2.5 API 参考

Mode 属性

指示在 Connection、Record 或 Stream 对象中修改数据的有效权限。

设置和返回值

设置或返回 ConnectModeEnum 值。对于 Connection，默认值为 adModeUnknown。对于 Record 对象，默认值为 adModeRead。对于与基本源相关联的 Stream（用 URL 将其作为源打开或者作为 Record 的默认 Stream 打开），默认值为 adModeRead。对于与基本源不关联的 Stream（在内存中实例化），默认值为 adModeUnknown。

说明

使用 Mode 属性设置或返回当前连接上提供者使用的访问权限。只有当 Connection 对象关闭时，才能设置 Mode 属性。

对于 Stream 对象，如果未指定访问模式，它将从用于打开 Stream 对象的源继承。例如，如果 Stream 是从 Record 对象打开的，默认情况下它将以打开 Record 对象相同的模式打开。

此属性在对象关闭时为读/写，在对象打开时为只读。

远程数据服务用法 当在客户端的 Connection 对象上使用时，Mode 属性只能设置为 adModeUnknown。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

适用于：Connection 对象 | Record 对象 | Stream 对象


Name 属性 (ADO)

ADO 2.5 API 参考

Name 属性

指示对象的名称。

设置和返回值

设置或返回 String 值，指示对象的名称。

说明

使用 Name 属性为 Command、Property、Field 或 Parameter 对象分配名称或检索名称。

该值对于 Command 对象为读/写，对于 Property 对象为只读。

对于 Field 对象，Name 通常为只读。但是，对于已追加到 Record 的 Fields 集合中的新 Field 对象，只有当已指定 Field 的 Value 属性并且数据提供者通过调用 Fields 集合的 Update 方法成功添加了新的 Field 时，Name 才为读/写。

对于尚未追加到 Parameters 集合的 Parameter 对象，Name 属性为读/写。对于已追加的 Parameter 对象和所有其他对象，Name 属性为只读。名称在集合中不必是唯一的。

可以按序号引用来检索对象的 Name 属性，然后便可以直接按名称引用该对象。例如，如果 rstMain.Properties(20).Name 产生 Updatability，随后便可以用 rstMain.Properties("Updatability") 来引用此属性。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

适用于：Command 对象 | Field 对象 | Parameter 对象 | Property 对象


NativeError 属性 (ADO)

ADO 2.5 API 参考

NativeError 属性

指示给定 Error 对象的提供者特有的错误代码。

返回值

返回 Long 值，指示错误代码。

说明

使用 NativeError 属性对某个 Error 对象检索数据库特有的错误信息。例如，当配合使用 Microsoft ODBC Provider for OLE DB 和 Microsoft SQL Server 数据库时，从 SQL Server 产生的原生错误代码将通过 ODBC 和 ODBC Provider 传递到 ADO NativeError 属性。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

适用于：Error 对象


Number 属性 (ADO)

ADO 2.5 API 参考

Number 属性

指示唯一标识 Error 对象的数字。

返回值

返回 Long 值，该值可能对应于一个 ErrorValueEnum 常量。

说明

使用 Number 属性确定发生了哪个错误。属性的值是与错误条件对应的唯一数字。

Errors 集合以十六进制格式（例如 0x80004005）或以 Long 值（例如 2147467259）返回 HRESULT。这些 HRESULT 由基本组件生成，如 OLE DB，甚至是 OLE 本身。有关这些数字的详细信息，请参阅 OLE DB Programmer's Reference 的 Chapter 16。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Description 属性 | HelpContext 和 HelpFile 属性 | Source 属性 (ADO Error)

适用于：Error 对象


NumericScale 属性 (ADO)

ADO 2.5 API 参考

NumericScale 属性

指示 Parameter 或 Field 对象中数字值的范围。

设置和返回值

设置或返回 Byte 值，指示数字值要精确的小数位数。

说明

使用 NumericScale 属性来确定数字型 Parameter 或 Field 对象的值的小数位数。

对于 Parameter 对象，NumericScale 属性为读/写。

对于 Field 对象，NumericScale 通常为只读。但是，对于已追加到 Record 的 Fields 集合中的新 Field 对象，只有当 Field 的 Value 属性已被指定并且数据提供者通过调用 Fields 集合的 Update 方法成功添加了新的 Field 时，NumericScale 才为读/写。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Precision 属性

适用于：Field 对象 | Parameter 对象


OriginalValue 属性 (ADO)

ADO 2.5 API 参考

OriginalValue 属性

指示发生任何更改前记录中已经存在的 Field 的值。

返回值

返回 Variant 值，表示更改前字段的值。

说明

用 OriginalValue 属性返回当前记录中某字段的原始字段值。

在“立即更新模式”（在此模式下，调用 Update 方法后提供者便把更改写入基本数据源）下，OriginalValue 属性返回更改前（即自从最后一次调用 Update 方法）存在的字段值。它与 CancelUpdate 方法用来替换 Value 属性的值相同。

在“批更新模式”（在此模式下，只有当调用 UpdateBatch 方法时，提供者才将多个更改存入缓存并将它们写入基本数据源）下，OriginalValue 属性返回更改前（即自从最后一次调用 UpdateBatch 方法）存在的字段值。它与 CancelBatch 方法用来替换 Value 属性的值相同。当将此属性与 UnderlyingValue 属性配合使用时，可以解决批更新时出现的冲突。

记录

对于 Record 对象，调用 Update 前添加的字段的 OriginalValue 属性将为空。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

UnderlyingValue 属性

适用于：Field 对象


PageCount 属性 (ADO)

ADO 2.5 API 参考

PageCount 属性

指示 Recordset 对象包含的数据页数。

返回值

返回 Long 值，指示 Recordset 中的页数。

说明

用 PageCount 属性确定 Recordset 对象中的数据页数。Pages 是大小与 PageSize 属性设置相等的记录组。即使最后一页因为记录比 PageSize 值少而不完整，在 PageCount 值中仍作为附加页计数。如果 Recordset 对象不支持此属性，则该值为 -1，指示 PageCount 无法确定。

有关页的功能的详细信息，请参阅 PageSize 和 AbsolutePage 属性。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

AbsolutePage 属性 | PageSize 属性 | RecordCount 属性

适用于：Recordset 对象


PageSize 属性 (ADO)

ADO 2.5 API 参考

PageSize 属性

指示 Recordset 中一页包含的记录数目。

设置和返回值

设置或返回 Long 值，指示一页上的记录数目。默认值为 10。

说明

用 PageSize 属性确定组成一个数据逻辑页的记录数目。建立页大小允许用 AbsolutePage 属性移动到特定页的第一个记录。如果要在 Web 服务器方案中允许用户对数据进行分页，那么此属性将非常有用，可以一次查看一定数量的记录。

可以随时设置此属性，其值将用来计算特定页的第一个记录的位置。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

AbsolutePage 属性 | PageCount 属性

适用于：Recordset 对象


ParentRow 属性 (ADO)

ADO 2.5 API 参考

ParentRow 属性

在 ADORecordConstruction 对象上设置 OLE DB Row 对象的容器，以将父行转换为 ADO Record 对象。

只写。

语法

HRESULT put_ParentRow([in] IUnknown* pParent);

参数

pParent
行的容器。

返回值

此属性方法返回标准的 HRESULT 值，包括 S_OK 和 E_FAIL。

适用于

ADORecordConstruction


ParentURL 属性 (ADO)

ADO 2.5 API 参考

ParentURL 属性

指示指向当前 Record 对象的父 Record 的绝对 URL 字符串。

返回值

返回 String 值，指示父 Record 的 URL。

说明

ParentURL 属性依赖于用于打开 Record 对象的源。例如，可以用包含 ActiveConnection 属性所引用的目录的相关路径名的源打开 Record。

假设“second”是包含在“first”中的文件夹。用下列代码打开 Record 对象：

record.ActiveConnection = "http://first"
record.Open "second"

现在，ParentURL 属性的值为 "http://first"，与 ActiveConnection 的值相同。

源也可以是一个绝对 URL，如 "http://first/second"。ParentURL 属性的值则为 "http://first"，它是 "second" 的上一层。

在下列情况下，此属性为 Null 值：

  • 当前对象没有父对象。例如，如果 Record 对象表示目录的根。
  • Record 对象表示使用 URL 不能指定的项目。

此属性是只读的。

注意 此属性只受文档的源提供者（如 Microsoft OLE DB Provider for Internet Publishing）支持。有关详细信息，请参阅记录和提供者提供的字段。
注意 使用 http 模式的 URL 将自动调用 Microsoft OLE DB Provider for Internet Publishing。有关详细信息，请参阅绝对和相对 URL。
注意 如果当前记录包含 ADO Recordset 中的数据记录，那么访问 ParentURL 属性将导致运行时错误，指示可能没有 URL。

请参阅

适用于：Record 对象


Position 属性 (ADO)

ADO 2.5 API 参考

Position 属性

指示在 Stream 对象中的当前位置。

设置和返回值

设置或返回 Long 值，指定流开始处到当前位置的偏移字节数。默认值为 0，表示流中的第一个字节。

说明

可将当前位置移动到流的结尾处后面的一点。如果在流结尾处以外的地方指定当前位置，Stream 对象的 Size 也将随之增加。所有以这种方式添加的新字节都将为 Null。

注意 Position 始终度量字节。对于使用多字节字符集的文本流，请将位置与字符大小相乘以确定字符数。例如，对于双字节字符集，第一个字符位置为 0，第二个字符位置为 2，第三个字符位置为 4，依此类推。
不能用负值更改 Stream 中的当前位置。只有正数才能用于 Position。
对于只读 Stream 对象，如果设置的 Position 值超过 Stream 的 Size，ADO 将不返回错误。这不会更改 Stream 的大小，也不会以任何方式改变 Stream 的内容。但是，应避免这种操作，因为它可能产生无意义 Position 值。

请参阅

范例

Charset 属性

适用于：Stream 对象


Precision 属性 (ADO)

ADO 2.5 API 参考

Precision 属性

指示 Parameter 对象中的数字值的精度或数字型 Field 对象的精度。

设置和返回值

设置或返回 Byte 值，指示表示值的最大位数。

说明

用 Precision 属性确定表示数字型 Parameter 或 Field 对象值的最大位数。

对于 Parameter 对象，该值为读/写。

对于 Field 对象，Precision 通常为只读。但是，对于已追加到 Record 的 Fields 集合的新 Field 对象，只有当已指定 Field 的 Value 属性并且数据提供者通过调用 Fields 集合的 Update 方法成功添加了新 Field 时，Precision 才为读/写。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

NumericScale 属性

适用于：Field 对象 | Parameter 对象


Prepared 属性 (ADO)

ADO 2.5 API 参考

Prepared 属性

指示执行前是否保存命令的编译版本。

设置和返回值

设置或返回 Boolean 值，如果设置为 True，则指示要准备的命令。

说明

用 Prepared 属性将提供者保存为查询的已准备好（或已编译）版本，该查询是第一次执行 Command 对象前在 CommandText 属性中指定的。这可能会降低命令第一次执行的速度，但一旦提供者编译一个命令后，便可将命令的编译版本用于所有后续的执行中，这样便可提高性能。

如果该属性为 False，提供者将直接执行 Command 对象而不创建编译版本。

如果提供者不支持命令准备，则一旦将此属性设置为 True，提供者便可能返回错误。如果它不返回错误，则仅忽略准备命令的请求，并将 Prepared 属性设置为 False。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

适用于：Command 对象


Provider 属性 (ADO)

ADO 2.5 API 参考

Provider 属性

指示 Connection 对象的提供者的名称。

设置和返回值

设置或返回 String 值，指示提供者的名称。

说明

用 Provider 属性设置或返回连接的提供者名称。也可用 ConnectionString 属性的内容或 Open 方法的 ConnectionString 参数来设置此属性。但是，当调用 Open 方法时，如果在多个地方指定提供者，将可能导致无法预测的结果。如果未指定提供者，该属性将默认使用 MSDASQL (Microsoft OLE DB Provider for ODBC)。

Provider 属性在连接关闭时为读/写，在连接打开时为只读。只有当打开 Connection 对象或访问 Connection 对象的 Properties 集合时，设置才生效。如果设置无效，则将产生错误。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Microsoft OLE DB Provider for ODBC | Appendix A: Providers

适用于：Connection 对象


RecordCount 属性 (ADO)

ADO 2.5 API 参考

RecordCount 属性

指示 Recordset 对象中的记录数目。

返回值

返回 Long 值，指示 Recordset 中的记录数目。

说明

用 RecordCount 属性查找 Recordset 对象中的记录数目。如果 ADO 无法确定记录数目或者提供者或游标类型不支持 RecordCount，该属性将返回 -1。读取已关闭的 Recordset 的 RecordCount 属性将产生错误。

如果 Recordset 对象支持近似定位或书签（即 Supports (adApproxPosition) 或 Supports (adBookmark) 分别返回 True），那么不管是否已被完全预置，此值都将是 Recordset 中的记录的确切数目。如果 Recordset 对象不支持近似定位，此属性可能会由于必须对所有记录进行检索和计数以返回精确的 RecordCount 值而严重消耗资源。

Recordset 对象的游标类型将影响是否能确定记录的数目。对于仅向前游标，RecordCount 属性将返回 -1；对于静态或键集游标，将返回实际计数；而对于动态游标，则返回 -1 或实际计数，这取决于数据源。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

AbsolutePosition 属性 | PageCount 属性

适用于：Recordset 对象


RecordType 属性 (ADO)

ADO 2.5 API 参考

RecordType 属性

指示 Record 对象的类型。

返回值

返回 RecordTypeEnum 值。

说明

RecordType 属性为只读。

请参阅

范例

Type 属性 | Type 属性 (ADO Stream)

适用于：Record 对象


Row 属性 (ADO)

ADO 2.5 API 参考

Row 属性

从/在 ADORecordConstruction 对象上获得或设置 OLE DB Row 对象。使用 put_Row 设置 Row 对象时，便将行转换为 ADO Record 对象。

读/写。语法

HRESULT get_Row([out, retval] IUnknown** ppRow);
HRESULT put_Row([in] IUnknown* pRow);

参数

ppRow
指针，指向 OLE DB Row 对象。
PRow
OLE DB Row 对象。

返回值

此属性方法返回标准的 HRESULT 值，包括 S_OK 和 E_FAIL。

适用于

ADORecordConstruction


RowPosition 属性 (ADO)

ADO 2.5 API 参考

RowPosition 属性

从/在 ADORecordsetConstruction 对象上获得或设置 OLE DB RowPosition 对象。使用 put_RowPosition 设置 RowPosition 对象时，所得到的 Recordset 对象将使用 RowPosition 对象确定当前行。

读/写。

语法

HRESULT get_RowPosition([out, retval] IUnknown** ppRowPos);
HRESULT put_RowPosition([in] IUnknown* pRowPos);

参数

ppRowPos
指针，指向 OLE DB RowPosition 对象。
PRowPos
OLE DB RowPosition 对象。

返回值

此属性方法返回标准的 HRESULT 值，包括 S_OK 和 E_FAIL。

说明

设置此属性时，如果 RowPosition 对象上的 Rowset 对象与 Recordset 对象上的 Rowset 对象不相同，那么前者将覆盖后者。同样的行为还适用于 RowPosition 的当前 Chapter。

适用于

ADORecordsetConstruction


Rowset 属性 (ADO)

ADO 2.5 API 参考

Rowset 属性

从/在 ADORecordsetConstruction 对象上获得或设置 OLE DB Rowset 对象。使用 put_Rowset 进行设置时，便将行集合转换为 ADO Recordset 对象。

读/写。

语法

HRESULT get_Rowset([out, retval] IUnknown** ppRowset);
HRESULT put_Rowset([in] IUnknown* pRowset);

参数

ppRowset
指针，指向 OLE DB Rowset 对象。
PRowset
OLE DB Rowset 对象。

返回值

此属性方法返回标准的 HRESULT 值，包括 S_OK 和 E_FAIL。

适用于

ADORecordsetConstruction


Size 属性 (ADO)

ADO 2.5 API 参考

Size 属性

指示 Parameter 对象的最大字节或字符大小。

设置和返回值

设置或返回 Long 值，指示 Parameter 对象的最大字节或字符大小。

说明

用 Size 属性确定写入 Parameter 对象的 Value 属性中或从中读取的值的最大大小。

如果要指定 Parameter 对象的变长数据类型（例如所有 String 类型，如 adVarChar），必须先设置对象的 Size 属性，然后再将该对象追加到 Parameters 集合。否则，将会产生错误。

如果已经将 Parameter 对象追加到 Command 对象的 Parameters 集合中，并将其类型更改为变长数据类型，则必须先设置 Parameter 对象的 Size 属性，然后再执行 Command 对象。否则，将发生错误。

如果使用 Refresh 方法从提供者获取参数信息，并且返回一个或多个变长数据类型 Parameter 对象，ADO 可能会根据其可能的最大尺寸为这些参数分配内存空间，这在执行过程中可能会导致错误。若要避免错误，在执行命令前应显式地设置这些参数的 Size 属性。

Size 属性为读/写。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例 | JScript 范例

Size 属性 (ADO Stream)

适用于：Parameter 对象


Size 属性 (ADO Stream)

指示流的字节数。

返回值

返回 Long 值，指定流的字节数。默认值为流的大小，如果不知道流的大小，则该值为 -1。

说明

Size 只能与打开的 Stream 对象配合使用。

注意 Stream 对象中可以存储任意多个位，它仅受系统资源限制。如果 Stream 包含的位数超过 Long 值所能表示的位数，Size 将被截断因而不能精确表示 Stream 的长度。

请参阅

Size 属性

适用于：Stream 对象


Sort 属性 (ADO)

ADO 2.5 API 参考

Sort 属性

指示一个或多个作为 Recordset 排序基准的字段名，并指示按升序还是降序对每个字段进行排序。

设置和返回值

设置或返回 String 值，指示要作为 Recordset 排序基准的字段名称。每个名称均由逗号隔开，（可选）后面跟空格和关键字 ASC（按升序对字段进行排序）或 DESC（按降序对字段进行排序）。如果未指定关键字，默认情况下将按升序对字段进行排序。

说明

此属性要求将 CursorLocation 属性设置为 adUseClient。如果索引已不存在，则将为 Sort 属性中指定的每个字段创建临时索引。

由于并没有对数据进行物理上的重新排列，因此排序操作仍有效，只不过是按索引指定的顺序进行访问。

将 Sort 属性设置为空字符串将会把行重置为原始顺序并删除临时索引。现有的索引不会被删除。

假设 Recordset 包含三个字段，名称为 firstName、middleInitial 和 lastName。如果将 Sort 属性设置为字符串“lastName DESC, firstName ASC”，则会按姓氏对 Recordset 进行降序排序，然后按名字进行升序排序。中间名被忽略。

不能将字段命名为“ASC”或“DESC”，因为这些名称与关键字 ASC 和 DESC 相冲突。请使用返回 Recordset 的查询中的 AS 关键字来为有名称冲突的字段设置别名。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Optimize 动态属性 (ADO) | SortColumn 属性 (RDS) | SortDirection 属性 (RDS)

适用于：Recordset 对象


Source 属性 (ADO Error)

指示最初产生错误的对象或应用程序的名称。

返回值

返回 String 值，指示对象或应用程序的名称。

说明

使用 Error 对象的 Source 属性以确定最初产生错误的对象或应用程序的名称。它可能是对象的类名称或编程 ID。对于 ADO 中的错误，属性值将为 ADODB.ObjectName，此 ObjectName 为触发错误的对象名称。对于 ADOX 和 ADO MD，该值将分别为 ADOX ObjectName 和 ADOMD ObjectName。

基于 Error 对象的 Source、Number 和 Description 属性中的错误文档，可以编写处理错误的适当代码。

对于 Error 对象，Source 属性为只读。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Description 属性 | HelpContext 和 HelpFile 属性 | Number 属性 | Source 属性 (ADO Record) | Source 属性 (ADO Recordset)

适用于：Error 对象


Source 属性 (ADO Record)

指示由 Record 表示的数据源或对象。

设置和返回值

设置或返回 Variant 值，指示由 Record 表示的项目。

说明

Source 属性返回 Record 对象 Open 方法的 Source 参数。它可包含绝对或相对 URL 字符串。可用绝对 URL 直接打开 Record 对象而无须设置 ActiveConnection 属性。在这种情况下，将创建隐式的 Connection 对象。

Source 属性也可以包含对已打开的 Recordset 的引用，该 Recordset 打开表示 Recordset 中的当前行的 Record 对象。

Source 属性也可以包含对 Command 对象的引用，该对象从提供者返回单行数据。

如果还设置了 ActiveConnection 属性，则 Source 属性必须指向存在于该连接范围内的某个对象。例如，在树状结构的名称空间中，如果 Source 属性包含绝对 URL，它必须指向节点范围内的节点，该节点范围由连接字符串中的 URL 标识。如果 Source 属性包含相对 URL，则它在由 ActiveConnection 属性设置的上下文中有效。

Source 属性在 Record 对象关闭时为读/写，在 Record 对象打开时为只读。

注意 使用 http 模式的 URL 将自动调用 Microsoft OLE DB Provider for Internet Publishing。有关详细信息，请参阅绝对和相对 URL。

请参阅

Source 属性 (ADO Error) | Source 属性 (ADO Recordset)

适用于：Record 对象


Source 属性 (ADO Recordset)

指示 Recordset 对象的数据源。

设置和返回值

设置 String 值或 Command 对象引用；只返回指示 Recordset 的源的 String 值。

说明

用 Source 属性指定使用下列内容之一的 Recordset 对象的数据源：Command 对象变量、SQL 语句、存储过程或表名。

如果将 Source 属性设置为 Command 对象，则 Recordset 对象的 ActiveConnection 属性将继承指定 Command 对象的 ActiveConnection 属性的值。但是，读取 Source 属性不会返回 Command 对象，而是返回 Command 对象（该对象的 Source 属性被设置）的 CommandText 属性。

如果 Source 属性是一个 SQL 语句、存储过程或表名，则可以通过调用 Open 方法传递相应的 Options 参数来优化性能。

Source 属性在 Recordset 对象关闭时为读/写，在 Recordset 打开时为只读。

请参阅

Visual Basic 范例

Source 属性 (ADO Error) | Source 属性 (ADO Record)

适用于：Recordset 对象


SQLState 属性 (ADO)

ADO 2.5 API 参考

SQLState 属性

指示给定 Error 对象的 SQL 状态。

返回值

返回符合 ANSI SQL 标准的五个字符的 String 值，用于指示错误代码。

说明

如果在处理 SQL 语句过程中发生错误，请用 SQLState 属性读取提供者返回的五个字符的错误代码。例如，当配合使用 Microsoft OLE DB Provider for ODBC 和 Microsoft SQL Server 数据库时，将根据 ODBC 特有的错误或 Microsoft SQL Server 生成的错误从 ODBC 生成 SQL 状态错误代码，并将错误代码映射到 ODBC 错误上。这些错误代码在 ANSI SQL 标准中有说明，但是如果数据源不同，其实现方式也会不同。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

适用于：Error 对象


State 属性 (ADO)

ADO 2.5 API 参考

State 属性

对所有适用的对象，指示该对象状态是打开的还是关闭的。

指示对所有可应用的对象执行异步方法，指示对象的当前状态是正在连接、正在执行还是正在检索。

返回值

返回可能是 ObjectStateEnum 值的 Long 值。默认值为 adStateClosed。

说明

可以随时用 State 属性确定给定对象的当前状态。

对象的 State 属性可以是值的组合。例如，如果正在执行某个语句，此属性将有一个 adStateOpen 和 adStateExecuting 的组合值。

State 属性为只读。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

适用于：Command 对象 | Connection 对象 | Record 对象 | Recordset 对象 | Stream 对象


Status 属性 (ADO Field)

指示 Field 对象的状态。

返回值

返回 FieldStatusEnum 值。默认值为 adFieldOK。

说明

对于 Recordset 对象的字段，此属性始终返回 adFieldOK。

调用 Update 方法前，对 Record 对象的 Fields 集合所做的添加和删除将一直保存在缓存中。Status 属性使您能够确定哪些字段已被成功添加或删除。

为了提高性能，调用 Update 前模式更改将一直保存在缓存中，然后在开放式批更新中进行更改。如果未调用 Update 方法，服务器将不会被更新。如果更新失败，将返回错误，并且 Status 属性指示该操作的组合值和错误状态代码。例如，adFieldPendingInsert OR adFieldPermissionDenied。每个 Field 的 Status 属性均可用于确定该 Field 未被添加、修改或删除的原因。Status 只有显露在 Record.Fields 集合而非 Recordset.Fields 集合中才有意义。

添加、修改或删除 Field 时可能出现两个问题。如果用户删除 Field，则它在 Fields 集合中被标记为删除。如果由于用户在不具备权限的情况下试图删除 Field 而使后续的 Update 返回错误，Field 的状态将为 adFieldPermissionDenied OR adFieldPendingDelete。调用 CancelUpdate 方法可恢复初始值并可将 Status 设置为 adFieldOK。与之类似，如果添加了新的 Field 并赋予其不适当的值，Update 方法可能会因此返回错误。在这种情况下，新的 Field 将位于 Fields 集合中，其状态为 adFieldPendingInsert，也可能为 adFieldCantCreate。可以为新的 Field 提供一个适当的值并再次调用 Update。请注意，调用 Resync 需要提供者。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

适用于：Field 对象

© 1998-2002 Microsoft Corporation。保留所有权利。


Status 属性 (ADO Recordset)

指示有关批更新或其他大量操作的当前记录的状态。

返回值

返回一个或多个 RecordStatusEnum 值的和。

说明

用 Status 属性查看在批更新过程中修改的记录的挂起更改。也可以用 Status 属性查看在大量操作过程中失败的记录的状态。例如，当调用 Recordset 对象的 Resync、UpdateBatch 或 CancelBatch 方法时，或者将 Recordset 对象的 Filter 属性设置为书签数组时。用此属性可以确定给定记录失败的原因，并相应地加以解决。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

适用于：Recordset 对象


StayInSync 属性 (ADO)

ADO 2.5 API 参考

StayInSync 属性

指示在分级 Recordset 对象中，当父行位置更改时，对基本子记录（即“子集”）的引用是否会更改。

设置和返回值

设置或返回 Boolean 值。默认值是 True。如果为 True，则当父 Recordset 对象更改行位置时子集将被更新；如果为 False，则即使父 Recordset 对象已更改行位置，子集仍将继续引用以前子集中的数据。

说明

此属性应用于分级 Recordset（例如由 Microsoft Data Shaping Service for OLE DB 支持的记录集），而且在检索子 Recordset 前必须先在父 Recordset 上设置该属性。此属性可以简化分级记录集的定位。

请参阅

Visual Basic 范例

Microsoft Data Shaping Service for OLE DB

适用于：Recordset 对象


Type 属性 (ADO)

ADO 2.5 API 参考

Type 属性

指示 Parameter、Field 或 Property 对象的可操作类型或数据类型。

设置和返回值

设置或返回 DataTypeEnum 值。

说明

对于 Parameter 对象，Type 属性为读/写。对于已追加到 Record 的 Fields 集合中的新 Field 对象，只有当 Field 的 Value 属性已被指定并且数据提供者通过调用 Fields 集合的 Update 方法成功添加了新的 Field 时，Type 才为读/写。

对于其他所有对象，Type 属性为只读。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

RecordType 属性 | Type 属性 (ADO Stream)

适用于：Field 对象 | Parameter 对象 | Property 对象


Type 属性 (ADO Stream)

指示 Stream 中包含的数据的类型（二进制或文本）。

设置和返回值

设置或返回 StreamTypeEnum 值，用于指定包含在 Stream 对象中的数据类型。默认值为 adTypeText。但如果二进制数据最初被写入新的空 Stream 中，Type 将被更改为 adTypeBinary。

说明

只有在当前位置位于 Stream 的开始处（Position 为 0）时，Type 属性才为读/写；位于其他位置时均为只读。

Type 属性确定读写 Stream 所使用的方法。对于文本 Stream 对象，请使用 ReadText 和 WriteText。对于二进制 Stream，请使用 Read 和 Write。

请参阅

范例

RecordType 属性 | Type 属性

适用于：Stream 对象


UnderlyingValue 属性 (ADO)

ADO 2.5 API 参考

UnderlyingValue 属性

指示数据库中 Field 对象的当前值。

返回值

返回 Variant 值，用于指示 Field 的值。

说明

用 UnderlyingValue 属性从数据库中返回当前字段值。UnderlyingValue 属性中的字段值是事务的可视值，它可能是另一事务最近更新的结果。这可能与 OriginalValue 属性不同，因为 OriginalValue 属性反映最初返回到 Recordset 的值。

这与使用 Resync 方法类似，但 UnderlyingValue 属性只从当前记录返回特定字段的值。该值与 Resync 方法用来替换 Value 属性的值相同。

将此属性与 OriginalValue 属性配合使用可以解决批更新时出现的冲突。

记录

对于 Record 对象，调用 Update 前添加的字段的此属性为空。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

OriginalValue 属性 | Resync 方法

适用于：Field 对象


Value 属性 (ADO)

ADO 2.5 API 参考

Value 属性

指示分配给 Field、Parameter 或 Property 对象的值。

设置和返回值

设置或返回 Variant 值，用于指示对象的值。默认值取决于 Type 属性。

说明

用 Value 属性设置或返回 Field 对象中的数据，与 Parameter 对象一起使用来设置或返回参数值，或者与 Property 对象一起使用来设置或返回属性设置。Value 属性为读/写还是只读取决于很多因素。有关详细信息，请参阅对应的对象主题。

ADO 允许用 Value 属性设置和返回长二进制数据。

注意 对于 Parameter 对象，ADO 只从提供者读取 Value 属性一次。如果命令包含其 Value 属性为空的 Parameter，并且在命令中创建了 Recordset，请确保检索 Value 属性前先关闭 Recordset。否则，对于某些提供者，Value 属性可能为空，不会包含正确的值。
对于已追加到 Record 对象的 Fields 集合中的新 Field 对象，必须先设置 Value 属性，然后才可指定任何其他的 Field 属性。首先必须给 Value 属性分配特定的值，并且调用 Fields 集合的 Update。然后再访问其他属性（如 Type 或 Attributes）。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

适用于：Field 对象 | Parameter 对象 | Property 对象


Version 属性 (ADO)

ADO 2.5 API 参考

Version 属性

指示 ADO 版本号。

返回值

返回 String 值，用于指示版本。

说明

使用 Version 属性返回 ADO 的版本号。

提供者的版本可以从 Properties 集合中作为动态属性获得。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

适用于：Connection 对象


ADO 动态属性

可以向 Connection、Command 或 Recordset 对象的 Properties 集合中添加动态属性。这些属性的源可以是数据提供者（如 OLE DB Provider for SQL Server），也可以是服务提供者（如 Microsoft Cursor Service for OLE DB）。有关特定动态属性的详细信息，请参阅相应的数据提供者或服务提供者的文档。

ADO 动态属性索引为每个标准的 OLE DB 提供者动态属性提供了 ADO 和 OLE DB 名称之间的交叉引用。

以下动态属性具有特殊意义，在上面提到的源中也有说明。在下列 ADO 帮助主题中说明了 ADO 的特殊功能。

Optimize | 指定在此字段上是否创建索引。
Prompt | 指定 OLE DB 提供者是否提示用户输入初始化信息。
Reshape Name | 为 Recordset 对象指定一个名称。
Resync Command | 指定由 Resync 方法发出的用户提供的命令字符串，用于刷新在 Unique Table 动态属性中命名的表中的数据。
Unique Table、Unique Schema 和 Unique Catalog | Unique Table — 指定允许在其中进行更新、插入和删除的基本表的名称。 Unique Schema — 指定表的所有者的模式或名称。 Unique Catalog — 指定包含该表的数据库的目录或名称。
Update Resync | 指定 UpdateBatch 方法后面是否跟随隐式的 Resync 方法操作，如果是，则指定操作的范围。

请参阅

ADO API 参考 | ADO 集合 | ADO 枚举常量 | ADO 错误 | ADO 事件 | ADO 方法 | ADO 对象模型 | ADO 对象 | ADO 属性


ADO 动态属性索引

数据提供者、服务提供者和服务组件能够向未打开的 Connection 和 Recordset 对象的 Properties 集合中添加动态属性。当这些对象打开时，给定的提供者还可以插入附加属性。这些属性的一部分在“ADO 动态属性”一节中列出。其他属性列在“附录 A：提供者”一节中的特定提供者下。

下表是每个标准 OLE DB 提供者动态属性的 ADO 和 OLE DB 名称的交叉索引。提供者可以添加比此处所列的属性更多的属性。有关提供者特有的动态属性的特定信息，请参阅提供者的文档。

OLE DB Programmer's Reference 使用“Description”项引用 ADO 属性名称。有关这些标准属性的详细信息，请参阅 OLE DB Programmer's Reference。请在 Index 中搜索 OLE DB 属性名称或参阅以下主题：

  • Appendix C: OLE DB Properties
  • Supported Properties of the Cursor Service
  • Supported Properties of the Persistence Provider
  • Supported OLE DB Properties of the Remoting Provider

说明

用于交叉索引的注释数码：

(1) 此属性为 Boolean 标志，指示是否应使用已命名的接口。如果存在等价的 OLE DB 属性名称，将其列出。

(2) ADO 属性“Bookmarkable”是为向后兼容而在内部生成的，并被映射到 OLE DB 属性 DBPROP_IROWSETLOCATE。这是与 ADO 属性 IRowsetLocate 相对应的同一个属性。

(3) 对 ADO 属性“Hidden Columns”的命名不同于 OLE DB 属性名称的说明“Hidden Columns Count”。

(4) 对于分级记录集，“Maximum Rows”ADO 属性在所有子之间得到应用。根据返回行的顺序不同，您可能拥有每个父的全部、部分或零个子，也可能拥有生成的记录集中的孤立子。因此，重构形分级记录集时，每个子的标识符应当是唯一的。通常，Microsoft Data Shaping Service for OLE DB (MSDATASHAPE) 提供者不考虑可以从父继承的属性与不可从父继承的属性之间的区别。

(5) 不适用。

Connection 动态属性

ADO 属性名称 | OLE DB 属性名称
Active Sessions | DBPROP_ACTIVESESSIONS
Asynchable Abort | DBPROP_ASYNCTXNABORT
Asynchable Commit | DBPROP_ASYNCTNXCOMMIT
Autocommit Isolation Levels | DBPROP_SESS_AUTOCOMMITISOLEVELS
Catalog Location | DBPROP_CATALOGLOCATION
Catalog Term | DBPROP_CATALOGTERM
Column Definition | DBPROP_COLUMNDEFINITION
Connect Timeout | DBPROP_INIT_TIMEOUT
Current Catalog | DBPROP_CURRENTCATALOG
Data Source | DBPROP_INIT_DATASOURCE
Data Source Name | DBPROP_DATASOURCENAME
Data Source Object Threading Model | DBPROP_DSOTHREADMODEL
DBMS Name | DBPROP_DBMSNAME
DBMS Version | DBPROP_DBMSVER
Extended Properties | DBPROP_INIT_PROVIDERSTRING
GROUP BY Support | DBPROP_GROUPBY
Heterogeneous Table Support | DBPROP_HETEROGENEOUSTABLES
Identifier Case Sensitivity | DBPROP_IDENTIFIERCASE
Initial Catalog | DBPROP_INIT_CATALOG
Isolation Levels | DBPROP_SUPPORTEDTXNISOLEVELS
Isolation Retention | DBPROP_SUPPORTEDTXNISORETAIN
Locale Identifier | DBPROP_INIT_LCID
Location | DBPROP_INIT_LOCATION
Maximum Index Size | DBPROP_MAXINDEXSIZE
Maximum Row Size | DBPROP_MAXROWSIZE
Maximum Row Size Includes BLOB | DBPROP_MAXROWSIZEINCLUDESBLOB
Maximum Tables in SELECT | DBPROP_MAXTABLESINSELECT
Mode | DBPROP_INIT_MODE
Multiple Parameter Sets | DBPROP_MULTIPLEPARAMSETS
Multiple Results | DBPROP_MULTIPLERESULTS
Multiple Storage Objects | DBPROP_MULTIPLESTORAGEOBJECTS
Multi-Table Update | DBPROP_MULTITABLEUPDATE
NULL Collation Order | DBPROP_NULLCOLLATION
NULL Concatenation Behavior | DBPROP_CONCATNULLBEHAVIOR
OLE DB Services | DBPROP_INIT_OLEDBSERVICES
OLE DB Version | DBPROP_PROVIDEROLEDBVER
OLE Object Support | DBPROP_OLEOBJECTS
Open Rowset Support | DBPROP_OPENROWSETSUPPORT
ORDER BY Columns in Select List | DBPROP_ORDERBYCOLUMNSINSELECT
Output Parameter Availability | DBPROP_OUTPUTPARAMETERAVAILABILITY
Pass By Ref Accessors | DBPROP_BYREFACCESSORS
Password | DBPROP_AUTH_PASSWORD
Persist Security Info | DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO
Persistent ID Type | DBPROP_PERSISTENTIDTYPE
Prepare Abort Behavior | DBPROP_PREPAREABORTBEHAVIOR
Prepare Commit Behavior | DBPROP_PREPARECOMMITBEHAVIOR
Procedure Term | DBPROP_PROCEDURETERM
Prompt | DBPROP_INIT_PROMPT
Provider Friendly Name | DBPROP_PROVIDERFRIENDLYNAME
Provider Name | DBPROP_PROVIDERFILENAME
Provider Version | DBPROP_PROVIDERVER
Read-Only Data Source | DBPROP_DATASOURCEREADONLY
Rowset Conversions on Command | DBPROP_ROWSETCONVERSIONSONCOMMAND
Schema Term | DBPROP_SCHEMATERM
Schema Usage | DBPROP_SCHEMAUSAGE
SQL Support | DBPROP_SQLSUPPORT
Structured Storage | DBPROP_STRUCTUREDSTORAGE
Subquery Support | DBPROP_SUBQUERIES
Table Term | DBPROP_TABLETERM
Transaction DDL | DBPROP_SUPPORTEDTXNDDL
User ID | DBPROP_AUTH_USERID
User Name | DBPROP_USERNAME
Window Handle | DBPROP_INIT_HWND

Recordset 动态属性

注意，当 Recordset 关闭时，Recordset 对象的动态属性将不起作用（变得不可用）。

ADO 属性名称 | OLE DB 属性名称
IAccessor | DBPROP_IACCESSOR (1)
IChapteredRowset | (1)
IColumnsInfo | DBPROP_ICOLUMNSINFO (1)
IColumnsRowset | DBPROP_ICOLUMNSROWSET (1)
IConnectionPointContainer | DBPROP_ICONNECTIONPOINTCONTAINER (1)
IConvertType | (1)
ILockBytes | DBPROP_ILOCKBYTES (1)
IRowset | DBPROP_IROWSET (1)
IDBAsynchStatus | DBPROP_IDBASYNCHSTATUS (1)
IParentRowset | (1)
IRowsetChange | DBPROP_IROWSETCHANGE (1)
IRowsetExactScroll | (1)
IRowsetFind | DBPROP_IROWSETFIND (1)
IRowsetIdentity | DBPROP_IROWSETIDENTITY (1)
IRowsetInfo | DBPROP_IROWSETINFO (1)
IRowsetLocate | DBPROP_IROWSETLOCATE (1)
IRowsetRefresh | DBPROP_IROWSETREFRESH (1)
IRowsetResynch | (1)
IRowsetScroll | DBPROP_IROWSETSCROLL (1)
IRowsetUpdate | DBPROP_IROWSETUPDATE (1)
IRowsetView | DBPROP_IROWSETVIEW (1)
IRowsetIndex | DBPROP_IROWSETINDEX (1)
ISequentialStream | DBPROP_ISEQUENTIALSTREAM (1)
IStorage | DBPROP_ISTORAGE (1)
IStream | DBPROP_ISTREAM (1)
ISupportErrorInfo | DBPROP_ISUPPORTERRORINFO (1)
Access Order | DBPROP_ACCESSORDER
Append-Only Rowset | DBPROP_APPENDONLY
Asynchronous Rowset Processing | DBPROP_ROWSET_ASYNCH
Auto Recalc | DBPROP_ADC_AUTORECALC
Background Fetch Size | DBPROP_ASYNCHFETCHSIZE
Background Thread Priority | DBPROP_ASYNCHTHREADPRIORITY
Batch Size | DBPROP_ADC_BATCHSIZE
Blocking Storage Objects | DBPROP_BLOCKINGSTORAGEOBJECTS
Bookmark Type | DBPROP_BOOKMARKTYPE
Bookmarkable | DBPROP_IROWSETLOCATE (2)
Bookmarks Ordered | DBPROP_ORDEREDBOOKMARKS
Cache Child Rows | DBPROP_ADC_CACHECHILDROWS
Cache Deferred Columns | DBPROP_CACHEDEFERRED
Change Inserted Rows | DBPROP_CHANGEINSERTEDROWS
Column Privileges | DBPROP_COLUMNRESTRICT
Column Set Notification | DBPROP_NOTIFYCOLUMNSET
Column Writable | DBPROP_MAYWRITECOLUMN
Command Time Out | DBPROP_COMMANDTIMEOUT
Cursor Engine Version | DBPROP_ADC_CEVER
Defer Column | DBPROP_DEFERRED
Delay Storage Object Updates | DBPROP_DELAYSTORAGEOBJECTS
Fetch Backwards | DBPROP_CANFETCHBACKWARDS
Filter Operations | DBPROP_FILTERCOMPAREOPS
Find Operations | DBPROP_FINDCOMPAREOPS
Hidden Columns (Count) | DBPROP_HIDDENCOLUMNS (3)
Hold Rows | DBPROP_CANHOLDROWS
Immobile Rows | DBPROP_IMMOBILEROWS
Initial Fetch Size | DBPROP_ASYNCHPREFETCHSIZE
Literal Bookmarks | DBPROP_LITERALBOOKMARKS
Literal Row Identity | DBPROP_LITERALIDENTITY
Maintain Change Status | DBPROP_ADC_MAINTAINCHANGESTATUS
Maximum Open Rows | DBPROP_MAXOPENROWS
Maximum Pending Rows | DBPROP_MAXPENDINGROWS
Maximum Rows | DBPROP_MAXROWS (4)
Memory Usage | DBPROP_MEMORYUSAGE
Notification Granularity | DBPROP_NOTIFICATIONGRANULARITY
Notification Phases | DBPROP_NOTIFICATIONPHASES
Objects Transacted | DBPROP_TRANSACTEDOBJECT
Others' Changes Visible | DBPROP_OTHERUPDATEDELETE
Others' Inserts Visible | DBPROP_OTHERINSERT
Own Changes Visible | DBPROP_OWNUPDATEDELETE
Own Inserts Visible | DBPROP_OWNINSERT
Preserve on Abort | DBPROP_ABORTPRESERVE
Preserve on Commit | DBPROP_COMMITPRESERVE
Private1 | (5)
Quick Restart | DBPROP_QUICKRESTART
Reentrant Events | DBPROP_REENTRANTEVENTS
Remove Deleted Rows | DBPROP_REMOVEDELETED
Report Multiple Changes | DBPROP_REPORTMULTIPLECHANGES
Reshape Name | DBPROP_ADC_RESHAPENAME
Resync Command | DBPROP_ADC_CUSTOMRESYNCH
Return Pending Inserts | DBPROP_RETURNPENDINGINSERTS
Row Delete Notification | DBPROP_NOTIFYROWDELETE
Row First Change Notification | DBPROP_NOTIFYROWFIRSTCHANGE
Row Insert Notification | DBPROP_NOTIFYROWINSERT
Row Privileges | DBPROP_ROWRESTRICT
Row Resynchronization Notification | DBPROP_NOTIFYROWRESYNCH
Row Threading Model | DBPROP_ROWTHREADMODEL
Row Undo Change Notification | DBPROP_NOTIFYROWUNDOCHANGE
Row Undo Delete Notification | DBPROP_NOTIFYROWUNDODELETE
Row Undo Insert Notification | DBPROP_NOTIFYROWUNDOINSERT
Row Update Notification | DBPROP_NOTIFYROWUPDATE
Rowset Fetch Position Change Notification | DBPROP_NOTIFYROWSETFETCHPOSITIONCHANGE
Rowset Release Notification | DBPROP_NOTIFYROWSETRELEASE
Scroll Backwards | DBPROP_CANSCROLLBACKWARDS
Server Cursor | DBPROP_SERVERCURSOR
Skip Deleted Bookmarks | DBPROP_BOOKMARKSKIPPED
Strong Row Identity | DBPROP_STRONGIDENTITY
Unique Catalog | DBPROP_ADC_UNIQUECATALOG
Unique Rows | DBPROP_UNIQUEROWS
Unique Schema | DBPROP_ADC_UNIQUESCHEMA
Unique Table | DBPROP_ADC_UNIQUETABLE
Updatability | DBPROP_UPDATABILITY
Update Criteria | DBPROP_ADC_UPDATECRITERIA
Update Resync | DBPROP_ADC_UPDATERESYNC
Use Bookmarks | DBPROP_BOOKMARKS


Optimize 动态属性 (ADO)

指定是否在字段上创建索引。

设置和返回值

设置或返回 Boolean 值。该值指示是否创建索引。

说明

索引能够改善对 Recordset 中的值进行查询或排序的性能。该索引是 ADO 内部使用的，用户不能在应用程序中显式地访问或使用它。

要在字段上创建索引，请将 Optimize 属性设置为 True。要删除该索引，请将此属性设置为 False。

当把 CursorLocation 属性设置为 adUseClient 时，Optimize 是追加到 Field 对象 Properties 集合中的动态属性。

用法

Dim rs As New Recordset
Dim fld As Field
rs.CursorLocation = adUseClient      'Enable index creation
rs.Fields.Append "Field1", adChar, 35, adFldIsNullable
rs.Open
Set fld = rs.Fields(0)
fld.Properties("Optimize") = True    'Create an index
fld.Properties("Optimize") = False   'Delete an index

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Filter 属性 | Find 方法 | Sort 属性

适用于：Field 对象


Prompt 动态属性 (ADO)

指定 OLE DB 提供者是否提示用户输入初始化信息。

设置和返回值

设置并返回 ConnectPromptEnum 值。

说明

Prompt 是动态属性，可以由 OLE DB 提供者追加到 Connection 对象的 Properties 集合中。为了提示输入初始化信息，OLE DB 提供者通常将向用户显示一个对话框。

当 Connection 关闭时，Connection 对象的动态属性丢失。必须在重新打开 Connection 之前重置 Prompt 属性以便使用默认值以外的值。

注意 不要在用户不能响应对话框的方案中指定要提供者提示用户。例如，如果应用程序在服务器系统上而不是在用户的客户端上运行，或者在没有用户登录的系统上运行时，用户将不能作出响应。在这些情况下，应用程序将无限期地等待响应，就象锁定一样。

用法

Set cn = New Connection
cn.Provider = "SQLOLEDB"
cn.Properties("Prompt") = adPromptNever    ' do not prompt the user

请参阅

适用于：Connection 对象


Reshape Name 动态属性 (ADO)

为 Recordset 对象指定一个名称。

返回值

返回 String 值，该值是 Recordset 的名称。

说明

名称将在连接期间或者 Recordset 关闭之前持久保留。

Reshape Name 属性主要用于 Microsoft Data Shaping Service for OLE DB 服务提供者的重构形特性。为了参与重构形，名称必须是唯一的。

此属性是只读的，但是在创建 Recordset 时可以间接设置它。例如，如果 SHAPE 命令的子句创建了一个 Recordset 并通过“AS”关键字赋予它一个别名，那么该别名将分配给 Reshape Name 属性。如果没有声明别名，将给 Reshape Name 属性分配一个由数据构形服务生成的唯一名称。如果该别名与现有的 Recordset 同名，那么在二者之一被释放之前，每个 Recordset 都不会被重构形。通过在 ADO 连接上设置“Unique Reshape Names”（请参阅“Microsoft Data shaping service for OLE DB”）属性可以将默认行为更改为 TRUE。这样就赋予了数据构形服务更改用户分配的名称的权限（如果需要确保唯一性）。

当要在 SHAPE 命令中引用 Recordset 时，或由于通过 Data Shaping Service 产生因而用户不知道其名称时，请使用 Reshape Name 属性。在这种情况下，可以通过连接命令和由 Reshape Name 属性返回的字符串来产生 SHAPE 命令。

当 CursorLocation 属性设置为 adUseClient 时，Reshape Name 是追加到 Recordset 对象的 Properties 集合的动态属性。

请参阅

Microsoft Data Shaping Service for OLE DB (Unique Reshape Names)

适用于：Recordset 对象


Resync Command 动态属性 (ADO)

指定用户提供的命令字符串，该字符串由 Resync 方法发出，用于刷新在 Unique Table 动态属性中命名的表中的数据。

设置和返回值

设置或返回 String 值，该值是命令字符串。

说明

Recordset 对象是在多个基本表中执行 JOIN 操作的结果。受影响的行取决于 Resync 方法的 AffectRecords 参数。如果没有设置 Unique Table 和 Resync Command 属性，那么执行标准 Resync 方法。

Resync Command 属性的命令字符串是参数化命令或存储过程，它唯一地标识被刷新的行，并且返回单一行，此行中包含的列的数量和顺序与要刷新的行相同。命令字符串包含 Unique Table 中每个主键列的参数；否则将返回一个运行时错误。要被刷新的行的主键值将自动填充该参数。

下面是两个基于 SQL 的范例：

1) Recordset 由如下命令定义：

SELECT * FROM Customers JOIN Orders ON
   Customers.CustomerID = Orders.CustomerID
   WHERE city = Seattle
   ORDER BY CustomerID

Resync Command 属性设置如下：

"SELECT * FROM
   (SELECT * FROM Customers JOIN Orders
   ON Customers.CustomerID = Orders.CustomerID
   city = Seattle ORDER BY CustomerID)
WHERE Orders.OrderID = ?"

Unique Table 是 Orders，其主键 OrderID 已被参数化。子选择语句提供了一种简单的方法，通过编程确保返回的列的数量和顺序与原命令所返回的相同。

2) Recordset 由存储过程定义如下：

CREATE PROC Custorders @CustomerID char(5) AS
SELECT * FROM Customers JOIN Orders ON
Customers.CustomerID = Orders.CustomerID
WHERE Customers.CustomerID = @CustomerID

Resync 方法将执行下列存储过程：

CREATE PROC CustordersResync @ordid int AS
SELECT * FROM Customers JOIN Orders ON
Customers.CustomerID = Orders.CustomerID
WHERE Orders.ordid  = @ordid

Resync Command 属性设置如下：

"{call CustordersResync (?)}"

同样，Unique Table 是 Orders，并且其主键 OrderID 已被参数化。

当 CursorLocation 属性设置为 adUseClient 时，Resync Command 是追加到 Recordset 对象的 Properties 集合的动态属性。

请参阅

适用于：Recordset 对象


Unique Table、Unique Schema 和Unique Catalog 动态属性 (ADO)

ADO 2.5 API 参考

Unique Table、Unique Schema 和 Unique Catalog 动态属性 (ADO)

使用户能够进一步控制对通过在多个基本表上执行 JOIN 操作所得到的 Recordset 中的特定基本表的修改。

  • Unique Table 指定允许进行更新、插入和删除的基本表的名称。
  • Unique Schema 指定表的所有者的“模式”或名称。
  • Unique Catalog 指定包含该表的数据库的“目录”或名称。

设置和返回值

设置或返回 String 值，该值是表、模式或目录的名称。

说明

所需的基本表通过其目录、模式和表名唯一标识。当设置 Unique Table 属性后，Unique Schema 或 Unique Catalog 属性的值用于查找基本表。它将（但不必须）在设置 Unique Table 属性之前设置 Unique Schema 和 Unique Catalog 属性之一或全部。

Unique Table 的主键被当作整个 Recordset 的主键。这个键用于任何需要主键的方法。

当设置 Unique Table 后，Delete 方法仅影响命名的表。AddNew、Resync、Update 和 UpdateBatch 方法影响任何适当的 Recordset 的基本表。

Unique Table 必须在进行任何自定义重新同步之前指定。如果未指定 Unique Table，那么 Resync Command 属性将不起作用。

如果查找不到唯一的基本表，将发生运行时错误。

当 CursorLocation 属性设置为 adUseClient 时，这些动态属性被全部追加到 Recordset 对象的 Properties 集合中。

请参阅

适用于：Recordset 对象


Update Resync 动态属性 (ADO)

指定 UpdateBatch 方法后面是否跟随隐式的 Resync 方法操作，如果是，则指定操作的范围。

设置和返回值

设置或返回一个或多个 ADCPROP_UPDATERESYNC_ENUM 值。

说明

ADCPROP_UPDATERESYNC_ENUM 的值可以组合，但 adResyncAll 除外，因为它已经表示其余值的组合。

常量 adResyncConflicts 将 Resync 值存储为基本值，但并不覆盖挂起的更改。

当 CursorLocation 属性设置为 adUseClient 时，Update Resync 是追加到 Recordset 对象的 Properties 集合中的动态属性。

请参阅

适用于：Recordset 对象


ADO 方法

AddNew | 创建可更新的 Recordset 对象的新记录。
Append | 向集合中追加对象。如果集合是 Fields，可先创建新的 Field 对象，再将其追加到集合中。
AppendChunk | 将数据追加到大的文本或二进制数据 Field 或追加到 Parameter 对象。
BeginTrans、CommitTrans 和 RollbackTrans | 按下面的方法管理 Connection 对象中的事务处理： BeginTrans — 开始新事务。 CommitTrans — 保存更改并结束当前事务。它也可能启动新事务。 RollbackTrans — 取消当前事务中所做的更改并结束事务。它也可能启动新事务。
Cancel | 取消执行挂起的异步方法调用。
CancelBatch | 取消挂起的批更新。
CancelUpdate | 在调用 Update 方法之前，取消对 Recordset 对象的当前行或新行或者 Record 对象的 Fields 集合所做的更改。
Clear | 删除 Errors 集合中的所有 Error 对象。
Clone | 从现有 Recordset 对象创建一个相同的 Recordset 对象。可选择指定该副本为只读。
Close | 关闭打开的对象和任何相关的对象。
CompareBookmarks | 比较两个书签并返回其相对值的说明。
CopyRecord | 把文件或目录（及其内容）复制到另一个位置。
CopyTo | 将 Stream 中指定数目的字符或字节（取决于 Type）复制到另一个 Stream 对象。
CreateParameter | 创建具有指定属性的新的 Parameter 对象。
Delete（ADO Parameters 集合） | 从 Parameters 集合中删除对象。
Delete（ADO Fields 集合） | 从 Fields 集合中删除对象。
Delete (ADO Recordset) | 删除当前记录或记录组。
DeleteRecord | 删除文件或目录（及其所有子目录）。
Execute (ADO Command) | 执行 CommandText 属性中指定的查询、SQL 语句或存储过程。
Execute (ADO Connection) | 执行指定的查询、SQL 语句、存储过程或提供者特有的文本。
Find | 在 Recordset 中搜索满足指定条件的行。
Flush | 将保留在 ADO 缓冲区中的 Stream 的内容强加到与 Stream 相关联的基本对象。
GetChildren | 返回 Recordset，其中的行表示由此 Record 表示的目录中的文件和子目录。
GetChunk | 返回大的文本或二进制数据 Field 对象的全部或部分内容。
GetRows | 将 Recordset 对象的多个记录检索到数组中。
GetString | 将 Recordset 作为字符串返回。
LoadFromFile | 将现有文件的内容加载到 Stream 中。
Move | 在 Recordset 对象中移动当前记录的位置。
MoveFirst、MoveLast、MoveNext 和 MovePrevious | 移动到指定的 Recordset 对象中的第一个、最后一个、下一个或上一个记录并使其成为当前记录。
MoveRecord | 把文件或目录（及其内容）移动到另一个位置。
NextRecordset | 通过执行一系列命令清除当前 Recordset 对象并返回下一个 Recordset。
Open (ADO Connection) | 打开到数据源的连接。
Open (ADO Record) | 打开现有的 Record 对象，或者创建新的文件或目录。
Open (ADO Recordset) | 打开游标。
Open (ADO Stream) | 打开 Stream 对象来操作二进制或文本数据的流。
OpenSchema | 从提供者获取数据库模式信息。
Read | 从 Stream 对象读取指定数目的字节。
ReadText | 从文本 Stream 对象读取指定数目的字符。
Refresh | 更新集合中的对象以反映提供者可用的特有对象。
Requery | 通过重新执行对象所基于的查询来更新 Recordset 对象中的数据。
Resync | 从基本数据库刷新当前 Recordset 对象中的数据或 Record 对象的 Fields 集合。
Save | 将 Recordset 保存在文件或 Stream 对象中。
SaveToFile | 把 Stream 的二进制内容保存到文件。
Seek | 搜索 Recordset 的索引以快速定位与指定的值相匹配的行，并使其成为当前行。
SetEOS | 设置流的结尾位置。
SkipLine | 读取文本流时跳过一整行。
Stat | 获得有关打开的流的统计信息。
Supports | 确定指定的 Recordset 对象是否支持特定类型的功能。
Update | 保存对 Recordset 对象的当前行或者 Record 对象的 Fields 集合所做的更改。
UpdateBatch | 将所有挂起的批更新写入磁盘。
Write | 将二进制数据写入 Stream 对象。
WriteText | 将指定的文本字符串写入 Stream 对象。

请参阅

ADO API 参考 | ADO 集合 | ADO 动态属性 | ADO 枚举常量 | ADO 错误 | ADO 事件 | ADO 对象模型 | ADO 对象 | ADO 属性


AddNew 方法 (ADO)

ADO 2.5 API 参考

AddNew 方法

创建可更新的 Recordset 对象的新记录。

语法

recordset.AddNew FieldList, Values

参数

recordset
Recordset 对象。
FieldList
可选。新记录中字段的单个名称、名称数组或序号位置数组。
Values
可选。新记录中字段的单个值或值的数组。如果 Fieldlist 是数组，那么 Values 也必须是具有相同数目的成员的数组，否则将发生错误。字段名称的次序必须与每个数组中的字段值的次序相匹配。

说明

使用 AddNew 方法创建并初始化新记录。使用带 adAddNew（CursorOptionEnum 值）的 Supports 方法验证是否能够将记录添加到当前的 Recordset 对象。

在调用 AddNew 方法后，新记录将成为当前记录，并在调用 Update 方法后仍保持为当前记录。由于新记录是追加到 Recordset 中的，因此 Update 之后调用 MoveNext 将移过 Recordset 的结尾，从而使 EOF 为 True。如果 Recordset 对象不支持书签，那么一旦移至其他记录则无法访问此新记录。根据游标类型，可能需要调用 Requery 方法以访问新记录。

如果在编辑当前记录或添加新记录时调用 AddNew，ADO 将调用 Update 方法以保存更改，然后创建新记录。

AddNew 方法的行为取决于 Recordset 对象的更新模式以及是否传送 Fieldlist 和 Values 参数。

在“立即更新模式”下（在这种模式下，一旦调用 Update 方法，提供者将把更改写入基本数据源），调用不带参数的 AddNew 方法将 EditMode 属性设置为 adEditAdd（EditModeEnum 值）。提供者在本地缓存任何字段值的更改。调用 Update 方法可将新记录传递到数据库并将 EditMode 属性重置为 adEditNone（EditModeEnum 值）。如果传送 Fieldlist 和 Values 参数，ADO 将立即把新记录传递到数据库（无须调用 Update）；而 EditMode 属性值没有改变 (adEditNone)。

在“批更新模式”下（在这种模式下，提供者缓存多个更改并只在调用 UpdateBatch 方法时将其写入基本数据源），调用不带参数的 AddNew 方法将 EditMode 属性设置为 adEditAdd。提供者在本地缓存任何字段值的更改。调用 Update 方法可将新记录添加到当前 Recordset 并将 EditMode 属性重置为 adEditNone，但在调用 UpdateBatch 方法之前，提供者不会将更改传递到基本数据库。如果传送 Fieldlist 和 Values 参数，ADO 将把新记录发送给提供者以便存储在缓存中；需要调用 UpdateBatch 方法将新记录传递到基本数据库。

请参阅

Visual Basic 范例 | VBScript 范例 | Visual C++ 范例 | Visual J++ 范例

SafeArray | CancelUpdate 方法 | EditMode 属性 | Requery 方法 | Supports 方法 | Update 方法 | UpdateBatch 方法

应用于：Recordset 对象


Append 方法 (ADO)

ADO 2.5 API 参考

Append 方法

向集合中追加对象。如果集合是 Fields，可先创建新的 Field 对象，再将其追加到集合中。

语法

collection.Append object
fields.Append Name, Type, DefinedSize, Attrib, FieldValue

参数

collection
Collection 对象。
fields
Fields 集合。
object
对象变量，表示要追加的对象。
Name
String 值，包含新 Field 对象的名称，该名称不能与 fields 中任何其他对象的名称相同。
Type
DataTypeEnum 值，指定新字段的数据类型，其默认值为 adEmpty。ADO 不支持下列数据类型，向 Recordset 追加新字段时不能使用它们：adIDispatch、adIUnknown 和 adVariant。
DefinedSize
可选。Long 值，表示新字段的定义大小（以字符或字节为单位）。此参数的默认值源于 Type。DefinedSize 超过 255 字节的 Fields 被视为变长列。（未指定默认的 DefinedSize。）
Attrib
可选。FieldAttributeEnum 值，指定新字段的属性，其默认值为 adFldDefault。如果未指定此值，字段将包含源于 Type 的属性。
FieldValue
可选。Variant，表示新字段的值。 如果未指定，将把 Null 值追加到字段中。

说明

Parameters 集合

在将 Parameter 对象追加到 Parameters 集合前，必须设置其 Type 属性。如果选择变长数据类型，还必须将 Size 属性设置为大于零的值。

用户对参数作出说明，可以最大程度地减少对提供者的调用，进而在使用存储过程或参数化查询时提高性能。但是，用户必须了解与要调用的存储过程或参数化查询相关联的参数属性。

用 CreateParameter 方法创建具有适当属性设置的 Parameter 对象，并用 Append 方法将其添加到 Parameters 集合。这使用户可以设置和返回参数值，而不必调用提供者来获得参数信息。如果要写入不提供参数信息的提供者，必须使用此方法手动预置 Parameters 集合才能使用这些参数。

Fields 集合

FieldValue 参数只在向 Record 对象而非 Recordset 对象添加 Field 对象时有效。对于 Record 对象，可以同时追加字段并提供值。对于 Recordset 对象，必须在 Recordset 关闭时创建字段，然后打开 Recordset 给这些字段赋值。

注意 对于追加到 Record 对象的 Fields 集合的新 Field 对象，必须在指定任何其他 Field 属性之前设置 Value 属性。首先必须给 Value 属性分配特定的值，并且调用 Fields 集合的 Update。然后可以访问其他属性（如 Type 或 Attributes）。
下列数据类型 (DataTypeEnum) 的 Field 对象不能被追加到 Fields 集合，否则将发生错误：adArray、adChapter、adEmpty、adPropVariant 和 adUserDefined。ADO 也不支持下列数据类型：adIDispatch、adIUnknown 和 adIVariant。追加这些类型时将不会发生错误，但使用它们将产生不可预料的结果，包括内存溢出。

Recordset

如果在调用 Append 方法前未设置 CursorLocation 属性，则 CursorLocation 将在调用 Recordset 对象的 Open 方法时自动设置为 adUseClient（CursorLocationEnum 值）。

如果在打开的 Recordset 的 Fields 集合上或设置了 ActiveConnection 属性的 Recordset 上调用 Append 方法，将发生运行时错误。只能将字段追加到未打开且未连接到数据源的 Recordset。在以 CreateRecordset 方法虚构 Recordset 对象或分配给对象变量时通常就是这种情况。

Record

如果在打开的 Record 的 Fields 集合上调用 Append 方法，将发生运行时错误。新字段将被添加到 Record 对象的 Fields 集合。如果 Record 源于 Recordset，那么新字段将不会显示在 Recordset 对象的 Fields 集合中。

给非现有字段对象赋值，即假定其存在于集合中，就可创建该字段并将其追加到 Fields 集合。赋值将触发 Field 对象的自动创建和追加，然后完成赋值。

将 Field 追加到 Record 对象的 Fields 集合后，调用 Fields 集合的 Update 方法以保存更改。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

CreateParameter 方法 | Delete 方法 (ADO Fields Collection) | Delete 方法 (ADO Parameters Collection) | Delete 方法 (ADO Recordset) | Update 方法

应用于：Fields 集合 | Parameters 集合 | Record 对象


AppendChunk 方法 (ADO)

ADO 2.5 API 参考

AppendChunk 方法

将数据追加到大的文本或二进制数据 Field 或追加到 Parameter 对象。

语法

object.AppendChunk Data

参数

object
Field 或 Parameter 对象。
Data
Variant，包含要追加到对象的数据。

说明

使用 Field 或 Parameter 对象的 AppendChunk 方法用长二进制或字符数据填充。在系统内存有限的情况下，可使用 AppendChunk 方法操作部分而非全部的 Long 值。

Field

如果 Field 对象的 Attributes 属性中的 adFldLong 位设置为 True，可以对该字段使用 AppendChunk 方法。

在 Field 对象上的第一个 AppendChunk 调用将数据写入字段，覆盖任何现有数据。后续的 AppendChunk 调用向现有数据中添加数据。如果要将数据追加到一个字段然后在当前记录中设置或读取其他字段的值，ADO 会认为已完成向第一个字段追加数据。如果在第一个字段上再次调用 AppendChunk 方法，ADO 将把这次调用解释为新的 AppendChunk 操作并覆盖现有数据。访问其他 Recordset 对象（并非第一个 Recordset 对象的副本）中的字段将不会中断 AppendChunk 操作。

在 Field 对象上调用 AppendChunk 时，如果没有当前记录，将发生错误。

注意 AppendChunk 方法对 Record 对象的 Field 对象不起作用。它不执行任何操作并将产生运行时错误。

Parameter

如果 Parameter 对象的 Attributes 属性中的 adFldLong 位设置为 True，可以对该参数使用 AppendChunk 方法。

在 Parameter 对象上的第一个 AppendChunk 调用将数据写入参数，覆盖任何现有数据。Parameter 对象上的后续 AppendChunk 调用向现有参数数据中添加数据。传送 Null 值的 AppendChunk 调用放弃所有参数数据。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Attributes 属性 | GetChunk 方法

应用于：Field 对象 | Parameter 对象


BeginTrans、CommitTrans 和 RollbackTrans 方法 (ADO)

ADO 2.5 API 参考

BeginTrans、CommitTrans 和 RollbackTrans 方法

这些事务方法按如下方法管理 Connection 对象中的事务进程：

  • BeginTrans — 开始新事务。
  • CommitTrans — 保存更改并结束当前事务。它也可能启动新事务。
  • RollbackTrans — 取消当前事务中所做的更改并结束事务。它也可能启动新事务。

语法

level = object.BeginTrans()
object.BeginTrans
object.CommitTrans
object.RollbackTrans

返回值

BeginTrans 可以作为函数调用，用于返回指示事务嵌套层次的 Long 变量。

参数

object
Connection 对象。

Connection

如果想要以独立单元保存或取消对源数据所做的一系列更改，请对 Connection 对象使用这些方法。例如，要进行转帐，从一个帐户中减去某个数额并将对等数额添加到另一个帐户中。如果任何一个更新失败，都将导致帐户收支不平衡。在打开的事务中进行这些更改可确保只能选择进行全部更改或不作任何更改。

注意 并非所有的提供者都支持事务。验证提供者定义的属性“Transaction DDL”显示在 Connection 对象的 Properties 集合中，这表示提供者支持事务。 如果提供者不支持事务，调用这些方法之一将返回错误。

在调用 BeginTrans 方法后，提供者将不再立即提交所作的更改，直到调用 CommitTrans 或 RollbackTrans 结束事务。

对于支持嵌套事务的提供者，在打开的事务中调用 BeginTrans 方法将启动新的嵌套事务。返回值将指示嵌套层次：返回值为“1”指示打开了顶层事务（即此事务未嵌套在其他事务中），返回值为“2”指示打开了第二层事务（嵌套在顶层事务中的事务），依此类推。调用 CommitTrans 或 RollbackTrans 只影响最新打开的事务；在处理任何更高层事务之前必须关闭或回卷当前事务。

调用 CommitTrans 方法将保存连接上打开的事务中所做的更改并结束事务。调用 RollbackTrans 方法还原打开事务中所做的更改并结束事务。在无打开的事务时调用任何一种方法都会产生错误。

根据 Connection 对象的 Attributes 属性，调用 CommitTrans 或 RollbackTrans 方法都可以自动启动新事务。如果 Attributes 属性设置为 adXactCommitRetaining，在调用 CommitTrans 后提供者将自动启动新事务。如果 Attributes 属性设置为 adXactAbortRetaining，在调用 RollbackTrans 后提供者将自动启动新事务。

远程数据服务

BeginTrans、CommitTrans 和 RollbackTrans 方法在客户端 Connection 对象上无效。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Attributes 属性

应用于：Connection 对象


Cancel 方法 (ADO)

ADO 2.5 API 参考

Cancel 方法

取消执行挂起的异步方法调用。

语法

object.Cancel

说明

使用 Cancel 方法终止执行异步方法调用（即用 adAsyncConnect、adAsyncExecute 或 adAsyncFetch 选项调用的方法）。

下表显示使用特定类型对象的 Cancel 方法时将终止的任务。

如果 object 是 | 终止对此方法的上一次异步调用
Command | Execute
Connection | Execute 或 Open
Record | CopyRecord、DeleteRecord、MoveRecord 或 Open
Recordset | Open
Stream | Open

请参阅

Visual Basic 范例 | VBScript 范例 | Visual C++ 范例 | Visual J++ 范例

Cancel 方法 (RDS) | CancelBatch 方法 | CancelUpdate 方法 | CancelUpdate 方法 (RDS) | Execute 方法 (ADO Command) | Execute 方法 (ADO Connection) | Open 方法 (ADO Connection) | Open 方法 (ADO Recordset)

应用于：Command 对象 | Connection 对象 | Record 对象 | Recordset 对象 | Stream 对象


CancelBatch 方法 (ADO)

ADO 2.5 API 参考

CancelBatch 方法

取消挂起的批更新。

语法

recordset.CancelBatch AffectRecords

参数

AffectRecords
可选。AffectEnum 值，指示 CancelBatch 方法影响的记录数目。

说明

在批更新模式下，使用 CancelBatch 方法取消 Recordset 中任何挂起的更新。如果 Recordset 处于立即更新模式，调用不带 adAffectCurrent 的 CancelBatch 将产生错误。

如果调用 CancelBatch 时在编辑当前记录或添加新记录，那么 ADO 先调用 CancelUpdate 方法以取消任何缓存的更改。然后取消 Recordset 中所有挂起的更改。

有可能在 CancelBatch 调用后，特别是在添加新记录的过程中无法确定当前记录。因此，在 CancelBatch 调用后应考虑将当前记录位置设置为 Recordset 中的一个已知位置。例如调用 MoveFirst 方法。

如果因与基本数据冲突而导致取消挂起更新的尝试失败（如记录已被其他用户删除），提供者将向 Errors 集合返回警告但不终止程序执行。只有在所有提出请求的记录上都发生冲突时才会发生运行时错误。用 Filter 属性 (adFilterAffectedRecords) 和 Status 属性来定位发生冲突的记录。

请参阅

Visual Basic 范例 | Visual C++ 范例

Cancel 方法 | Cancel 方法 (RDS) | CancelUpdate 方法 | CancelUpdate 方法 (RDS) | Clear 方法 | LockType 属性 | UpdateBatch 方法

应用于：Recordset 对象


CancelUpdate 方法 (ADO)

ADO 2.5 API 参考

CancelUpdate 方法

在调用 Update 方法之前，取消对 Recordset 对象的当前行或新行或者 Record 对象的 Fields 集合所做的更改。

语法

recordset.CancelUpdate
record.Fields.CancelUpdate

说明

Recordset

使用 CancelUpdate 方法取消对当前行所做的更改或放弃新添加的行。调用 Update 方法后无法取消对当前行或新行所做的更改，除非更改是可以用 RollbackTrans 方法回卷的事务的一部分，或者是批更新的一部分。在批更新的情况下，可以用 CancelUpdate 或 CancelBatch 方法取消 Update。

如果调用 CancelUpdate 方法时在添加新行，调用 AddNew 之前的当前行将成为当前行。

如果处于编辑模式中并且希望离开当前记录（例如，使用 Move、NextRecordset 或 Close），则您可以使用 CancelUpdate 取消任何挂起的更改。如果更新无法成功地传递到数据源（例如，由于违反参照完整性而不能完成试图的删除，从而在调用 Delete 之后使 Recordset 处于编辑模式）。

Record

CancelUpdate 方法取消 Field 对象的任何挂起插入或删除，取消现有字段的挂起更新并将其还原为原值。Fields 集合中所有字段的 Status 属性都设置为 adFieldOK。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

AddNew 方法 | Cancel 方法 | Cancel 方法 (RDS) | CancelBatch 方法 | CancelUpdate 方法 (RDS) | EditMode 属性 | Update 方法

应用于：Fields 集合 | Recordset 对象


Clear 方法 (ADO)

ADO 2.5 API 参考

Clear 方法

删除 Errors 集合中的所有 Error 对象。

语法

Errors.Clear

说明

使用 Errors 集合的 Clear 方法以删除集合中所有现有的 Error 对象。发生错误时，ADO 将自动清空 Errors 集合，并用基于新错误的 Error 对象填充集合。

某些属性和方法返回警告，这些警告显示为 Errors 集合中的 Error 对象，但并不终止程序的执行。请先调用 Errors 集合的 Clear 方法，然后再调用 Recordset 对象的 Resync、UpdateBatch 或 CancelBatch 方法，调用 Connection 对象的 Open 方法，或设置 Recordset 对象的 Filter 属性。这样，就可以读取 Errors 集合的 Count 属性以测试返回的警告。

请参阅

Visual Basic 范例 | VBScript 范例 | Visual C++ 范例 | Visual J++ 范例

CancelBatch 方法 | Delete 方法（ADO Fields 集合） | Delete 方法（ADO Parameters 集合） | Delete 方法 (ADO Recordset) | Filter 属性 | Resync 方法 | UpdateBatch 方法

应用于：Errors 集合


Clone 方法 (ADO)

ADO 2.5 API 参考

Clone 方法

从现有 Recordset 对象创建一个相同的 Recordset 对象。可选择指定该副本为只读。

语法

Set rstDuplicate = rstOriginal.Clone (LockType)

返回值

返回 Recordset 对象引用。

参数

rstDuplicate
对象变量，指示要创建的 Recordset 对象副本。
rstOriginal
对象变量，指示要被复制的 Recordset 对象。
LockType
可选。LockTypeEnum 值，指定原 Recordset 的锁定类型或指定只读 Recordset。有效值为 adLockUnspecified 或 adLockReadOnly。

说明

使用 Clone 方法可创建多个相同的 Recordset 对象，这对于想要在给定的记录组中保留多个当前记录尤其有用。使用 Clone 方法比创建和打开与原对象定义相同的新 Recordset 对象更为有效。

原 Recordset 的 Filter 属性（如果存在）将不被应用到副本。设置新 Recordset 的 Filter 属性以过滤结果。复制任何现有 Filter 值的最简单的方式就是对其直接赋值，例如：rsNew.Filter = rsOriginal.Filter

将新创建副本的当前记录设置为首记录。

不管游标类型如何，对一个 Recordset 对象所做的更改将在其所有副本中显示。但是在对原 Recordset 执行 Requery 后，副本将不再与原 Recordset 同步。

关闭原 Recordset 时并不关闭其副本，而关闭副本也不会关闭原 Recordset 或任何其他副本。

用户只能复制支持书签的 Recordset 对象。书签值是可交换的，也就是说，来自一个 Recordset 对象的书签引用可引用其任何副本中的相同记录。

一些触发的 Recordset 事件也将在所有 Recordset 副本中触发。但是，由于当前记录可区分副本的 Recordsets，因此事件对副本可能无效。

例如，如果更改了一个字段值，则 WillChangeField 事件将在更改的 Recordset 中和所有副本中发生。副本的 Recordset（此处没有更改）的 WillChangeField 事件的 Fields 参数只是简单地引用该副本当前记录的字段，该记录可能与原 Recordset （此处有更改）的当前记录不同。

下表完整地列出了全部 Recordset 事件，并指示这些事件对于使用 Clone 方法生成的任何记录集副本是否是有效的和可触发的。

事件 | 是否可在副本中触发？
EndOfRecordset | 否
FetchComplete | 否
FetchProgress | 否
FieldChangeComplete | 是
MoveComplete | 否
RecordChangeComplete | 是
RecordsetChangeComplete | 否
WillChangeField | 是
WillChangeRecord | 是
WillChangeRecordset | 否
WillMove | 否

请参阅

Visual Basic 范例 | VBScript 范例 | Visual C++ 范例 | Visual J++ 范例

应用于：Recordset 对象


Close 方法 (ADO)

ADO 2.5 API 参考

Close 方法

关闭打开的对象和任何相关的对象。

语法

object.Close

说明

使用 Close 方法关闭 Connection、Record、Recordset 或 Stream 对象以便释放任何相关联的系统资源。关闭对象不会将其从内存中删除；随后可以更改其属性设置并再次将其打开。要从内存中彻底清除对象，请在关闭对象后将对象变量设置为 Nothing（在 Visual Basic 中）。

Connection

使用 Close 方法关闭 Connection 对象还将关闭与连接相关联的任何活动 Recordset 对象。与正在关闭的 Connection 对象相关联的 Command 对象将被持久保留，但不再与 Connection 对象相关联，即其 ActiveConnection 属性将被设置为 Nothing。还将从 Command 对象的 Parameters 集合中清除任何提供者定义的参数。

随后可以调用 Open 方法重新建立与相同数据源或其他数据源的连接。在 Connection 对象关闭后，调用任何需要与数据源打开连接的方法都将产生错误。

当连接上的 Recordset 对象打开时，关闭 Connection 对象将回卷所有 Recordset 对象中的挂起更改。在事务进行过程中显式关闭 Connection 对象（调用 Close 方法）将产生错误。如果在事务进行过程中 Connection 对象超出范围，ADO 将自动回卷事务。

Recordset、Record 和 Stream

使用 Close 方法关闭 Recordset、Record 或 Stream 对象将释放相关联的数据和可能通过此特定对象对数据进行的独立访问。随后可以调用 Open 方法重新打开具有相同属性或修改属性的对象。

在 Recordset 对象关闭后，调用任何需要活动游标的方法都将产生错误。

如果在立即更新模式下进行编辑，调用 Close 方法将产生错误，应先调用 Update 或 CancelUpdate 方法。如果在批更新模式下关闭 Recordset 对象，自上次 UpdateBatch 调用以来所做的更改将全部丢失。

如果使用 Clone 方法创建打开的 Recordset 对象的副本，关闭原 Recordset 或其副本不会影响任何其他副本。

请参阅

Visual Basic 范例 | VBScript 范例 | Visual C++ 范例 | Visual J++ 范例

Open 方法 (ADO Connection) | Open 方法 (ADO Recordset) | Save 方法

应用于：Connection 对象 | Record 对象 | Recordset 对象 | Stream 对象


CompareBookmarks 方法 (ADO)

ADO 2.5 API 参考

CompareBookmarks 方法

比较两个书签并返回其相对值的说明。

语法

result = recordset.CompareBookmarks(Bookmark1, Bookmark2)

返回值

返回一个 CompareEnum 值，此值指示由书签表示的两个记录的相对行位置。

参数

Bookmark1
第一行的书签。
Bookmark2
第二行的书签。

说明

书签必须应用于相同的 Recordset 对象或 Recordset 对象及其副本。用户无法可靠地比较来自不同 Recordset 对象的书签，即使它们的创建来源及创建所使用的命令相同。对于其基本提供者不支持比较的 Recordset 对象，也无法比较书签。

书签仅标识 Recordset 对象中的一行。使用当前行的 Bookmark 属性可以获取其书签。

因为书签的数据类型与提供者相对应，因此 ADO 将其作为 Variant 公开。例如，SQL Server 书签为 DBTYPE_R8 类型（Double 类型）。ADO 将此类型作为 Double 子类型的 Variant 公开。

在比较书签时，ADO 并不尝试任何类型的强制措施。只是简单地将值传递给进行比较的提供者。如果将传递给 CompareBookmarks 方法的书签存储在不同类型的变量中，则将产生类型不匹配错误，显示的信息为“参数类型不正确，参数不在可接受的范围内，或者与其他数据冲突。”

无效或形式错误的书签将引发错误。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Bookmark 属性

应用于：Recordset 对象


CopyRecord 方法 (ADO)

ADO 2.5 API 参考

CopyRecord 方法

将 Record 表示的项目复制到另一位置。

语法

Record.CopyRecord (Source, Destination, UserName, Password, Options, Async)

参数

Source
可选。String 值，包含指定要复制的项目（例如，文件或目录）的 URL。如果省略 Source 或指定空字符串，则将复制当前 Record 所表示的文件或目录。
Destination
可选。String 值，包含指定要复制 Source 的位置的 URL。
UserName
可选。String 值，包含授权访问 Destination（如果需要）的用户 ID。
Password
可选。String 值，包含验证 UserName（如果需要）的密码。
Options
可选。CopyRecordOptionsEnum 值，其默认值为 adCopyUnspecified。指定此方法的行为。
Async
可选。Boolean 值，其值为 True 时指定此操作应为异步。

返回值

String 值，通常返回 Destination 的值。然而，返回的准确值要取决于提供者。

说明

Source 和 Destination 的值必须相同，否则将发生运行时错误。服务器、路径或资源的名称至少有一个不同。

除非指定 adCopyNonRecursive，否则将递归复制 Source 的所有子（如子目录）。在递归操作中，Destination 不能是 Source 的子目录，否则操作将不能完成。

如果 Destination 标识现有项目（如文件或目录），除非指定 adCopyOverWrite，否则此方法将失败。

重要信息 请斟酌使用 adCopyOverWrite 选项。例如，将一个文件复制到某个目录时，指定此选项将删除这个目录，并用此文件替换它。
注意 使用 http 模式的 URL 将自动调用 Microsoft OLE DB Provider for Internet Publishing。有关详细信息，请参阅绝对和相对 URL。

请参阅

应用于：Record 对象


CopyTo 方法 (ADO)

ADO 2.5 API 参考

CopyTo 方法

将 Stream 中指定数目的字符或字节（取决于 Type）复制到另一个 Stream 对象。

语法

Stream.CopyTo DestStream, NumChars

参数

DestStream
对象变量值，包含打开的 Stream 对象的引用。将当前 Stream 复制到由 DestStream 指定的目标 Stream。目标 Stream 必须已经打开。否则，将发生运行时错误。
注意 DestStream 参数可能不会成为 Stream 对象的代理，因为这将需要访问 Stream 对象上无法与客户端远程连接的专用接口。
NumChars
可选。Integer 值，指定要从源 Stream 中的当前位置复制到目标 Stream 的字节或字符数目。默认值为 –1，它指定将所有字符或字节从当前位置复制到 EOS。

说明

此方法从 Position 属性指定的当前位置开始，复制指定数目的字符或字节。如果指定的数目超过可用的数目（即超过 EOS），那么只复制当前位置到 EOS 之间的字符或字节。如果省略 NumChars 值或其值为 –1，将复制从当前位置开始的所有字符或字节。

如果在目标流中存在现有字符或字节，超过复制结束位置的所有内容将保留，不会被截断。Position 成为紧跟在复制的最后一个字节后面的字节。如果要截断这些字节，请调用 SetEOS。

应使用 CopyTo 将数据复制到与源 Stream 同类型的目标 Stream（两者的 Type 属性设置都是 adTypeText，或者都是 adTypeBinary）。对于文本 Stream 对象，可以更改目标 Stream 的 Charset 属性设置以进行字符集间的转换。还可以将文本 Stream 对象成功地复制到二进制 Stream 对象中，但却不能将二进制 Stream 对象复制到文本 Stream 对象中。

请参阅

应用于：Stream 对象


CreateParameter 方法 (ADO)

ADO 2.5 API 参考

CreateParameter 方法

创建具有指定属性的新的 Parameter 对象。

语法

Set parameter = command.CreateParameter (Name, Type, Direction, Size, Value)

返回值

返回 Parameter 对象。

参数

Name
可选。String 值，包含 Parameter 对象的名称。
Type
可选。DataTypeEnum 值，指定 Parameter 对象的数据类型。
Direction
可选。ParameterDirectionEnum 值，指定 Parameter 对象的类型。
Size
可选。Long 值，指定参数值的最大长度（以字符或字节为单位）。
Value
可选。Variant，指定 Parameter 对象的值。

说明

使用 CreateParameter 方法创建具用指定的名称、类型、方向、大小和值的新的 Parameter 对象。在参数中传送的任何值都将写入相应的 Parameter 属性。

此方法不会将 Parameter 对象自动追加到 Command 对象的 Parameters 集合。这样就可以设置附加属性，在将 Parameter 对象追加到集合时，ADO 将使这些附加属性的值生效。

如果在 Type 参数中指定变长数据类型，在将其追加到 Parameters 集合之前必须传送 Size 参数或者设置 Parameter 对象的 Size 属性；否则将发生错误。

如果在 Type 参数中指定数字型数据类型（adNumeric 或 adDecimal），也必须设置 NumericScale 和 Precision 属性。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Append 方法 | Parameter 对象 | Parameters 集合

应用于：Command 对象


Delete 方法（ADO Parameters 集合）

从 Parameters 集合中删除对象。

语法

Parameters.Delete Index

参数

Index
String 值，包含要删除的对象的名称，或者对象在集合中的序号位置（索引）。

说明

使用集合的 Delete 方法可删除此集合中的一个对象。此方法只能用在 Command 对象的 Parameters 集合上。在调用 Delete 方法时，必须使用 Parameter 对象的 Name 属性或其集合索引（对象变量不是有效的参数）。

请参阅

Delete 方法（ADO Fields 集合） | Delete 方法 (ADO Recordset) | DeleteRecord 方法

应用于：Parameters 集合


Delete 方法（ADO Fields 集合）

从 Fields 集合中删除对象。

语法

Fields.Delete Field

参数

Field
Variant，指定要删除的 Field 对象。此参数可以是 Field 对象的名称或 Field 对象本身的序号位置。

说明

调用打开的 Recordset 的 Fields.Delete 方法将引发运行时错误。

请参阅

Delete 方法（ADO Parameters 集合） | Delete 方法 (ADO Recordset) | DeleteRecord 方法

应用于：Fields 集合


Delete 方法 (ADO Recordset)

删除当前记录或记录组。

语法

recordset.Delete AffectRecords

参数

AffectRecords
AffectEnum 值，确定 Delete 方法影响的记录数目。默认值为 adAffectCurrent。
注意 adAffectAll 和 adAffectAllCxhapters 不是 Delete 的有效参数。

说明

使用 Delete 方法将把 Recordset 对象中的当前记录或一组记录标记为删除。如果 Recordset 对象不允许删除记录，将发生错误。如果处在立即更新模式中，将在数据库中立即执行删除操作。如果无法成功删除记录（例如，由于违反数据库完整性），则在调用 Update 之后记录将继续处于编辑模式中。这意味着必须先使用 CancelUpdate 取消更新，然后才能离开当前记录（例如，使用 Close、Move 或 NextRecordset）。

如果处在批更新模式下，则记录将标记为从缓存中删除，并在调用 UpdateBatch 方法时才发生实际删除。（使用 Filter 属性查看删除的记录。）

从已删除的记录中检索字段值将产生错误。删除当前记录后，在移动到其他记录之前，已被删除的记录将保持为当前记录。一旦从已删除的记录处移开，就不能再访问它。

如果在事务中嵌套删除，可用 RollbackTrans 方法恢复删除的记录。如果处于批更新模式下，可以用 CancelBatch 方法取消一个或一组挂起删除。

如果因与基本数据冲突（如记录已被其他用户删除）而导致删除记录的尝试失败，提供者将向 Errors 集合返回警告，但不终止程序执行。只有在所有请求的记录都冲突时，才会产生运行时错误。

如果设置了 Unique Table 动态属性，并且对多个表执行 JOIN 操作的结果为 Recordset，则 Delete 方法将仅删除 Unique Table 属性中命名的表中的行。

请参阅

Visual Basic 范例 | VBScript 范例 | Visual C++ 范例 | Visual J++ 范例

Delete 方法（ADO Fields 集合） | Delete 方法（ADO Parameters 集合） | DeleteRecord 方法

适用于：Recordset 对象


DeleteRecord 方法 (ADO)

ADO 2.5 API 参考

DeleteRecord 方法

删除 Record 表示的项目。

语法

Record.DeleteRecord Source, Async

参数

Source
可选。String 值，包含标识要删除的项目（如文件或目录）的 URL。如果省略 Source 或指定空字符串，则将删除当前 Record 表示的项目。如果该 Record 为集合记录（adCollectionRecord 的 RecordType，如目录），则所有子（子目录）也将被删除。
Async
可选。Boolean 值，其值为 True 时将指定删除操作为异步。

说明

此方法完成后，对由此 Record 表示的对象的操作可能失败。在调用 DeleteRecord 后，根据提供者用数据源更新 Record 的时间不同，Record 的行为可能不可预料，因此应将 Record 关闭。

如果此 Record 从 Recordset 获取，那么在 Recordset 中将不会立即反映此操作的结果。关闭并重新打开 Recordset，或者执行 Recordset Requery 或 Update 和 Resync 方法，将刷新 Recordset。

注意 使用 http 模式的 URL 将自动调用 Microsoft OLE DB Provider for Internet Publishing。有关详细信息，请参阅绝对和相对 URL。

请参阅

Delete 方法（ADO Fields 集合） | Delete 方法（ADO Parameters 集合） | Delete 方法 (ADO Recordset)

应用于：Record 对象


Execute 方法 (ADO Command)

执行 CommandText 属性中指定的查询、SQL 语句或存储过程。

语法

对于以 Recordset 返回的 Command：

Set recordset = command.Execute( RecordsAffected, Parameters, Options )

对于不是以记录集返回的 Command：

command.Execute RecordsAffected, Parameters, Options

返回值

返回 Recordset 对象引用或 Nothing。

参数

RecordsAffected
可选。Long 变量，提供者向其返回受操作影响的记录的数目。RecordsAffected 参数仅应用于操作查询或存储过程。RecordsAffected 不返回由返回结果的查询或存储过程返回的记录数目。若要获取此信息，请使用 RecordCount 属性。在使用 adAsyncExecute 时，Execute 方法将不能返回正确信息，原因是：如果以异步方式执行命令，当方法返回时，可能无法确定受影响的记录数目。
Parameters
可选。用 SQL 语句传递的参数值的 Variant 数组。（用此参数传递时，输出参数将不能返回正确的值。）
Options
可选。Long 值，指示提供者计算 Command 对象的 CommandText 属性的方式。该值可为使用 CommandTypeEnum 和/或 ExecuteOptionEnum 值生成的位掩码值。例如，如果您希望 ADO 计算作为文本的 CommandText 属性值，并且指示执行命令文本时放弃且不返回任何可能生成的文本，则要将 adCmdText 和 adExecuteNoRecords 配合使用。

说明

使用 Command 对象的 Execute 方法将执行在该对象的 CommandText 属性中指定的查询。如果 CommandText 属性指定以行返回的查询，执行产生的任何结果都将存储在新的 Recordset 对象中。如果此命令不是以行返回的查询，提供者将返回关闭的 Recordset 对象。如果不需要 Recordset，某些应用程序语言允许忽略此返回值。

如果查询带有参数，将使用 Command 对象的参数的当前值，除非用 Execute 调用传递的参数值覆盖它们。可以在调用 Execute 方法时通过省略某些参数的新值来覆盖参数子集。指定参数的次序与此方法传递这些参数的次序相同。例如，如果有四个（或更多）参数，用户只希望传递第一个和第四个参数的新值，那么可以将 Array(var1,,,var4) 作为 Parameters 的参数传递。

注意 在 Parameters 参数中传递时，输出参数将不能返回正确值。

此操作结束时将发出 ExecuteComplete 事件。

请参阅

Visual Basic 范例 | VBScript 范例 | Visual C++ 范例 | Visual J++ 范例 | CommandText 属性 | CommandTypeEnum | Execute 方法 (ADO Connection) | ExecuteComplete 事件

应用于：Command 对象

© 1998-2002 Microsoft Corporation。保留所有权利。


Execute 方法 (ADO Connections)

ADO 2.5 API 参考

Execute 方法 (ADO Connection)

执行指定的查询、SQL 语句、存储过程或提供者特有的文本。

语法

对于不是以行返回的命令字符串：

connection.Execute CommandText, RecordsAffected, Options

对于以行返回的命令字符串：

Set recordset = connection.Execute (CommandText, RecordsAffected, Options)

返回值

返回 Recordset 对象引用。

参数

CommandText
String 值，包含要执行的 SQL 语句、存储过程、URL 或提供者特有的文本。此外，仅当提供者被 SQL 识别时才可使用表名称。例如，如果使用“Customers”作为表名称，则 ADO 将自动预先根据标准 SQL Select 语法构成“SELECT * FROM Customers”，并将其作为 T-SQL 语句传递给提供者。
RecordsAffected
可选。Long 变量，提供者向其返回操作影响的记录数目。
Options
可选。Long 值，指示提供者计算 CommandText 参数的方式。该值可以是一个或多个 CommandTypeEnum 或 ExecuteOptionEnum 值的位掩码。
注意 使用 ExecuteOptionEnum 的 adExecuteNoRecords 值，通过使内部处理最小化来提高性能。
不要将 CommandTypeEnum 的 adCmdFile 或 adCmdTableDirect 值与 Execute 一起使用。这些值仅可用作 Recordset 的 Open 和 Requery 方法的选项。

说明

使用 Connection 对象的 Execute 方法可以执行在指定连接的 CommandText 参数中传递给该方法的查询。如果 CommandText 参数指定按行返回的查询，那么执行产生的任何结果都将存储在新的 Recordset 对象中。如果此命令不用于返回结果（如 SQL UPDATE 查询），则只要指定了 adExecuteNoRecords 选项，提供者就将返回 Nothing；否则，Execute 将返回已关闭的 Recordset。

返回的 Recordset 对象始终是只读的、仅向前的游标。如果需要具有更多功能的 Recordset 对象，应先创建具有所需属性设置的 Recordset 对象，然后使用 Recordset 对象的 Open 方法执行查询并返回所需的游标类型。

CommandText 参数的内容是提供者特有的，可以是标准的 SQL 语法或提供者支持的任何特殊命令格式。

此操作结束时将发出 ExecuteComplete 事件。

注意 使用 http 模式的 URL 将自动调用 Microsoft OLE DB Provider for Internet Publishing。有关详细信息，请参阅绝对和相对 URL。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Execute 方法 (ADO Command) | ExecuteComplete 事件

应用于：Connection 对象

© 1998-2002 Microsoft Corporation。保留所有权利。


Find 方法 (ADO)

ADO 2.5 API 参考

Find 方法

在 Recordset 中搜索满足指定条件的行。可选择指定搜索方向、起始行和从起始行的偏移量。如果满足条件，当前行的位置将设置在找到的记录上；否则将把当前行位置设置为 Recordset 的结尾（或开始）处。

语法

Find (Criteria, SkipRows, SearchDirection, Start)

参数

Criteria
String 值，包含指定用于搜索的列名、比较操作符和值的语句。
SkipRows
可选。Long 值，其默认值为零，它指定当前行或 Start 书签的行偏移量以开始搜索。在默认情况下，搜索将从当前行开始。
SearchDirection
可选。 SearchDirectionEnum 值，指定搜索应从当前行开始，还是从搜索方向的下一个有效行开始。如果该值为 adSearchForward，不成功的搜索将在 Recordset 的结尾处停止。如果该值为 adSearchBackward，不成功的搜索将在 Recordset 的开始处停止。
Start
可选。Variant 书签，用于标记搜索的开始位置。

说明

在 criteria 中只能指定单列名称。此方法不支持多列搜索。

Criteria 中的比较操作符可以是“>”（大于）、“<”（小于）、“=”（等于）、“>=”（大于或等于）、“<=”（小于或等于）、“<>”（不等于）或“like”（模式匹配）。

Criteria 中的值可以是字符串、浮点数或者日期。字符串值用单引号或“#”标记（数字号）分隔（如“state = 'WA'”或“state = #WA#”）。日期值用“#”标记（数字号）分隔（如“start_date > #7/22/97#”）并可包括小时、分钟和秒以指示时间戳，但不能包括毫秒，否则将出现错误。

如果比较操作符为“like”，可以在字符串值中包含星号 (*) 以查找一次或多次出现的任意字符或子字符串。例如，“state like 'M*'”与 Maine 和 Massachusetts 匹配。您还可以使用前导和后续星号以查找包含在值内的子字符串。例如，“state like '*as*'”与 Alaska、Arkansas 和 Massachusetts 匹配。

星号可以只在条件字符串的结尾使用，也可以在条件字符串的开头和结尾一起使用，如上所示。不能将星号作为前导通配符 ('*str') 或嵌入通配符 ('s*r') 使用。这将引发错误。

注意 如果在调用 Find 前未设置当前行的位置，将发生错误。设置行位置的任何方法（如 MoveFirst）都应在调用 Find 之前调用。
注意 如果调用记录集的 Find 方法，并且记录集的当前位置在最后一个记录上或文件结尾 (EOF)，则不能找到任何结果。您需要调用 MoveFirst 方法以将当前位置/游标设置到记录集的开始处。

请参阅

Visual Basic 范例

Index 属性 | Optimize 动态属性 (ADO) | Seek 方法

应用于：Recordset 对象


Flush 方法 (ADO)

ADO 2.5 API 参考

Flush 方法

将保留在 ADO 缓冲区中的 Stream 的内容强加到与 Stream 相关联的基本对象。

语法

Stream.Flush

说明

此方法可用于将流缓冲区的内容发送到基本对象（例如，Stream 对象的源 URL 表示的节点或文件）。要确保对 Stream 内容所做的所有更改都被写入，则应调用此方法。但是使用 ADO 时一般不必调用 Flush，因为 ADO 尽可能在后台不断刷新其缓冲区。Stream 内容的更改将自动进行，在调用 Flush 前不会被缓存。

用 Close 方法关闭 Stream 将自动刷新 Stream 的内容，而无需在 Close 之前显式地调用 Flush。

请参阅

应用于：Stream 对象


GetChildren 方法 (ADO)

ADO 2.5 API 参考

GetChildren 方法

返回 Recordset，其中各行表示 Record 集合的各个子集。

语法

Set recordset = record.GetChildren

返回值

Recordset 对象的每一行表示当前 Record 对象的一个子集。例如，表示目录的 Record 的子集可以是父目录下的文件和子目录。

说明

提供者确定在返回的 Recordset 中包含哪些列。例如，文档源提供者始终返回资源 Recordset。

请参阅

范例 | 范例

适用于：Record 对象 | Recordset 对象


GetChunk 方法 (ADO)

ADO 2.5 API 参考

GetChunk 方法

返回大的文本或二进制数据 Field 对象的全部或部分内容。

语法

variable = field.GetChunk( Size )

返回值

返回 Variant。

参数

Size
Long 表达式，等于要检索的字节或字符数。

说明

使用 Field 对象的 GetChunk 方法来检索其中的部分或全部长二进制或字符数据。在系统内存有限的情况下，可使用 GetChunk 方法操作部分而非全部 Long 值。

GetChunk 调用返回的数据将被分配给 variable。如果 Size 大于剩余的数据，则 GetChunk 方法仅返回剩余的数据而不用空格填充 variable。如果该字段为空，则 GetChunk 方法将返回 Null 值。

每个后续的 GetChunk 调用将从上一次 GetChunk 调用停止处开始检索数据。但是，如果在当前记录中检索一个字段中的数据然后设置或读取另一个字段的值，ADO 将认为已经完成对第一个字段中的数据的检索。如果在第一个字段上再次调用 GetChunk 方法，ADO 将把这次调用解释为新的 GetChunk 操作，并从数据的开始处读取。访问其他 Recordset 对象（并非第一个 Recordset 对象的副本）中的字段将不会中断 GetChunk 操作。

如果 Field 对象的 Attributes 属性中的 adFldLong 位设置为 True，则可以对该字段使用 GetChunk 方法。

如果使用 Field 对象的 Getchunk 方法时没有当前记录，将产生错误 3021（没有当前记录）。

注意 GetChunk 方法对 Record 对象的 Field 对象不起作用。它不执行任何操作并将产生运行时错误。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

AppendChunk 方法 | Attributes 属性

适用于：Field 对象


GetRows 方法 (ADO)

ADO 2.5 API 参考

GetRows 方法

将 Recordset 对象的多个记录检索到数组中。

语法

array = recordset.GetRows( Rows, Start, Fields )

返回值

返回 Variant，其值为二维数组。

参数

Rows
可选。GetRowsOptionEnum 值，指示要检索的记录数。默认值为 adGetRowsRest。
Start
可选。String 值或 Variant，计算 GetRows 操作开始处的记录的书签。还可以使用 BookmarkEnum 值。
Fields
可选。Variant，表示单个字段名或序号位置，或者字段名数组或序号位置编号。ADO 仅返回这些字段中的数据。

说明

使用 GetRows 方法将 Recordset 中的记录复制到二维数组中。第一个下标标识字段，第二个下标标识记录编号。当 GetRows 方法返回数据时，array 变量将自动调整到正确大小。

如果未指定 Rows 参数的值，GetRows 方法将自动检索 Recordset 对象中的所有记录。如果请求的记录多于可用的记录，GetRows 仅返回可用的记录数目。

如果 Recordset 对象支持书签，可以通过在 Start 参数中传递该记录的 Bookmark 属性的值来指定 GetRows 方法从哪一个记录开始检索数据。

如果要限制 GetRows 调用返回的字段，可以在 Fields 参数中传递单个字段名/编号，或者字段名/编号的数组。

在调用 GetRows 后，下一个未读取的记录成为当前记录。如果没有其他记录，EOF 属性将被设置为 True。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

适用于：Recordset 对象


GetString 方法 (ADO)

ADO 2.5 API 参考

GetString 方法

将 Recordset 作为字符串返回。

语法

Variant = recordset.GetString(StringFormat, NumRows, ColumnDelimiter, RowDelimiter, NullExpr)

返回值

将 Recordset 作为值为字符串的 Variant (BSTR) 返回。

参数

StringFormat
StringFormatEnum 值，指定将 Recordset 转换成字符串的方式。RowDelimiter、ClumnDelimiter 和 NullExpr 参数只可同 adClipString 的 StringFormat 一起使用。
NumRows
可选。Recordset 中要转换的行数。如果未指定 NumRows，或者其值大于 Recordset 中的总行数，那么将转换 Recordset 中的所有行。
ColumnDelimiter
可选。如果指定了分隔符，在列之间使用该分隔符，否则使用 TAB 字符。
RowDelimiter
可选。如果指定了分隔符，在行之间使用该分隔符，否则使用 CARRIAGE RETURN 字符。
NullExpr
可选。如果指定了表达式，在 NULL 值处使用该表达式，否则使用空字符串。

说明

行数据（但没有模式数据）被保存在字符串中。因此不能使用此字符串重新打开 Recordset。

此方法等价于 RDO GetClipString 方法。

请参阅

Visual Basic 范例

适用于：Recordset 对象


LoadFromFile 方法 (ADO)

ADO 2.5 API 参考

LoadFromFile 方法

将现有文件的内容加载到 Stream 中。

语法

Stream.LoadFromFile FileName

参数

FileName
String 值，包含要加载到 Stream 中的文件的名称。FileName 可以包含任何 UNC 格式的有效路径和名称。如果指定的文件不存在，将发生运行时错误。

说明

此方法可用于将本地文件的内容加载到 Stream 对象中。还可用于将本地文件的内容上载至服务器。

调用 LoadFromFile 之前 Stream 对象必须是打开的。此方法不改变 Stream 对象的绑定；它将仍旧绑定到原来打开 Stream 的 URL 或 Record 所指定的对象。

LoadFromFile 用从该文件中读取的数据覆盖 Stream 对象的当前内容。Stream 中任何现有的字节都被该文件的内容覆盖。LoadFromFile 创建的 EOS 后跟随的任何原有和剩余的字节都将被截去。

在调用 LoadFromFile 后，当前位置将设置在 Stream 的开始处（Position 为 0）。

为便于编码，可能会在 stream 的开始处添加 2 个字节，因此 stream 的大小与加载它的文件的大小可能不完全相同。

请参阅

适用于：Stream 对象


Move 方法 (ADO)

ADO 2.5 API 参考

Move 方法

在 Recordset 对象中移动当前记录的位置。

语法

recordset.Move NumRecords, Start

参数

NumRecords
带符号的 Long 表达式，指定当前记录位置移动的记录数。
Start
可选。String 值或 Variant，用于计算书签。还可以使用 BookmarkEnum 值。

说明

所有 Recordset 对象都支持 Move 方法。

如果 NumRecords 参数大于零，当前记录位置向前移动（向 Recordset 的结尾移动）。如果 NumRecords 小于零，当前记录位置向后移动（向 Recordset 的开始移动）。

如果 Move 调用将当前记录位置移动到首记录之前，ADO 会将当前记录设置在记录集的首记录之前（BOF 为 True）。在 BOF 属性设置为 True 时，试图向后移动将产生错误。

如果 Move 调用将当前记录位置移动到最后一个记录之后，ADO 会将当前记录设置在记录集的最后一个记录之后（EOF 为 True）。在 EOF 属性设置为 True 时，试图向前移动将产生错误。

从空的 Recordset 对象调用 Move 方法将产生错误。

假定 Recordset 对象支持书签，如果传送 Start 参数，将相对于具有此书签的记录移动。如果未指定，将相对于当前记录移动。

如果使用 CacheSize 属性在本地缓存来自提供者的记录，传送将当前记录位置移动到当前缓存记录组之外的 NumRecords 参数时，将强制 ADO 从目标记录开始检索新的记录组。CacheSize 属性确定新检索的组的大小，而目标记录是检索的第一个记录。

如果 Recordset 对象是仅向前的，用户仍然可以传送小于零的 NumRecords 参数，只要目标在当前缓存记录集合中。如果 Move 调用将当前记录位置移动到第一个缓存记录的前面，将发生错误。因此，可以使用记录缓存，它支持在仅向前滚动的提供者上完全滚动。因为缓存记录是加载到内存中的，所以应避免不必要地缓存太多记录。即使仅向前的 Recordset 对象支持这种向后移动方式，调用任何仅向前 Recordset 对象的 MovePrevious 方法仍将产生错误。

注意 根据提供者的不同，某些提供者可能不支持在仅向前的 Recordset 中向后移动。如果已将当前记录位置移动到 Recordset 中最后一个记录的后面，则向后 Move 将不能移动到当前正确的位置。

请参阅

Visual Basic 范例 | VBScript 范例 | Visual C++ 范例 | Visual J++ 范例

MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法 | MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法 (RDS) | MoveRecord 方法

适用于：Recordset 对象


MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法 (ADO)

ADO 2.5 API 参考

MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法

移动到指定的 Recordset 对象中的第一个、最后一个、下一个或上一个记录并使其成为当前记录。

语法

recordset.{MoveFirst | MoveLast | MoveNext | MovePrevious}

说明

使用 MoveFirst 方法将当前记录位置移动到 Recordset 中的第一个记录。

使用 MoveLast 方法将当前记录位置移动到 Recordset 中的最后一个记录。Recordset 对象必须支持书签或向后移动游标，否则调用该方法将产生错误。

在 Recordset 为空时（BOF 和 EOF 均为 True）调用 MoveFirst 或 MoveLast 都将产生错误。

使用 MoveNext 方法将当前记录位置向前移动一个记录（向 Recordset 的底部移动）。如果最后一个记录是当前记录并调用 MoveNext 方法，ADO 将把当前记录位置设置在 Recordset 中的最后一个记录之后（EOF 为 True）。在 EOF 属性设置为 True 时，试图向前移动将产生错误。

在 Recordset 已被过滤或排序且当前记录的数据已更改的情况下，位置可能也会改变。在这种情况下，MoveNext 方法运行正常，但应注意该位置已从新位置向前移动一个记录，而非原来的位置。例如，更改当前记录的数据，使记录移动到已排序的 Recordset 的结尾，这意味着调用 MoveNext 将导致 ADO 将当前记录位置设置在 Recordset 中的最后一个记录之后 (EOF = True)。

使用 MovePrevious 方法将当前记录位置向后移动一个记录（向 Recordset 的顶部移动）。Recordset 对象必须支持书签或向后移动游标，否则调用该方法将产生错误。如果当前记录是首记录并调用 MovePrevious 方法，ADO 将把当前记录位置设置在 Recordset 的首记录之前（BOF 为 True）。在 BOF 属性设置为 True 时，试图向后移动将产生错误。如果 Recordset 对象不支持书签或向后移动游标，MovePrevious 方法将产生错误。

如果 Recordset 是仅向前的并且用户希望同时支持向前和向后滚动，可以使用 CacheSize 属性创建记录缓存，通过 Move 方法支持向后移动游标。因为缓存记录是加载到内存中的，所以应避免不必要地缓存太多记录。可以调用仅向前的 Recordset 对象的 MoveFirst 方法，这样做可能会使提供者重新执行生成 Recordset 对象的命令。

请参阅

Visual Basic 范例 | VBScript 范例 | Visual C++ 范例 | Visual J++ 范例

Move 方法 | MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法 (RDS) | MoveRecord 方法

适用于：Recordset 对象


MoveRecord 方法 (ADO)

ADO 2.5 API 参考

MoveRecord 方法

将由 Record 表示的项目移动到其他位置。

语法

Record.MoveRecord (Source, Destination, UserName, Password, Options, Async)

参数

Source
可选。String 值，包含标识要移动的 Record 的 URL。如果省略 Source 或指定空字符串，将移动此 Record 表示的对象。例如，如果 Record 表示文件，则将文件的内容移动到 Destination 指定的位置。
Destination
可选。String 值，包含指定要移动的 Source 的位置的 URL。
UserName
可选。String 值，包含授权访问 Destination（如果需要）的用户 ID。
Password
可选。String，包含验证 UserName（如果需要）的密码。
Options
可选。MoveRecordOptionsEnum 值，其默认值为 adMoveUnspecified。指定此方法的行为。
Async
可选。Boolean 值，其值为 True 时将指定此操作为异步。

返回值

String 值。通常返回 Destination 值。然而，返回的准确值要取决于提供者。

说明

Source 和 Destination 的值必须相同，否则将发生运行时错误。至少服务器、路径和资源的名称不能相同。

对于使用 Internet Publishing Provider 移动的文件，此方法将更新正被移动的文件中的所有超文本链接（除 Options 指定的以外）。如果 Destination 标识现有的对象（例如，文件或目录），除非指定 adMoveOverWrite，否则此方法将失败。

注意 请斟酌使用 adMoveOverWrite 选项。例如，把一个文件移动到某个目录中，指定此选项将删除这个目录并用此文件替换它。

此操作完成后，Record 对象的某些属性（如 ParentURL 属性）将不会被更新。关闭 Record 然后用文件或目录移动位置的 URL 重新打开它，即可刷新 Record 对象的属性。

如果此 Record 是从 Recordset 获取的，移动的文件或目录的新位置将不会立即反映在 Recordset 中。关闭并重新打开将刷新 Recordset。

注意 使用 http 模式的 URL 将自动调用 Microsoft OLE DB Provider for Internet Publishing。有关详细信息，请参阅绝对和相对 URL。

请参阅

Move 方法 | MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法 | MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法 (RDS)

适用于：Record 对象


NextRecordset 方法 (ADO)

ADO 2.5 API 参考

NextRecordset 方法

通过执行一系列命令清除当前 Recordset 对象并返回下一个 Recordset。

语法

Set recordset2 = recordset1.NextRecordset( RecordsAffected )

返回值

返回 Recordset 对象。在语法模型中，recordset1 和 recordset2 可以是相同的 Recordset 对象，也可以使用单独的对象。当使用单独的 Recordset 对象时，在调用 NextRecordset 后重置原来 Recordset (recordset1) 上的 ActiveConnection 属性将产生错误。

参数

RecordsAffected
可选。Long 变量，提供者向其返回当前操作影响的记录数目。
注意 此参数仅返回受操作影响的记录数目，它不会从用于生成 Recordset 的选择语句中返回记录的计数。

说明

使用 NextRecordset 方法返回复合命令语句中下一条命令的结果，或者返回多个结果的存储过程的结果。如果使用 Command 的 Execute 方法或者 Recordset 的 Open 方法打开基于复合命令语句（例如“SELECT * FROM table1;SELECT * FROM table2”）的 Recordset 对象，ADO 仅执行第一个命令并将结果返回到 recordset。要访问语句中后续命令的结果，请调用 NextRecordset 方法。

只要有其他的结果，并且包含复合语句的 Recordset 未被跨进程边界断开连接或调度，那么 NextRecordset 方法将继续返回 Recordset 对象。如果以行返回的命令执行成功，但是没有返回记录，返回的 Recordset 对象将被打开，但是空的。通过验证 BOF 和 EOF 属性均为 True 来测试这种情况。如果不是以行返回的命令执行成功，返回的 Recordset 对象将被关闭，可以通过测试 Recordset 上的 State 属性验证这种情况。没有其他结果时，recordset 将被设置为 Nothing。

NextRecordset 方法在断开连接的 Recordset 对象上不可用，因为在该对象中 ActiveConnection 已被设置为 Nothing（在 Microsoft Visual Basic 中）或 NULL（在其他语言中）。

如果在立即更新模式下进行编辑，调用 NextRecordset 方法将产生错误。请先调用 Update 或 CancelUpdate 方法。

若要通过填充 Parameters 集合或者通过使用原来的 Open 或 Execute 调用传送数组为复合语句中的多个命令传送参数，这些参数在集合或数组中的次序必须与它们在命令序列中各自命令的次序相同。在读取输出参数值之前必须完成所有结果的读取。

OLE DB 提供者确定复合语句中的各个命令在何时执行。例如，Microsoft OLE DB Provider for SQL Server 在接收到复合语句时执行批中的所有命令。调用 NextRecordset 时即可返回得到的 Recordsets。

但是，其他提供者只能在 NextRecordset 被调用之后执行语句中的下一个命令。对于这些提供者，如果在单步执行整个命令语句之前显式关闭 Recordset 对象，ADO 将不再执行其余的命令。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

适用于：Recordset 对象


Open 方法 (ADO Connection)

打开到数据源的连接。

语法

connection.Open ConnectionString, UserID, Password, Options

参数

ConnectionString
可选。String 值，包含连接信息。有关有效设置的详细信息，请参阅 ConnectionString 属性。
UserID
可选。String 值，包含建立连接时要使用的用户名称。
Password
可选。String 值，包含建立连接时要使用的密码。
Options
可选。ConnectOptionEnum 值，确定应在建立连接之后（同步）还是应在建立连接之前（异步）返回本方法。

说明

使用 Connection 对象的 Open 方法建立到数据源的物理连接。当本方法成功完成后，该连接便成为有效连接，您可以对它发布命令并处理结果。

使用可选的 ConnectionString 参数指定包含一系列由分号隔开的 argument = value 语句的连接字符串，或指定用 URL 标识的文件或目录资源。ConnectionString 属性自动继承用于 ConnectionString 参数的值。因此，您既可以在打开前设置 Connection 对象的 ConnectionString 属性，也可以在调用 Open 方法过程中使用 ConnectionString 参数设置或覆盖当前连接参数。

如果同时在 ConnectionString 参数和可选的 UserID 和 Password 参数中传递用户和密码信息，那么 UserID 和 Password 参数将覆盖在 ConnectionString 中指定的值。

当结束了对打开的 Connection 的操作时，请使用 Close 方法释放所有相关的系统资源。关闭对象并不是将其从内存中删除，将来还可以更改其属性设置和用 Open 方法再次打开。若要从内存中彻底删除对象，请将对象变量设置为 Nothing。

远程数据服务用法 在客户端 Connection 对象上使用 Open 方法时，只有在 Connection 对象上打开 Recordset，才会真正建立与服务器的连接。
注意 使用 http 模式的 URL 将自动调用 Microsoft OLE DB Provider for Internet Publishing。有关详细详细，请参阅绝对和相对 URL。

请参阅

Visual Basic 范例 | VBScript 范例 | Visual C++ 范例 | Visual J++ 范例

Open 方法 (ADO Record) | Open 方法 (ADO Recordset) | Open 方法 (ADO Stream) | OpenSchema 方法

应用于：Connection 对象


Open 方法 (ADO Record)

打开现有的 Record 对象，或者创建新的由 Record 表示的项目（如文件或目录）。

语法

Open Source, ActiveConnection, Mode, CreateOptions, Options, UserName, Password

参数

Source
可选。Variant（可以表示此 Record 对象要表示的项目的 URL）、Command、打开的 Recordset 或其他 Record 对象、包含 SQL SELECT 语句或表名的字符串。
ActiveConnection
可选。Variant，表示连接字符串或打开的 Connection 对象。
Mode
可选。ConnectModeEnum 值，默认值为 adModeUnknown，指定对所得到的 Record 对象的访问模式。
CreateOptions
可选。RecordCreateOptionsEnum 值，默认值为 adFailIfNotExists，指定应打开现有的文件或目录还是应创建新的文件或目录。如果设置为默认值，将从 Mode 属性中获取访问模式。如果 Source 参数不包含 URL，则省略此参数。
Options
可选。RecordOpenOptionsEnum 值，默认值为 adOpenRecordUnspecified，指定用于打开 Record 的选项。这些值可以组合。
UserName
可选。String 值，包含授权访问 Source（如果需要）的用户 ID。
Password
可选。String 值，包含验证 UserName（如果需要）的密码。

说明

Source 可以是如下内容：

  • URL。如果 URL 的协议是 http，则默认情况下将调用 Internet Provider。如果 URL 指向包含可执行脚本（如 .ASP 页）的节点，则默认情况下打开的是包含源的 Record 而不是已执行内容。使用 Options 参数修改此行为。
  • Record 对象。从其他 Record 打开的 Record 对象将复制原来的 Record 对象。
  • Command 对象。打开的 Record 对象表示通过执行 Command 返回的单行。如果结果包含多个单行，第一行的内容将被放到记录中，同时向 Errors 集合添加一个错误。
  • SQL SELECT 语句。打开的 Record 对象表示通过执行字符串的内容返回的单行。如果结果包含多个单行，第一行的内容将被放到记录中，同时向 Errors 集合添加一个错误。
  • 表名。

如果 Record 对象表示不能通过 URL 访问（如源自数据库的 Recordset 的行）的项目，那么 ParentURL 属性的值和通过 adRecordURL 常量访问的字段的值都将为 Null。

注意 使用 http 模式的 URL 将自动调用 Microsoft OLE DB Provider for Internet Publishing。有关详细详细，请参阅绝对和相对 URL。

请参阅

范例 | 范例

Open 方法 (ADO Connection) | Open 方法 (ADO Recordset) | Open 方法 (ADO Stream) | OpenSchema 方法

适用于：Record 对象


Open 方法 (ADO Recordset)

打开游标。

语法

recordset.Open Source, ActiveConnection, CursorType, LockType, Options

参数

Source
可选。Variant，计算有效的 Command 对象、SQL 语句、表名、存储过程调用、URL 或包含持久存储 Recordset 的文件名或 Stream 对象。
ActiveConnection
可选。Variant，计算有效的 Connection 对象变量名，或包含 ConnectionString 参数的 String。
CursorType
可选。CursorTypeEnum 值，确定在打开 Recordset 时提供者应使用的游标类型。默认值为 adOpenForwardOnly。
LockType
可选。LockTypeEnum 值，确定在打开 Recordset 时提供者应使用的锁定（并发）类型。默认值为 adLockReadOnly。
Options
可选。Long 值，指示提供者计算 Source 参数的方式（如果该参数表示除 Command 对象之外的某些内容），或者指示 Recordset 应该从以前保存过的文件中恢复。可以是一个或多个 CommandTypeEnum 或 ExecuteOptionEnum 值，这些值可以用位 AND 操作符组合。
注意 如果从包含持久 Recordset 的 Stream 中打开 Recordset，那么使用 adAsyncFetchNonBlocking 的 ExecuteOptionEnum 值将不起作用；提取操作将同步进行并发生阻塞。
adExecuteNoRecords 或 adExecuteStream 的 ExecuteOpenEnum 值不应与 Open 一起使用。

说明

ADO Recordset 的默认游标是位于服务器上的仅向前的只读游标。

在 Recordset 对象上使用 Open 方法打开游标，该游标表示基本表中的记录、查询的结果或以前保存的 Recordset。

使用可选的 Source 参数指定数据源，这些数据源使用下列之一：Command 对象变量、SQL 语句、存储过程、表名、URL 或完整的文件路径名。如果 Source 是文件路径名，它可以是完整路径（“c:\dir\file.rst”）、相对路径（“..\file.rst”）或 URL（“http://files/file.rst”）。

最好不要使用 Open 方法的 Source 参数执行操作查询，由于很难确定调用是否成功，所以该查询不返回记录。由此类查询所返回的 Recordset 将被关闭。调用 Command 对象的 Execute 方法或 Connection 对象的 Execute 方法，而不要执行无返回记录的查询（如 SQL INSERT 语句）。

ActiveConnection 参数与 ActiveConnection 属性相对应，指定打开 Recordset 对象的连接。如果传递此参数的连接定义，ADO 将用指定的参数打开新连接。使用客户端游标 (CursorLocation = adUseClient) 打开 Recordset 之后，可以更改此属性的值，以将更新发送到其他提供者。或者，可以将此属性设置为 Nothing（在 Microsoft Visual Basic 中）或 NULL，以断开 Recordset 与任何提供者的的连接。但是，更改服务器端游标的 ActiveConnection 将产生错误。

对于与 Recordset 对象的属性直接对应的其他参数（Source、CursorType 和 LockType），参数与属性的关系如下：

  • 在打开 Recordset 对象之前，属性为读/写。
  • 除非在执行 Open 方法时传递相应的参数，否则将使用属性设置。如果传递一个参数，那么该参数将覆盖相应的属性设置，并用参数值更新属性设置。
  • 在打开 Recordset 对象之后，这些属性将变为只读。
注意 对于 Source 属性设置为有效 Command 对象的 Recordset 对象，即使 Recordset 对象未打开，ActiveConnection 属性也为只读。

如果同时传递 Source 参数中的 Command 对象和 ActiveConnection 参数，将产生错误。Command 对象的 ActiveConnection 属性必须已被设置为有效的 Connection 对象或连接字符串。

如果传递除 Source 参数中的 Command 对象之外的某些对象，则可以使用 Options 参数优化 Source 参数的计算。如果未定义 Options 参数，系统性能将会降低，因为 ADO 必须调用提供者来确定该参数是 SQL 语句、存储过程、URL 还是表名。如果知道正在使用的 Source 类型，则设置 Options 参数可以提示 ADO 直接跳到相关的代码。如果 Options 参数与 Source 类型不符，将产生错误。

如果传递 Source 参数中的 Stream 对象，不应将信息传递到其他参数；否则将产生错误。从 Stream 中打开 Recordset 时不会保留 ActiveConnection 信息。

如果没有与 Recordset 相关联的连接，Options 参数的默认值将为 adCmdFile。对于持久存储的 Recordset 对象，通常就是这种情况。

如果数据源不返回记录，提供者将把 BOF 和 EOF 属性都设为 True，并取消定义当前记录位置。如果游标类型允许，仍可以将新数据添加给这个空的 Recordset 对象。

当结束了对打开的 Recordset 对象的操作时，请使用 Close 方法释放所有相关的系统资源。关闭对象并不是将其从内存中删除，将来还可以更改其属性设置和用 Open 方法再次打开。若要从内存中彻底删除对象，请将对象变量设置为 Nothing。

在设置 ActiveConnection 属性之前，调用没有操作数的 Open 可以创建 Recordset 的实例，这些 Recordset 是通过将字段追加到 Recordset 的 Fields 集合中创建的。

如果已将 CursorLocation 属性设置为 adUseClient，则可用两种方法中的任何一种以异步方式来检索行。建议将 Options 设置为 adAsyncFetch。另外，可以使用 Properties 集合中的“Asynchronous Rowset Processing”动态属性，但是，如果不将 Options 参数设置为 adAsyncFetch，可能会丢失相关的检索事件。

注意 只能通过 Open 方法的 Options 参数在 MS Remote 提供者中提取背景。
注意 使用 HTTP 模式的 URL 将自动调用 Microsoft OLE DB Provider for Internet Publishing。有关详细信息，请参阅绝对和相对 URL。

请参阅

Visual Basic 范例 | VBScript 范例 | Visual C++ 范例 | Visual J++ 范例 | Visual Basic 范例

Open 方法 (ADO Connection) | Open 方法 (ADO Record) | Open 方法 (ADO Stream) | OpenSchema 方法 | Save 方法

适用于：Recordset 对象


Open 方法 (ADO Stream)

打开 Stream 对象来操作二进制或文本数据的流。

语法

Stream.Open Source, Mode, OpenOptions, UserName, Password

参数

Source
可选。Variant 值，指定 Stream 的数据源。Source 可能包含绝对 URL 字符串，该字符串指向某个众所周知的树状结构（如电子邮件或文件系统）中现有的节点。应使用 URL 关键字 ("URL=scheme://server/folder") 来指定 URL。另外，Source 也可包含对已打开的 Record 对象的引用，该对象打开与 Record 相关联的默认流。如果未指定 Source，Stream 将被实例化并被打开，默认情况下它不与基本源相关联。有关 URL 模式及其相关联的提供者的详细信息，请参阅绝对和相对 URL。
Mode
可选。ConnectModeEnum 值，指定得出的 Stream 的访问模式（例如，读/写或只读）。默认值为 adModeUnknown。有关访问模式的详细信息，请参阅 Mode 属性。如果未指定 Mode，它将被源对象继承。例如，如果以只读模式打开源 Record，那么默认情况下 Stream 也将以只读模式打开。
OpenOptions
可选。StreamOpenOptionsEnum 值。默认值为 adOpenStreamUnspecified。
UserName
可选。String 值，包含访问 Stream 对象（如果需要）的用户标识。
Password
可选。String 值，包含访问 Stream 对象（如果需要）的密码。

说明

当把 Record 对象作为源参数传递时，将不使用 UserID 和 Password 参数，因为这样就已经可以访问 Record 对象。与之类似，Record 对象的 Mode 也被传递给 Stream 对象。如果未指定 Source，打开的 Stream 将不包含数据，并且其 Size 为零 (0)。当 Stream 关闭时，要避免丢失任何写入此 Stream 的数据，请用 CopyTo 或 SaveToFile 方法保存 Stream，或将其保存到另一个内存位置。

adOpenStreamFromRecord 的 OpenOptions 值标识 Source 参数的内容，该参数为将被打开的 Record 对象。默认行为是将 Source 当作直接指向树状结构中节点（如文件）的 URL。与该节点相关联的默认流将被打开。

Stream 未打开时，有可能读取 Stream 的所有只读属性。如果异步打开 Stream，所有后续的操作（除了检查 State 和其他只读属性）都将被阻塞，直到 Open 操作完成为止。

除了上面讨论的选项以外，不通过指定 Source 也可以实例化内存中的 Stream 对象，而不将其与基本源相关联。通过使用 Write 或 WriteText 将二进制或文本数据写入 Stream，或者通过使用 LoadFromFile 从文件加载数据，可以将数据动态地添加到流。

请参阅

范例

Open 方法 (ADO Connection) | Open 方法 (ADO Record) | Open 方法 (ADO Recordset) | OpenSchema 方法 | SaveToFile 方法

适用于：Stream 对象


OpenSchema 方法 (ADO)

ADO 2.5 API 参考

OpenSchema 方法

从提供者获取数据库模式信息。

语法

Set recordset = connection.OpenSchema (QueryType, Criteria, SchemaID)

返回值

返回包含模式信息的 Recordset 对象。Recordset 将以只读、静态游标模式打开。QueryType 确定在 Recordset 中出现的列。

参数

QueryType
任意 SchemaEnum 值，表示要运行的模式查询的类型。
Criteria
可选。每个 QueryType 选项的查询约束的数组，如 SchemaEnum 中列出的内容。
SchemaID
OLE DB 规范未定义的提供者模式查询的 GUID。如果 QueryType 被设置为 adSchemaProviderSpecific，则需要此参数。否则，将不使用它。

说明

OpenSchema 方法返回有关数据源的自述信息，如数据源中包含的表、表中的列和支持的数据类型。

QueryType 参数是一个指示返回的列（模式）的 GUID。OLE DB 规范有一个完整的模式列表。

Criteria 参数限制模式查询的结果。Criteria 指定值的数组，这些值必须出现在结果 Recordset 中的列（称为“约束列”）的对应子集中。

如果提供者在上述列表中的范围以外定义自己的非标准模式查询，那么 QueryType 参数将使用 adSchemaProviderSpecific 常量。如果使用此常量，则要求用 SchemaID 参数来传递要执行的模式查询的 GUID。如果把 QueryType 设置为 adSchemaProviderSpecific 但未提供 SchemaID，将产生错误。

不要求提供者支持所有 OLE DB 标准模式查询。特别指出，OLE DB 规范只要求 adSchemaTables、adSchemaColumns 和 adSchemaProviderTypes。但并不要求提供者支持上面所列的模式查询的 Criteria 约束。

远程数据服务用法 OpenSchema 方法在客户端 Connection 对象上不可用。
注意 在 Visual Basic 中，包含从 Connection 对象 OpenSchema 方法返回的 Recordset 中的四字节无符号整数 (DBTYPE UI4) 的列不能与其他变量相比较。有关 OLE DB 数据类型的详细信息，请参阅 Microsoft OLE DB Programmer's Reference 的 Chapter 13 和 Appendix A。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Open 方法 (ADO Connection) | Open 方法 (ADO Record) | Open 方法 (ADO Recordset) | Open 方法 (ADO Stream) | Appendix A: Providers

适用于：Connection 对象


Read 方法 (ADO)

ADO 2.5 API 参考

Read 方法

从二进制 Stream 对象读取指定的字节数。

语法

Variant = Stream.Read ( NumBytes )

参数

NumBytes
可选。Long 值，指定要从文件或 StreamReadEnum 值 adReadAll（默认值）读取的字节数。

返回值

Read 方法从 Stream 对象读取指定的字节数或整个流，并以 Variant 形式返回所得到的数据。

说明

如果 NumBytes 超过 Stream 中剩余的字节数，将只返回剩余的字节。数据读取没有被填充到与 NumBytes 指定的长度一致。如果没有剩余的字节可读取，将返回一个值为 Null 的变体。Read 不能用于向后读取。

注意 NumBytes 始终度量字节。对于文本 Stream 对象（Type 为 adTypeText），使用 ReadText。

请参阅

范例

ReadText 方法

适用于：Stream 对象


ReadText 方法 (ADO)

ADO 2.5 API 参考

ReadText 方法

从文本 Stream 对象读取指定的字符数。

语法

String = Stream.ReadText ( NumChars )

参数

NumChars
可选。Long 值，指定要从文件读取的字符数，或 StreamReadEnum 值。默认值为 adReadAll。

返回值

ReadText 方法从 Stream 对象中读取指定数目的字符、整个行或整个流，并返回所得到的字符串。

说明

如果 NumChar 超过流中剩余的字符数，将只返回剩余的字符。读取的字符串没有被填充到与 NumChar 指定的长度一致。如果没有剩余的字符可读取，将返回一个值为 Null 的变体。ReadText 不能用于向后读取。

注意 ReadText 方法与文本流（Type 为 adTypeText）一起使用。对于二进制流（Type 为 adTypeBinary），使用 Read。

请参阅

范例

Read 方法

适用于：Stream 对象


Refresh 方法 (ADO)

ADO 2.5 API 参考

Refresh 方法

更新集合中的对象以反映提供者提供的和特有的对象。

语法

collection.Refresh

说明

Refresh 方法可以完成各种不同的任务，这取决于您从哪个集合调用它。

Parameters

使用 Command 对象的 Parameters 集合的 Refresh 方法检索存储过程的提供者参数信息，或者检索 Command 对象中指定的参数化查询。对于不支持存储过程调用或参数化查询的提供者，该集合将为空。

在调用 Refresh 方法之前，应先将 Command 对象的 ActiveConnection 属性设置为有效的 Connection 对象，将 CommandText 属性设置为有效的命令，并将 CommandType 属性设置为 adCmdStoredProc。

如果在调用 Refresh 方法之前访问 Parameters 集合，ADO 将自动为您调用该方法并预置集合。

注意 如果使用 Refresh 方法从提供者获取参数信息，而且返回一个或多个变长数据类型的 Parameter 对象，ADO 可能会根据参数最大可能的大小为其分配内存，这样一来，在执行中可能会发生错误。要避免错误，在调用 Execute 方法之前应显式地设置这些参数的 Size 属性。

Fields

使用 Fields 集合的 Refresh 方法将没有可视效果。要从基本数据库结构中检索更改，必须使用 Requery 方法；如果 Recordset 对象不支持书签，则必须使用 MoveFirst 方法。

Properties

使用某些对象的 Properties 集合的 Refresh 方法预置该集合，其动态属性由提供者显露。这些属性提供有关提供者特有的功能信息，ADO 支持的内置属性除外。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual VJ++ 范例

Count 属性 | Refresh 方法 (RDS)

应用于：Axes 集合 | Columns 集合 | CubeDefs 集合 | Dimensions 集合 | Errors 集合 | Fields 集合 | Groups 集合 | Hierarchies 集合 | Indexes 集合 | Keys 集合 | Levels 集合 | Members 集合 | Parameters 集合 | Positions 集合 | Procedures 集合 | Properties 集合 | Tables 集合 | Users 集合 | Views 集合


Requery 方法 (ADO)

ADO 2.5 API 参考

Requery 方法

通过重新执行对象所基于的查询来更新 Recordset 对象中的数据。

语法

recordset.Requery Options

参数

Options
可选。位掩码，包含影响本操作的 ExecuteOptionEnum 和 CommandTypeEnum 的值。
注意 如果将 Options 设置为 adAsyncExecute，本操作将异步执行，操作完成时将发布一个 RecordsetChangeComplete 事件。
adExecuteNoRecords 或 adExecuteStream 的 ExecuteOpenEnum 值不能与 Requery 一起使用。

说明

用 Requery 方法通过重新发布原始命令和再次检索数据来刷新数据源中 Recordset 对象的所有内容。调用此方法等价于依次连续调用 Close 和 Open 方法。如果正在编辑当前记录或正在添加新记录，将发生错误。

当 Recordset 对象打开时，定义游标性质（CursorType、LockType、MaxRecords 等）的属性为只读。因此，Requery 方法只能刷新当前游标。要更改任何一个游标属性并查看结果，必须使用 Close 方法以使这些属性重新变为读/写。然后可以更改属性设置并调用 Open 方法重新打开游标。

请参阅

Visual Basic 范例 | VBScript 范例 | Visual C++ 范例 | Visual J++ 范例

CommandText 属性

应用于：Recordset 对象


Resync 方法 (ADO)

ADO 2.5 API 参考

Resync 方法

从基本数据库刷新当前 Recordset 对象中的数据或 Record 对象的 Fields 集合。

语法

Recordset.Resync AffectRecords, ResyncValues
Record.Fields.Resync ResyncValues

参数

AffectRecords
可选。AffectEnum 值，确定 Resync 方法影响的记录数目。默认值为 adAffectAll。此值不能用于 Record 对象的 Fields 集合的 Resync 方法。
ResyncValues
可选。ResyncEnum 值，指定是否覆盖基本值。默认值为 adResyncAllValues。

说明

Recordset

用 Resync 方法使当前 Recordset 中的记录与基本数据库重新同步。如果正在使用静态或仅向前游标，但是想查看基本数据库中的所有更改，上述操作将大有用处。

如果将 CursorLocation 属性设置为 adUseClient，那么 Resync 只对非只读的 Recordset 对象有效。

与 Requery 方法不同，Resync 方法不重新执行 Recordset 对象的基本命令。基本数据库中的新记录将不可见。

如果因为与基本数据发生冲突（例如，记录已被另一个用户删除）而导致重新同步失败，提供者将向 Errors 集合返回警告，并发生运行时错误。用 Filter 属性 (adFilterAffectedRecords) 和 Status 属性来定位发生冲突的记录。

如果设置了 Unique Table 和 Resync Command 动态属性，并且 Recordset 是对多个表执行 JOIN 操作的结果，那么 Resync 方法仅执行在 Unique Table 属性命名的表中的 Resync Command 属性中给定的命令。

Fields

用 Resync 方法使 Record 对象的 Fields 集合的值与基本数据源重新同步。此方法不会影响 Count 属性。

如果将 ResyncValues 设置为 adResyncAllValues（默认值），那么集合中 Field 对象的 UnderlyingValue、Value 和 OriginalValue 属性都将同步。如果将 ResyncValues 设置为 adResyncUnderlyingValues，那么只有 UnderlyingValue 属性同步。

每个 Field 对象的 Status 属性值在调用时也会影响 Resync 的行为。对于 Status 值为 adFieldPendingUnknown 或 adFieldPendingInsert 的 Field 对象，Resync 没有效果。对于值为 adFieldPendingChange 或 adFieldPendingDelete 的 Status，Resync 将使仍存在于数据源中的字段的数据值同步。

只有当调用 Resync 产生错误时，Resync 才会修改 Field 对象的 Status 值。例如，如果字段已不存在，提供者将返回 Field 对象的适当 Status 值，如 adFieldDoesNotExist。返回的 Status 值可在 Status 属性的值的范围内进行逻辑组合。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Clear 方法 | UnderlyingValue 属性

应用于：Fields 集合 | Recordset 对象


Save 方法 (ADO)

ADO 2.5 API 参考

Save 方法

将 Recordset 保存在文件或 Stream 对象中。

语法

recordset.Save Destination, PersistFormat

参数

Destination
可选。Variant，表示保存 Recordset 的文件的完整路径名，或者表示对 Stream 对象的引用。
PersistFormat
可选。PersistFormatEnum 值，指定 Recordset 的保存格式（XML 或 ADTG）。默认值为 adPersistADTG。

说明

只能在打开的 Recordset 上调用 Save 方法。将来使用 Open 方法从 Destination 中恢复 Recordset。

如果 Filter 属性对 Recordset 有效，那么将只保存可在过滤器下访问的行。如果 Recordset 是分级的，那么当前的子 Recordset 及其子都将被保存，包括父 Recordset。如果调用子 Recordset 的 Save 方法，那么该子及其所有的子都将被保存，而父则不被保存。

第一次保存 Recordset 时，可以指定 Destination，也可以不指定。如果省略 Destination，将创建一个新文件，其名称被设置为 Recordset 的 Source 属性的值。

如果在第一次保存后接着调用 Save，请省略 Destination，否则将产生运行时错误。如果接着调用带有新的 Destination 的 Save，Recordset 将被保存到新的目标。但是，新的目标和原始目标都将是打开的。

Save 不关闭 Recordset 或 Destination，因此您可以继续使用 Recordset 并保存最近所做的更改。Destination 保持打开，直至 Recordset 关闭。

为安全起见，Save 方法只允许使用由 Microsoft Internet Explorer 执行的脚本中的低和自定义级别安全设置。有关安全问题的详细说明，请参阅 Microsoft Data Access Technical Articles 中的 ActiveX Data Objects (ADO) Technical Articles 下面的“ADO and RDS Security Issues in Microsoft Internet Explorer”。

如果在异步 Recordset 提取、执行或更新操作时调用 Save 方法，那么 Save 将一直等到该异步操作完成后才执行。

从 Recordset 的第一行开始保存记录。当完成 Save 方法时，当前行位置将移动到 Recordset 的第一行。

要得到最佳结果，请用 Save 将 CursorLocation 属性设置为 adUseClient。如果提供者不支持保存 Recordset 对象所必需的所有功能，Cursor Service 将提供该功能。

当持久保留 CursorLocation 属性被设置为 adUseServer 的 Recordset 时，Recordset 的更新能力将受到限制。通常只允许更新、插入和删除单个表（取决于提供者的功能）。Resync 方法在此配置下也不可用。

注意 ADO 不支持保存 Fields 设置为 adVariant、adIDispatch 或 adIUnknown 类型的 Recordset，此操作可能导致无法预测的后果。

只有条件字符串形式（例如，OrderDate > '12/31/1999'）的 Filters 对持久保留 Recordset 的内容起作用。使用 Bookmarks 数组或使用 FilterGroupEnum 中的值创建的过滤器对持久保留 Recordset 的内容不起作用。这些规则适用于使用客户端或服务器端游标创建的 Recordsets。

由于 Destination 参数可以接受支持 OLE DB IStream 接口的所有对象，因此可以将 Recordset 直接保存到 ASP Response 对象。有关详细信息，请参阅 XML Recordset 持久性方案。

也可以按 XML 格式将 Recordset 保存为 MSXML DOM 对象的一个实例，如下面的 Visual Basic 代码所示：

Dim xDOM As New MSXML.DOMDocument
Dim rsXML As New ADODB.Recordset
Dim sSQL As String, sConn As String

sSQL = "SELECT customerid, companyname, contactname FROM customers"
sConn="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Program Files" & _
        "\Common Files\System\msadc\samples\NWind.mdb"
rsXML.Open sSQL, sConn
rsXML.Save xDOM, adPersistXML   'Save Recordset directly into a DOM tree.
...
注意 以 XML 格式保存分级 Recordsets（数据构形）时有两个限制条件。如果分级 Recordset 包含挂起的更新，则不能以 XML 格式保存；参数化的分级 Recordset 也不能以 XML 格式保存。
以 XML 格式保存的 Recordset 是使用 UTF-8 格式保存的。将这类文件加载到 ADO Stream 中时，Stream 对象将不会尝试从流中打开 Recordset，除非将流的 Charset 属性设置为 UTF-8 格式的适当的值。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

Open 方法 (ADO Recordset) | Open 方法 (ADO Stream) | SaveToFile 方法

适用于：Recordset 对象 | Stream 对象


SaveToFile 方法 (ADO)

ADO 2.5 API 参考

SaveToFile 方法

把 Stream 的二进制内容保存到文件。

语法

Stream.SaveToFile FileName, SaveOptions

参数

FileName
String 值，包含要保存的 Stream 内容的文件的完整名称。可以保存到任何有效的本地位置，或任何可以通过 UNC 值访问的位置。
SaveOptions
SaveOptionsEnum 值，指定当文件不存在时 SaveToFile 是否创建新文件。默认值为 adSaveCreateNotExists。如果指定的文件不存在，可以用这些选项来指定产生错误。还可以指定 SaveToFile 覆盖现有文件的当前内容。
注意 如果覆盖现有的文件（设置 adSaveCreateOverwrite），SaveToFile 将截断原始文件中超出新 EOS 的所有字节。

说明

SaveToFile 可用于将 Stream 对象的内容复制到本地文件。Stream 对象的内容或属性不发生变化。调用 SaveToFile 之前，Stream 对象必须被打开。

此方法不更改 Stream 对象与其基本源的关联。Stream 对象将仍与原来的 URL 或 Record 关联，该 URL 或 Record 在 Stream 对象打开时就是其源。

完成 SaveToFile 操作后，流中的当前位置 (Position) 被设置到流的开始处 (0)。

请参阅

Open 方法 (ADO Stream) | Save 方法

适用于：Stream 对象


Seek 方法 (ADO)

ADO 2.5 API 参考

Seek 方法

搜索 Recordset 的索引以快速定位与指定的值相匹配的行，并使其成为当前行。

语法

recordset.Seek KeyValues, SeekOption

参数

KeyValues
Variant 值的数组。索引由一个或多个列组成，并且该数组包含与每个对应列作比较的值。
SeekOption
SeekEnum 值，指定在索引的列与相应的 KeyValues 之间进行的比较类型。

说明

如果基本提供者支持 Recordset 对象上的索引，请将 Seek 方法和 Index 属性结合使用。用 Supports (adSeek) 方法确定基本提供者是否支持 Seek，用 Supports(adIndex) 方法确定提供者是否支持索引。（例如，OLE DB Provider for Microsoft Jet 支持 Seek 和 Index。）

如果 Seek 没有找到所需的行，将不会产生错误，该行将被放在 Recordset 的结尾处。执行此方法前，请先将 Index 属性设置为所需的索引。

此方法只受服务器端游标支持。如果 Recordset 对象的 CursorLocation 属性值为 adUseClient，将不支持 Seek。

仅当使用 adCmdTableDirect 的CommandTypeEnum 值打开 Recordset 对象时，才可以使用此方法。

请参阅

Visual Basic 范例 | Visual C++ 范例

Find 方法 | Index 属性

适用于：Recordset 对象


SetEOS 方法 (ADO)

ADO 2.5 API 参考

SetEOS 方法

设置流的结尾位置。

语法

Stream.SetEOS

说明

SetEOS 通过使当前 Position 成为流的结尾来更新 EOS 属性的值。当前位置后面的所有字节或字符都将被截断。

由于 Write、WriteText 和 CopyTo 不截断现有 Stream 对象中多余的值，因此可以通过用 SetEOS 设置新的流结尾位置来截断这些字节或字符。

警告 如果将 EOS 设置到流的实际结尾前面的位置，那么新的 EOS 位置后面的所有数据都将丢失。

请参阅

适用于：Stream 对象


SkipLine 方法 (ADO)

ADO 2.5 API 参考

SkipLine 方法

读取文本流时跳过一整行。

语法

Stream.SkipLine

说明

到（包括）下一个分行符之间的所有字符都被跳过。默认情况下，LineSeparator 为 adCRLF。如果试图跳过超出 EOS 的位置，那么当前位置将保持在 EOS 处。

SkipLine 方法与文本流（Type 为 adTypeText）一起使用。

请参阅

适用于：Stream 对象


Stat 方法 (ADO)

ADO 2.5 API 参考

Stat 方法

检索有关 Stream 对象的信息。

语法

Long stream.Stat(StatStg, StatFlag)

返回值

Long 值，指示操作的状态。

参数

StatStg
STATSTG 结构，将要用有关流的信息填充该结构。ADO Stream 对象使用的 Stat 方法的实现不能填充该结构中的所有字段。
StatFlag
指定此方法不返回 STATSTG 结构中的某些成员，这样可以节省内存分配操作。从 STATFLAG 枚举中选择值。

STATFLAG 枚举有两个值
常量 | 值
STATFLAG_DEFAULT | 0
STATFLAG_NONAME | 1

说明

ADO Stream 对象实现的 Stat 方法的版本填充 STATSTG 结构中的下列字段：

pwcsName
包含流名称的字符串，如果有一个可用的字符串，就不会将 StatFlag 的值指定为 STATFLAG_NONAME。
cbSize
指定流或字节数组的字节数。
mtime
指示上次修改存储、流或字节数组的时间。
ctime
指示创建存储、流或字节数组的时间。
atime
指示上次访问存储、流或字节数组的时间。

如果在 StatFlag 参数中指定了 STATFLAG_NONAME，将不返回流名称。

如果在 StatFlag 参数中未指定 STATFLAG_NONAME，并且没有适用于当前流的名称，此值将为 E_NOTIMPL。

请参阅

适用于：Stream 对象


Supports 方法 (ADO)

ADO 2.5 API 参考

Supports 方法

确定指定的 Recordset 对象是否支持特定类型的功能。

语法

boolean = recordset.Supports( CursorOptions )

返回值

返回 Boolean 值，指示提供者是否支持用 CursorOptions 参数标识的所有功能。

参数

CursorOptions
Long 表达式，由一个或多个 CursorOptionEnum 值组成。

说明

用 Supports 方法确定 Recordset 对象支持的功能类型。如果 Recordset 对象支持其对应常量包括在 CursorOptions 中的功能，则 Supports 方法返回 True。否则，它将返回 False。

注意 尽管对于给定的功能，Supports 方法可能返回 True，但它不保证提供者能使该功能在所有情况下都可用。如果符合特定条件，Supports 方法只返回提供者是否能支持指定功能的信息。例如，即使游标是基于多表连接，并且其中某些列是不可更新的，Supports 方法仍可能指示 Recordset 对象支持更新。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

CursorType 属性

适用于：Recordset 对象


Update 方法 (ADO)

ADO 2.5 API 参考

Update 方法

保存对 Recordset 对象的当前行或者 Record 对象的 Fields 集合所做的更改。

语法

recordset.Update Fields, Values
record.Fields.Update

参数

Fields
可选。Variant 或 Variant 数组，Variant 表示单个名称，Variant 数组则表示要修改的字段的名称或序号位置。
Values
可选。Variant 或 Variant 数组，Variant 表示单个值，Variant 数组表示新记录中字段的值。

说明

Recordset

用 Update 方法保存对 Recordset 对象的当前记录所做的全部更改，这些更改是在调用 AddNew 方法或在更改现有记录中的任一字段值之后进行的。Recordset 对象必须支持更新。

若要设置字段值，请执行下列操作之一：

  • 给 Field 对象的 Value 属性指定值并调用 Update 方法。
  • 通过调用 Update 将字段名和值作为参数传递。
  • 通过调用 Update 传递字段名称数组和值数组。

如果使用字段和值的数组，那么两个数组中必须有相同数量的元素。此外，字段名称的顺序必须与字段值的顺序匹配。如果字段数目和顺序与值不匹配，将产生错误。

如果 Recordset 对象支持批更新，在调用 UpdateBatch 方法之前，可以把对一个或多个记录所做的多个更改在本地缓存。如果调用 UpdateBatch 方法时正在编辑当前记录或添加新记录，那么在将批更改传送到提供者之前，ADO 将自动调用 Update 方法保存对当前记录所做的所有挂起的更改。

如果调用 Update 方法前在正在添加或编辑的记录中移动，ADO 将自动调用 Update 保存更改。如果要取消对当前记录所做的任何更改或放弃新添加的记录，必须调用 CancelUpdate 方法。

调用 Update 方法后，当前记录仍然保持当前。

Record

Update 方法最终完成对 Record 对象 Fields 集合中字段的添加、删除和更新。

例如，用 Delete 方法删除的字段将立即被标记为删除，但仍保留在集合中。必须调用 Update 方法将这些字段从提供者的集合中真正删除。

请参阅

Visual Basic 范例 | Visual C++ 范例

AddNew 方法 | CancelUpdate 方法 | EditMode 属性 | UpdateBatch 方法

适用于：Fields 集合 | Recordset 对象


UpdateBatch 方法 (ADO)

ADO 2.5 API 参考

UpdateBatch 方法

将所有挂起的批更新写入磁盘。

语法

recordset.UpdateBatch AffectRecords

参数

AffectRecords
可选。AffectEnum 值，指示 UpdateBatch 方法影响的记录数目。

说明

当在批更新模式下修改 Recordset 对象时，请用 UpdateBatch 方法将在 Recordset 对象中所做的所有更改传送到基本数据库。

如果 Recordset 对象支持批更新，在调用 UpdateBatch 方法之前，可以把对一个或多个记录所做的多个更改在本地缓存。如果调用 UpdateBatch 方法时正在编辑当前记录或添加新记录，那么在将批更改传送到提供者之前，ADO 将自动调用 Update 方法保存对当前记录所做的所有挂起的更改。批更新应当只与键集游标或静态游标配合使用。

注意 如果当前 Recordset 中看不到记录（如没有与过滤器相匹配的记录），那么将此参数指定为 adAffectGroup 值将导致错误。

如果由于与基本数据冲突（如记录已被另一用户删除）而导致对某个或所有记录的更改传送失败，提供者将向 Errors 集合返回警告，并发生运行时错误。用 Filter 属性 (adFilterAffectedRecords) 和 Status 属性来定位发生冲突的记录。

要取消所有挂起的批更新，请使用 CancelBatch 方法。

如果设置了 Unique Table 和 Update Resync 动态属性，并且 Recordset 是对多个表执行 JOIN 操作得到的结果，那么根据 Update Resync 属性的设置，Resync 方法将在 UpdateBatch 方法之后隐式地执行。

在数据源中进行批更新时，各个更新的顺序不必与在本地 Recordset 中进行批更新的顺序相同。更新顺序取决于提供者。编写相互关联的更新代码时请注意这一点，如外键将约束插入或更新。

请参阅

Visual Basic 范例 | Visual C++ 范例 | Visual J++ 范例

CancelBatch 方法 | Clear 方法 | LockType 属性 | Update 方法

适用于：Recordset 对象


Write 方法 (ADO)

ADO 2.5 API 参考

Write 方法

将二进制数据写入 Stream 对象。

语法

Stream.Write Buffer

参数

Buffer
Variant，包含要写入的字节数组。

说明

指定的字节被写入 Stream 对象，每个字节之间没有间隔。

当前 Position 被设置为写入数据的后一个字节。Write 方法不会截断流中剩余的数据。如果要截断这些字节，请调用 SetEOS。

如果写入超过了当前 EOS 位置，Stream 的 Size 将增加以包含新的字节，EOS 也将移动到 Stream 中新的最后一个字节。

注意 Write 方法与二进制流（Type 为 adTypeBinary）一起使用。对于文本流（Type 为 adTypeText），使用 WriteText。

请参阅

WriteText 方法

适用于：Stream 对象


WriteText 方法 (ADO)

ADO 2.5 API 参考

WriteText 方法

将指定的文本字符串写入 Stream 对象。

语法

Stream.WriteText Data, Options

参数

Data
String 值，包含要写入的字符文本。
Options
可选。StreamWriteEnum 值，指定是否在指定字符串的结尾写入分行符字符。

说明

指定的字符串被写入 Stream 对象，每个字符串之间没有间隔空格或字符。

当前 Position 被设置为写入数据的后一个字节。WriteText 方法不会截断流中剩余的数据。如果要截断这些字节，请调用 SetEOS。

如果写入超过了当前 EOS 位置，Stream 的 Size 将增加以包含新的字符，EOS 也将移动到 Stream 中新的最后一个字节。

注意 WriteText 方法与文本流（Type 为 adTypeText）一起使用。对于二进制流（Type 为 adTypeBinary），使用 Write。

请参阅

Write 方法

适用于：Stream 对象


ADO 事件

BeginTransComplete | 在 BeginTrans 操作后调用。
CommitTransComplete | 在 CommitTrans 操作后调用。
ConnectComplete | 在连接启动后调用。
Disconnect | 在连接结束后调用。
EndOfRecordset | 在试图移动到超过 Recordset 结尾的行时调用。
ExecuteComplete | 在命令执行结束后调用。
FetchComplete | 在长异步操作中的所有记录已经检索到 Recordset 中之后调用。
FetchProgress | 在长异步操作期间定期调用，用于报告 Recordset 中当前已经检索的行数。
FieldChangeComplete | 在更改了一个或多个 Field 对象的值后调用。
InfoMessage | 在 ConnectionEvent 操作期间出现警告时调用。
MoveComplete | 在 Recordset 中的当前位置更改后调用。
RecordChangeComplete | 在一个或多个记录更改后调用。
RecordsetChangeComplete | 在 Recordset 更改后调用。
RollbackTransComplete | 在 RollbackTrans 操作后调用。
WillChangeField | 在挂起操作更改 Recordset 中的一个或多个 Field 对象的值之前调用。
WillChangeRecord | 在 Recordset 中的一个或多个记录（行）更改前调用。
WillChangeRecordset | 在挂起操作更改 Recordset 前调用。
WillConnect | 在连接开始前调用。
WillExecute | 在对此连接执行挂起命令前调用，使用户能够检查和修改挂起执行参数。
WillMove | WillMove 事件在挂起操作更改 Recordset 中的当前位置前调用。

请参阅

ADO API 参考 | ADO 集合 | ADO 动态属性 | ADO 枚举常量 | ADO 错误 | ADO 事件模型、同步和异步操作 | ADO 方法 | ADO 对象模型 | ADO 对象 | ADO 属性


BeginTransComplete、CommitTransComplete 和 RollbackTransComplete 事件 (ADO)

ADO 2.5 API 参考

BeginTransComplete、CommitTransComplete 和 RollbackTransComplete 事件

这些事件将在执行对 Connection 对象的相关操作后调用。

  • BeginTransComplete 在 BeginTrans 操作后调用。
  • CommitTransComplete 在 CommitTrans 操作后调用。
  • RollbackTransComplete 在 RollbackTrans 操作后调用。

语法

BeginTransComplete TransactionLevel, pError, adStatus, pConnection
CommitTransComplete pError, adStatus, pConnection
RollbackTransComplete pError, adStatus, pConnection

参数

TransactionLevel
Long 值，包含引发此事件的 BeginTrans 的新事务级别。
pError
Error 对象。描述当 EventStatusEnum 的值是 adStatusErrorsOccurred 时发生的错误；否则将不对它进行设置。
adStatus
EventStatusEnum 状态值。当调用这些事件中的任一事件时，如果引发事件的操作成功，此参数将设置为 adStatusOK；否则设置为 adStatusErrorsOccurred。

通过在事件返回前将此参数设置为 adStatusUnwantedEvent，这些事件可以避免后续的通知。

pConnection
引发此事件的 Connection 对象。

说明

在 Visual C++ 中，多个 Connection 可以共享同一个事件处理方法。该方法使用返回的 Connection 对象以确定引发事件的对象。

如果 Attributes 属性设置为 adXactCommitRetaining 或 adXactAbortRetaining，则在提交或回卷事务后将启动新的事务。使用 BeginTransComplete 事件可忽略除第一个事务启动事件以外的所有事件。

请参阅

Visual C++ 范例 | Visual J++ 范例 | Visual Basic 范例

ADO 事件处理程序汇总 | BeginTrans、CommitTrans 和 RollbackTrans 方法

应用于：Connection 对象


ConnectComplete 和 Disconnect 事件 (ADO)

ADO 2.5 API 参考

ConnectComplete 和 Disconnect 事件

ConnectComplete 事件在连接开始后调用。Disconnect 事件在连接结束后调用。

语法

ConnectComplete pError, adStatus, pConnection
Disconnect adStatus, pConnection

参数

pError
Error 对象。描述当 adStatus 的值是 adStatusErrorsOccurred 时发生的错误；否则将不对它进行设置。
adStatus
EventStatusEnum 值，总是返回 adStatusOK。

当调用 ConnectComplete 时，如果 WillConnect 事件请求取消挂起的连接，此参数将设置为 adStatusCancel。

在两个事件中的任一个返回之前，将此参数设置为 adStatusUnwantedEvent 可避免后续的通知。但是，关闭并重新打开 Connection 会导致这些事件再次发生。

pConnection
应用此事件的 Recordset。

请参阅

Visual C++ 范例

ADO 事件处理程序汇总

应用于：Connection 对象


EndOfRecordset 事件 (ADO)

ADO 2.5 API 参考

EndOfRecordset 事件

EndOfRecordset 事件在试图移动到超过 Recordset 结尾的行时调用。

语法

EndOfRecordset fMoreData, adStatus, pRecordset

参数

fMoreData
VARIANT_BOOL 值，如果将其设置为 VARIANT_TRUE，则指示有更多的行被添加到 Recordset 中。
adStatus
EventStatusEnum 状态值。

当调用 EndOfRecordset 时，如果引发事件的操作成功，此参数将被设置为 adStatusOK。如果此事件不能请求取消引发此事件的操作，它将被设置为 adStatusCantDeny。

在 EndOfRecordset 返回前，将此参数设置为 adStatusUnwantedEvent 可避免后续的通知。

pRecordset
Recordset 对象。引发此事件的 Recordset。

说明

如果 MoveNext 操作失败，则可能发生 EndOfRecordset 事件。

在试图移过 Recordset 对象的结尾时（这可能是由调用 MoveNext 引起的），将调用此事件处理程序。但是，在此事件中，可以从数据库中检索更多的记录并将其追加到 Recordset 的结尾。在这种情况下，请将 fMoreData 设置为 VARIANT_TRUE，并从 EndofRecordset 返回。然后再次调用 MoveNext 以访问新检索到的记录。

请参阅

Visual C++ 范例

ADO 事件处理程序汇总

应用于：Recordset 对象


ExecuteComplete 事件 (ADO)

ADO 2.5 API 参考

ExecuteComplete 事件

ExecuteComplete 事件在执行完命令后调用。

语法

ExecuteComplete RecordsAffected, pError, adStatus, pCommand, pRecordset, pConnection

参数

RecordsAffected
Long 值，指示该命令影响的记录的数目。
pError
Error 对象。描述当 adStatus 的值是 adStatusErrorsOccurred 时发生的错误；否则将不对它进行设置。
adStatus
EventStatusEnum 状态值。当调用此事件时，如果引发事件的操作成功，此参数将设置为 adStatusOK；否则设置为 adStatusErrorsOccurred。

在此事件返回前，将此参数设置为 adStatusUnwantedEvent 可避免后续的通知。

pCommand
被执行的 Command 对象。即使在调用 Connection.Execute 或 Recordset.Open 时没有显式创建 Command，也会包含 Command 对象。在这种情况下，Command 对象将由 ADO 内部创建。
pRecordset
Recordset 对象，是命令执行的结果。此 Recordset 可能为空。当 ADO 试图访问不再存在的对象时，这样做将导致“访问冲突”。
pConnection
Connection 对象，通过该连接执行操作。

说明

ExecuteComplete 事件可能由下列方法引发：Connection.Execute、Command.Execute、Recordset.Open、Recordset.Requery 或 Recordset.NextRecordset 方法。

请参阅

Visual C++ 范例

ADO 事件处理程序汇总

应用于：Connection 对象


FetchComplete 事件 (ADO)

ADO 2.5 API 参考

FetchComplete 事件

FetchComplete 事件在长异步操作中的所有记录被检索到 Recordset 后调用。

语法

FetchComplete pError, adStatus, pRecordset

参数

pError
Error 对象。描述当 adStatus 的值是 adStatusErrorsOccurred 时发生的错误；否则将不对它进行设置。
adStatus
EventStatusEnum 状态值。当调用此事件时，如果引发事件的操作成功，此参数将设置为 adStatusOK；否则设置为 adStatusErrorsOccurred。

在此事件返回前，将此参数设置为 adStatusUnwantedEvent 可避免后续的通知。

pRecordset
Recordset 对象。为其检索记录的对象。

说明

若要通过 Microsoft Visual Basic 使用 FetchComplete，需要 Visual Basic 6.0 或更新版本。

请参阅

Visual C++ 范例

ADO 事件处理程序汇总

应用于：Recordset 对象


FetchProgress 事件 (ADO)

ADO 2.5 API 参考

FetchProgress 事件

FetchProgress 事件在长异步操作期间定期调用，报告提取操作当前检索到 Recordset 中的行数。

语法

FetchProgress Progress, MaxProgress, adStatus, pRecordset

参数

Progress
Long 值，指示当前已由提取操作检索的记录数目。
MaxProgress
Long 值，指示要检索的最大记录数目。
adStatus
EventStatusEnum 状态值。
pRecordset
Recordset 对象，即正在为其检索记录的对象。

说明

在使用包含子 Recordset 的 FetchProgress 时，请注意 Progress 和 MaxProgress 参数值来自基本 Cursor Service 的行集合。返回值表示基本行集合中的记录总数，而不仅是当前子集中的记录数。

注意 要通过 Microsoft Visual Basic 使用 FetchProgress，需要 Visual Basic 6.0 或更新版本。

请参阅

Visual C++ 范例

ADO 事件处理程序汇总

应用于：Recordset 对象


InfoMessage 事件 (ADO)

ADO 2.5 API 参考

InfoMessage 事件

InfoMessage 事件在 ConnectionEvent 操作期间出现警告时调用。

语法

InfoMessage pError, adStatus, pConnection

参数

pError
Error 对象。此参数包含返回的任何错误。如果返回多个错误，则枚举 Errors 集合以查找它们。
adStatus
EventStatusEnum 状态值。如果出现警告，adStatus 将被设置为 adStatusOK，并且 pError 中包含该警告。

在此事件返回前，将此参数设置为 adStatusUnwantedEvent 可避免后续的通知。

pConnection
Connection 对象。引发警告的连接。例如，在打开 Connection 对象或对 Connection 执行 Command 时可能出现警告。

请参阅

Visual C++ 范例

ADO 事件处理程序汇总

应用于：Connection 对象


WillChangeField 和 FieldChangeComplete 事件 (ADO)

ADO 2.5 API 参考

WillChangeField 和 FieldChangeComplete 事件

WillChangeField 事件在挂起操作更改 Recordset 中的一个或多个 Field 对象的值以前调用。FieldChangeComplete 事件在一个或多个 Field 对象的值更改后调用。

语法

WillChangeField cFields, Fields, adStatus, pRecordset
FieldChangeComplete cFields, Fields, pError, adStatus, pRecordset

参数

cFields
Long，指示 Fields 中 Field 对象的数目。
Fields
对于 WillChangeField，Fields 参数是一个 Variant 数组，包含 Field 对象的原始值。

对于 FieldChangeComplete，Fields 参数是一个 Variant 数组，包含 Field 对象的更改后的值。
pError
Error 对象。描述当 adStatus 的值是 adStatusErrorsOccurred 时发生的错误；否则将不对它进行设置。
adStatus
EventStatusEnum 状态值。

当调用 WillChangeField 时，如果引发事件的操作成功，此参数将被设置为 adStatusOK。如果此事件无法请求取消挂起的操作，它将被设置为 adStatusCantDeny。

当调用 FieldChangeComplete 时，如果引发事件的操作成功，此参数将设置为 adStatusOK；否则设置为 adStatusErrorsOccurred。

在返回 WillChangeField 之前，将此参数设置为 adStatusCancel 可请求取消挂起的操作。

在返回 FieldChangeComplete 之前，将此参数设置为 adStatusUnwantedEvent 可避免后续的通知。

pRecordset
Recordset 对象。引发此事件的 Recordset。

说明

在用字段和值数组参数设置 Value 属性并调用 Update 方法时，可能会发生 WillChangeField 或 FieldChangeComplete 事件。

请参阅

Visual C++ 范例

ADO 事件处理程序汇总

应用于：Recordset 对象


WillChangeRecord 和 RecordChangeComplete 事件 (ADO)

ADO 2.5 API 参考

WillChangeRecord 和 RecordChangeComplete 事件

WillChangeRecord 事件在 Recordset 中的一个或多个记录（行）更改之前调用。RecordChangeComplete 事件在一个或多个记录更改之后调用。

语法

WillChangeRecord adReason, cRecords, adStatus, pRecordset
RecordChangeComplete adReason, cRecords, pError, adStatus, pRecordset

参数

adReason
EventReasonEnum 值，指定此事件的起因。其值可以是 adRsnAddNew、adRsnDelete、adRsnUpdate、adRsnUndoUpdate、adRsnUndoAddNew、adRsnUndoDelete 或 adRsnFirstChange。
cRecords
Long 值，指示受更改影响的记录数目。
pError
Error 对象。描述当 adStatus 的值是 adStatusErrorsOccurred 时发生的错误；否则将不对它进行设置。
adStatus
EventStatusEnum 状态值。

当调用 WillChangeRecord 时，如果引发事件的操作成功，此参数将设置为 adStatusOK。如果此事件无法请求取消挂起的操作，它将被设置为 adStatusCantDeny。

当调用 RecordChangeComplete 时，如果引发事件的操作成功，此参数将设置为 adStatusOK；否则设置为 adStatusErrorsOccurred。

在返回 WillChangeRecord 之前，将此参数设置为 adStatusCancel 可请求取消引发此事件的操作，或者将此参数设置为 adStatusUnwantedEvent 可避免后续的通知。

在返回 RecordChangeComplete 之前，将此参数设置为 adStatusUnwantedEvent 可避免后续的通知。

pRecordset
Recordset 对象。引发此事件的 Recordset。

说明

WillChangeRecord 或 RecordChangeComplete 事件可能因下列 Recordset 操作而针对行中第一个更改的字段发生：Update、Delete、CancelUpdate、AddNew、UpdateBatch 和 CancelBatch。Recordset CursorType 的值确定了引发事件的操作。

在 WillChangeRecord 事件期间，Recordset Filter 属性将被设置为 adFilterAffectedRecords。在处理事件时不能更改此属性。

对于每个可能的 adReason 值，必须将 adStatus 参数设置为 adStatusUnwantedEvent，以便对任何包括 adReason 参数的事件完全停止事件通知。

请参阅

Visual C++ 范例

ADO 事件处理程序汇总

应用于：Recordset 对象


WillChangeRecordset 和 RecordsetChangeComplete 事件 (ADO)

ADO 2.5 API 参考

WillChangeRecordset 和 RecordsetChangeComplete 事件

WillChangeRecordset 事件在挂起的操作更改 Recordset 之前调用。RecordsetChangeComplete 事件在 Recordset 更改后调用。

语法

WillChangeRecordset   adReason, adStatus, pRecordset
RecordsetChangeComplete   adReason, pError, adStatus, pRecordset

参数

adReason
EventReasonEnum 值，指定此事件的起因。其值可以是 adRsnRequery、adRsnResynch、adRsnClose 和 adRsnOpen。
adStatus
EventStatusEnum 状态值。

当调用 WillChangeRecordset 时，如果引发事件的操作成功，此参数将设置为 adStatusOK。如果此事件无法请求取消挂起的操作，它将被设置为 adStatusCantDeny。

当调用 RecordsetChangeComplete 时，如果引发事件的操作成功，此参数将设置为 adStatusOK；如果操作失败，则设置为 adStatusErrorsOccurred；如果与以前接受的 WillChangeRecordset 事件相关联的操作已被取消，则设置为 adStatusCancel。

在返回 WillChangeRecordset 之前，将此参数设置为 adStatusCancel 可请求取消挂起操作，或者将此参数设置为 adStatusUnwantedEvent 可避免后续的通知。

在返回 WillChangeRecordset 或 RecordsetChangeComplete 之前，将此参数设置为 adStatusUnwantedEvent 可避免后续的通知。

pError
Error 对象。描述当 adStatus 的值是 adStatusErrorsOccurred 时发生的错误；否则将不对它进行设置。
pRecordset
Recordset 对象。引发此事件的 Recordset。

说明

WillChangeRecordset 或 RecordsetChangeComplete 事件可能由 Recordset 的 Requery 或 Open 方法引发。

如果提供者不支持书签，则每次从提供者处检索新行时，都将发生 RecordsetChange 事件通知。此事件的频率取决于 RecordsetCacheSize 属性。

对于每个可能的 adReason 值，必须将 adStatus 参数设置为 adStatusUnwantedEvent，以便对任何包括 adReason 参数的事件完全停止事件通知。

请参阅

Visual C++ 范例

ADO 事件处理程序汇总

应用于：Recordset 对象


WillConnect 事件 (ADO)

ADO 2.5 API 参考

WillConnect 事件

WillConnect 事件在连接开始前调用。

语法

WillConnect ConnectionString, UserID, Password, Options, adStatus, pConnection

参数

ConnectionString
String，包含挂起连接的连接信息。
UserID
String，包含挂起连接的用户名。
Password
String，包含挂起连接的密码。
Options
Long 值，指示提供者计算 ConnectionString 的方式。唯一的选项是 adAsyncOpen。
adStatus
EventStatusEnum 状态值。

在调用此事件时，此参数默认设置为 adStatusOK。如果此事件无法请求取消挂起的操作，它将被设置为 adStatusCantDeny。

在此事件返回前，将此参数设置为 adStatusUnwantedEvent 可避免后续的通知。将此参数设置为 adStatusCancel 可请求引发取消此通知的连接操作。

pConnection
应用此事件通知的 Connection 对象。WillConnect 事件处理程序对 Connection 参数的更改不会影响 Connection。

说明

在调用 WillConnect 时，ConnectionString、UserID、Password 和 Options 参数将被设置为由引发此事件（挂起连接）的操作建立的值，并可以在事件返回前更改。WillConnect 可以返回取消挂起连接的请求。

在取消此事件时，将调用 ConnectComplete，其 adStatus 参数设置为 adStatusErrorsOccurred。

请参阅

Visual C++ 范例

ADO 事件处理程序汇总

应用于：Connection 对象


WillExecute 事件 (ADO)

ADO 2.5 API 参考

WillExecute 事件

WillExecute 事件在对连接执行挂起命令之前调用。

语法

WillExecute Source, CursorType, LockType, Options, adStatus, pCommand, pRecordset, pConnection

参数

Source
String，包含 SQL 命令或存储过程名称。
CursorType
CursorType CursorTypeEnum，包含将要打开的 Recordset 的游标类型。使用此参数，可以在 Recordset 的 Open 操作期间更改游标的类型。对于任何其他操作，CursorType 将被忽略。
LockType
CursorTypeEnum，包含将要打开的 Recordset 的锁定类型。使用此参数，可以在 Recordset 的 Open 操作期间更改锁定的类型。对于任何其他操作，LockType 将被忽略。
Options
Long 值，指示可用于执行命令或打开 Recordset 的选项。
adStatus
EventStatusEnum 状态值，在调用此事件时，此值可以是 adStatusCantDeny 或 adStatusOK。如果值为 adStatusCantDeny，此事件不能请求取消挂起的操作。

在返回此事件之前，将此参数设置为 adStatusUnwantedEvent 可避免后续的通知，设置为 adStatusCancel 可请求取消引发此事件的操作。

pCommand
应用此事件通知的 Command 对象。
pRecordset
应用此事件通知的 Recordset 对象。
pConnection
应用此事件通知的 Connection 对象。

说明

WillExecute 事件可能由 Connection.Execute、Command.Execute 或 Recordset.Open 方法引发。pConnection 参数始终应包含对 Connection 对象的有效引用。如果此事件由 Connection.Execute 引发，pRecordset 和 pCommand 参数将被设置为 Nothing。如果此事件由 Recordset.Open 引发，pRecordset 参数将引用 Recordset 对象，pCommand 参数将设置为 Nothing。如果此事件由 Command.Execute 引发，pCommand 参数将引用 Command 对象，pRecordset 参数将设置为 Nothing。

WillExecute 允许检查和修改挂起执行的参数。此事件可以返回取消挂起命令的请求。

请参阅

Visual C++ 范例

ADO 事件处理程序汇总

应用于：Connection 对象

© 1998-2002 Microsoft Corporation。保留所有权利。


WillMove 和 MoveComplete 事件 (ADO)

ADO 2.5 API 参考

WillMove 和 MoveComplete 事件

WillMove 事件在挂起操作更改 Recordset 中的当前位置前调用。MoveComplete 事件在更改 Recordset 中的当前位置后调用。

语法

WillMove adReason, adStatus, pRecordset
MoveComplete adReason, pError, adStatus, pRecordset

参数

adReason
EventReasonEnum 值，指定此事件的起因。其值可以是 adRsnMoveFirst、adRsnMoveLast、adRsnMoveNext、adRsnMovePrevious、adRsnMove 或 adRsnRequery。
pError
Error 对象。描述当 adStatus 的值是 adStatusErrorsOccurred 时发生的错误；否则将不对它进行设置。
adStatus
EventStatusEnum 状态值。

当调用 WillMove 时，如果引发事件的操作成功，此参数将设置为 adStatusOK。如果此事件无法请求取消挂起的操作，它将被设置为 adStatusCantDeny。

当调用 MoveComplete 时，如果引发事件的操作成功，此参数将设置为 adStatusOK；否则设置为 adStatusErrorsOccurred。

在返回 WillMove 之前，将此参数设置为 adStatusCancel 可请求取消挂起操作，或者将此参数设置为 adStatusUnwantedEvent 可避免后续的通知。

在 MoveComplete 返回前，将此参数设置为 adStatusUnwantedEvent 可避免后续的通知。

pRecordset
Recordset 对象。引发此事件的 Recordset。

说明

WillMove 或 MoveComplete 事件可能由下列 Recordset 操作引发：Open、Move、MoveFirst、MoveLast、MoveNext、MovePrevious、AddNew 和 Requery。这些事件可能由下列属性引发：Filter、Index、Bookmark、AbsolutePage 和 AbsolutePosition。如果子 Recordset 已经用 Recordset 事件进行了连接并且父 Recordset 被移动，也将引发这些事件。

对于每个可能的 adReason 值，必须将 adStatus 参数设置为 adStatusUnwantedEvent，以便对任何包括 adReason 参数的事件完全停止事件通知。

请参阅

Visual C++ 范例

ADO 事件处理程序汇总

应用于：Recordset 对象


ADO 枚举常量

为了帮助调试，ADO 枚举列出了每个常量的值。但是，此值仅供参考。在不同的 ADO 版本中，它可能会有变化。代码应只取决于每个枚举常量的名称，而不是实际值。

ADCPROP_ASYNCTHREADPRIORITY_ENUM | 对于 RDS Recordset 对象，指定检索数据的异步线程的执行优先级。
ADCPROP_AUTORECALC_ENUM | 指定 MSDataShape 提供者何时重新计算分级 Recordset 中的合计列和计算列。
ADCPROP_UPDATECRITERIA_ENUM | 指定哪个字段可以用于检测在通过 Recordset 对象开放式更新数据源的行期间的冲突。
ADCPROP_UPDATERESYNC_ENUM | 指定 UpdateBatch 方法后面是否跟随隐式 Resync 方法操作，如果是，则指定操作的范围。
AffectEnum | 指定操作影响了哪些记录。
BookmarkEnum | 指定书签，该书签指示操作将从何处开始。
CommandTypeEnum | 指定解释命令参数的方法。
CompareEnum | 指定由各自书签表示的两个记录的相对位置。
ConnectModeEnum | 指定在 Connection 中修改数据、打开 Record 或指定 Record 和 Stream 对象 Mode 属性的值的可用权限。
ConnectOptionEnum | 指定 Connection 对象的 Open 方法将在连接建立之后（同步）还是之前（异步）返回。
ConnectPromptEnum | 指定打开到 ODBC 数据源的连接时，是否将显示一个对话框以提示缺少参数。
CopyRecordOptionsEnum | 指定 CopyRecord 方法的行为。
CursorLocationEnum | 指定游标引擎的位置。
CursorOptionEnum | 指定 Supports 方法将测试的功能。
CursorTypeEnum | 指示 Recordset 对象中所用游标的类型。
DataTypeEnum | 指定 Field、Parameter 或 Property 的数据类型。
EditModeEnum | 指定记录的编辑状态。
ErrorValueEnum | 指定 ADO 运行时错误的类型。
EventReasonEnum | 指定导致事件发生的原因。
EventStatusEnum | 指定事件执行的当前状态。
ExecuteOptionEnum | 指定提供者执行命令的方式。
FieldEnum | 指定在 Record 对象的 Fields 集合中引用的特殊字段。
FieldAttributeEnum | 指定 Field 对象的一个或多个属性。
FieldStatusEnum | 指定 Field 对象的状态。
FilterGroupEnum | 指定要从 Recordset 中过滤的记录组。
GetRowsOptionEnum | 指定要从 Recordset 中检索的记录的数量。
IsolationLevelEnum | 指示 Connection 对象的事务隔离级别。
LineSeparatorsEnum | 指定在文本 Stream 对象中用作分行符的字符。
LockTypeEnum | 指定在编辑过程中记录上的锁定类型。
MarshalOptionsEnum | 指定要将哪些记录返回服务器。
MoveRecordOptionsEnum | 指定 Record 对象的 MoveRecord 方法的行为。
ObjectStateEnum | 指定对象的状态是已打开或已关闭、正在连接到数据源、正在执行命令，还是正在提取数据。
ParameterAttributesEnum | 指定 Parameter 对象的属性。
ParameterDirectionEnum | 指定 Parameter 是表示输入参数、输出参数还是两者都表示，或者指示该参数是否是从存储过程返回的值。
PersistFormatEnum | 指定保存 Recordset 的格式。
PositionEnum | 指定记录指针在 Recordset 中的当前位置。
PropertyAttributesEnum | 指定 Property 对象的属性。
RecordCreateOptionsEnum | 对 Record 对象 Open 方法指定是打开现有的 Record 还是创建新的 Record。
RecordOpenOptionsEnum | 指定打开 Record 的选项。这些值可以用 OR 操作符组合。
RecordStatusEnum | 指定批更新和其他大量操作的相关记录的状态。
RecordTypeEnum | 指定 Record 对象的类型。
ResyncEnum | 指定是否通过调用 Resync 来覆盖基本值。
SaveOptionsEnum | 指定从 Stream 对象保存时是创建文件还是覆盖文件。这些值可以用 AND 操作符组合。
SchemaEnum | 指定 OpenSchema 方法检索的模式 Recordset 的类型。指定 Recordset 中记录搜索的方向。
SearchDirectionEnum | 指定 Recordset 中记录搜索的方向。指定要执行的 Seek 类型。
SeekEnum | 指定要执行的 Seek 类型。指定打开 Stream 对象的选项。这些值可以用 AND 操作符组合。
StreamOpenOptionsEnum | 指定打开 Stream 对象的选项。这些值可以用 AND 操作符组合。指定是从 Stream 对象读取整个流还是下一行。
StreamReadEnum | 指定是从 Stream 对象读取整个流还是下一行。指定存储在 Stream 对象中的数据类型。
StreamTypeEnum | 指定存储在 Stream 对象中的数据类型。指定是否将分行符追加到写入 Stream 对象的字符串中。
StreamWriteEnum | 指定是否将分行符追加到写入 Stream 对象的字符串中。指定将 Recordset 作为字符串检索时使用的格式。
StringFormatEnum | 指定将 Recordset 作为字符串检索时使用的格式。指定 Connection 对象的事务属性。
XactAttributeEnum | 指定 Connection 对象的事务属性。

请参阅

ADO API 参考 | ADO 集合 | ADO 动态属性 | ADO 错误 | ADO 事件 | ADO 方法 | ADO 对象模型 | ADO 对象 | ADO 属性


ADCPROP_ASYNCTHREADPRIORITY_ENUM

对于 RDS Recordset 对象，指定检索数据的异步线程的执行优先级。

这些常量与 Recordset 的“Background Thread Priority”动态属性一起使用，该属性在 ADO-to-OLE DB Dynamic Property 索引中引用并在 Microsoft Cursor Service for OLE DB 文档中说明。

常量 | 值 | 说明
adPriorityAboveNormal | 4 | 将优先级设置在普通和最高之间。
adPriorityBelowNormal | 2 | 将优先级设置在最低和普通之间。
adPriorityHighest | 5 | 将优先级设置为可能的最高级别。
AdPriorityLowest | 1 | 将优先级设置为可能的最低级别。
adPriorityNormal | 3 | 将优先级设置为普通级别。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.AdcPropAsyncThreadPriority.ABOVENORMAL
AdoEnums.AdcPropAsyncThreadPriority.BELOWNORMAL
AdoEnums.AdcPropAsyncThreadPriority.HIGHEST
AdoEnums.AdcPropAsyncThreadPriority.LOWEST
AdoEnums.AdcPropAsyncThreadPriority.NORMAL


ADCPROP_AUTORECALC_ENUM

指定 MSDataShape 提供者何时重新计算分级 Recordset 中的合计列和计算列。

这些常量仅与 MSDataShape 提供者和 Recordset 的“Auto Recalc”动态属性一起使用，该属性在 ADO 动态属性索引中引用并在 Microsoft Cursor Service for OLE DB 或 Microsoft Data Shaping Service for OLE DB 文档中说明。

常量 | 值 | 说明
adRecalcAlways | 1 | 默认值。只要 MSDataShape 提供者确定计算列所依赖的值已更改，就要重新计算。
adRecalcUpFront | 0 | 仅在最初生成分级 Recordset 时计算。

ADO/WFC 等价内容

这些常量没有 ADO/WFC 等价内容。


ADCPROP_UPDATECRITERIA_ENUM

指定哪些字段可用于检测在通过 Recordset 对象开放式更新数据源的行期间的冲突。

这些常量与 Recordset 的“Update Criteria”动态属性一起使用，该属性在 ADO 动态属性索引中引用并在 Microsoft Cursor Service for OLE DB 文档中说明。

常量 | 值 | 说明
adCriteriaAllCols | 1 | 在数据源行的任意列被更改时检测冲突。
adCriteriaKey | 0 | 如果数据源行的键列发生更改（即该行已被删除），则检测冲突。
adCriteriaTimeStamp | 3 | 如果数据源行的时间戳发生更改（即在获取 Recordset 之后访问过该行），则检测冲突。
adCriteriaUpdCols | 2 | 如果数据源行中与 Recordset 的已更新字段相对应的任意列被更改，则检测冲突。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.AdcPropUpdateCriteria.ALLCOLS
AdoEnums.AdcPropUpdateCriteria.KEY
AdoEnums.AdcPropUpdateCriteria.TIMESTAMP
AdoEnums.AdcPropUpdateCriteria.UPDCOLS


ADCPROP_UPDATERESYNC_ENUM

指定 UpdateBatch 方法后面是否跟随隐式 Resync 方法操作，如果是，则指定操作的范围。

常量 | 值 | 说明
adResyncAll | 15 | 通过其他所有 ADCPROP_UPDATERESYNC_ENUM 成员的组合值调用 Resync。
adResyncAutoIncrement | 1 | 默认值。试图检索由数据源（例如 Microsoft Jet AutoNumber 字段或 Microsoft SQL Server Identity 列）自动增加或生成的列的新标识值。
adResyncConflicts | 2 | 对由于并发冲突而导致行的更新或删除操作失败的所有行调用 Resync。
adResyncInserts | 8 | 对所有成功插入的行调用 Resync。但是，AutoIncrement 列值没有重新同步。相反，新插入的行的内容将基于现有的主键值被重新同步。如果主键值是 AutoIncrement 值，Resync 将不检索预期的行的内容。为了自动增加 AutoIncrement 主键值，通过 adResyncAutoIncrement + adResyncInserts 的组合值调用 UpdateBatch。
adResyncNone | 0 | 不调用 Resync。
adResyncUpdates | 4 | 对所有成功更新的行调用 Resync。

请参阅

应用于：Update Resync 动态属性 (ADO)


AffectEnum

指定操作影响了哪些记录。

常量 | 值 | 说明
adAffectAll | 3 | 如果没有应用于 Recordset 的 Filter，将影响所有记录。 如果 Filter 属性设置为字符串条件（例如“Author='Smith'”），那么操作将影响当前子集中的可见记录。 如果 Filter 属性设置为 FilterGroupEnum 的成员或 Bookmarks 的数组，那么操作将影响 Recordset 的所有行。 注意 在 Visual Basic Object Browser 中 adAffectAll 是隐藏的。
adAffectAllChapters | 4 | 影响 Recordset 的所有兄弟子集中的所有记录，包括那些通过任何当前应用的 Filter 都不可见的记录。
adAffectCurrent | 1 | 仅影响当前记录。
adAffectGroup | 2 | 仅影响满足当前 Filter 属性设置的记录。要使用此选项，必须将 Filter 属性设置为 FilterGroupEnum 值或设置为 Bookmarks 的数组。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.Affect.ALL
AdoEnums.Affect.ALLCHAPTERS
AdoEnums.Affect.CURRENT
AdoEnums.Affect.GROUP

请参阅

应用于：CancelBatch 方法 | Delete 方法 (ADO Recordset) | Resync 方法 | UpdateBatch 方法


BookmarkEnum

指定书签，该书签指示操作将从何处开始。

常量 | 值 | 说明
adBookmarkCurrent | 0 | 从当前记录开始。
adBookmarkFirst | 1 | 从第一个记录开始。
adBookmarkLast | 2 | 从最后一个记录开始。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.Bookmark.CURRENT
AdoEnums.Bookmark.FIRST
AdoEnums.Bookmark.LAST

请参阅

应用于：GetRows 方法 | Move 方法


CommandTypeEnum

指定解释命令参数的方法。

常量 | 值 | 说明
adCmdUnspecified | -1 | 不指定命令类型的参数。
adCmdText | 1 | 按命令或存储过程调用的文本定义计算 CommandText。
adCmdTable | 2 | 按表名计算 CommandText，该表的列全部是由内部生成的 SQL 查询返回的。
adCmdStoredProc | 4 | 按存储过程名计算 CommandText。
adCmdUnknown | 8 | 默认值。指示 CommandText 属性中命令的类型未知。
adCmdFile | 256 | 按持久存储的 Recordset 的文件名计算 CommandText。只与 Recordset. Open 或 Requery 一起使用。
adCmdTableDirect | 512 | 按表名计算 CommandText，该表的列被全部返回。只与 Recordset.Open 或 Requery 一起使用。若要使用 Seek 方法，必须通过 adCmdTableDirect 打开 Recordset。 该值不能与 ExecuteOptionEnum 的值 adAsyncExecute 组合。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.CommandType.UNSPECIFIED
AdoEnums.CommandType.TEXT
AdoEnums.CommandType.TABLE
AdoEnums.CommandType.STOREDPROC
AdoEnums.CommandType.UNKNOWN
AdoEnums.CommandType.FILE
AdoEnums.CommandType.TABLEDIRECT

请参阅

应用于：CommandType 属性 | Execute 方法 (ADO Command) | Execute 方法 (ADO Connection) | Open 方法 (ADO Recordset) | Requery 方法


CompareEnum

指定由各自书签表示的两个记录的相对位置。

常量 | 值 | 说明
adCompareEqual | 1 | 指示书签是相等的。
adCompareGreaterThan | 2 | 指示第一个书签在第二个书签之后。
adCompareLessThan | 0 | 指示第一个书签在第二个书签之前。
adCompareNotComparable | 4 | 指示书签不能作比较。
adCompareNotEqual | 3 | 指示书签不相等并且没有排序。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.Compare.EQUAL
AdoEnums.Compare.GREATERTHAN
AdoEnums.Compare.LESSTHAN
AdoEnums.Compare.NOTCOMPARABLE
AdoEnums.Compare.NOTEQUAL

请参阅

应用于：CompareBookmarks 方法


ConnectModeEnum

指定在 Connection 中修改数据、打开 Record 或指定 Record 和 Stream 对象 Mode 属性的值的可用权限。

常量 | 值 | 说明
adModeRead | 1 | 指示只读权限。
adModeReadWrite | 3 | 指示读/写权限。
adModeRecursive | 0x400000 | 与其他 *ShareDeny* 值（adModeShareDenyNone、adModeShareDenyWrite 或 adModeShareDenyRead）一起使用，以将共享限制传播给当前 Record 的所有子记录。如果 Record 没有子记录，将没有影响。如果它仅和 adModeShareDenyNone 一起使用，将产生运行时错误。但是，与其他值结合后，它可以和 adModeShareDenyNone 一起使用。例如，可以使用“adModeRead Or adModeShareDenyNone Or adModeRecursive”。
adModeShareDenyNone | 16 | 允许其他人以任何权限打开连接。不拒绝其他人的读访问或写访问。
adModeShareDenyRead | 4 | 禁止其他人以读权限打开连接。
adModeShareDenyWrite | 8 | 禁止其他人以写权限打开连接。
adModeShareExclusive | 12 | 禁止其他人打开连接。
adModeUnknown | 0 | 默认值。指示尚未设置或不能确定权限。
adModeWrite | 2 | 指示只写权限。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.ConnectMode.READ
AdoEnums.ConnectMode.READWRITE
(There is no equivalent of AdoEnums.ConnectMode.RECURSIVE)
AdoEnums.ConnectMode.SHAREDENYNONE
AdoEnums.ConnectMode.SHAREDENYREAD
AdoEnums.ConnectMode.SHAREDENYWRITE
AdoEnums.ConnectMode.SHAREEXCLUSIVE
AdoEnums.ConnectMode.UNKNOWN
AdoEnums.ConnectMode.WRITE

请参阅

应用于：Mode 属性 | Open 方法 (ADO Record) | Open 方法 (ADO Stream) | Stream 对象


ConnectOptionEnum

指定应在连接建立之后（同步）还是之前（异步）返回 Connection 对象的 Open 方法。

常量 | 值 | 说明
adAsyncConnect | 16 | 异步打开连接。ConnectComplete 事件可以用来确定连接何时可用。
adConnectUnspecified | -1 | 默认值。同步打开连接。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.ConnectOption.ASYNCCONNECT
AdoEnums.ConnectOption.CONNECTUNSPECIFIED

请参阅

应用于：Open 方法 (ADO Connection)


ConnectPromptEnum

指定打开到数据源的连接时是否显示一个对话框以提示缺少参数。

常量 | 值 | 说明
adPromptAlways | 1 | 始终提示。
adPromptComplete | 2 | 需要详细信息时提示。
adPromptCompleteRequired | 3 | 在需要详细信息，但不允许可选参数时提示。
adPromptNever | 4 | 从不提示。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.ConnectPrompt.ALWAYS
AdoEnums.ConnectPrompt.COMPLETE
AdoEnums.ConnectPrompt.COMPLETEREQUIRED
AdoEnums.ConnectPrompt.NEVER

请参阅

应用于：Prompt 动态属性 (ADO)


CopyRecordOptionsEnum

指定 CopyRecord 方法的行为。

常量 | 值 | 说明
adCopyAllowEmulation | 4 | 如果由于 Destination 在不同的服务器上或使用非 Source 提供者而造成此方法失败，则指示 Source 提供者尝试使用下载和上载操作来模拟复制。注意，提供者能力不同可能会妨碍性能或丢失数据。
adCopyNonRecursive | 2 | 将当前目录（但不包括其子目录）复制到目标位置。复制操作不递归。
adCopyOverWrite | 1 | 如果 Destination 指向现有文件或目录，则覆盖该文件或目录。
adCopyUnspecified | -1 | 默认值。执行默认的复制操作：如果目标文件或目录已经存在，操作将失败，且该操作将进行递归复制。

ADO/WFC 等价内容

这些常量没有 ADO/WFC 等价内容。

请参阅

应用于：CopyRecord 方法


CursorLocationEnum

指定游标服务的位置。

常量 | 值 | 说明
adUseClient | 3 | 使用本地游标库提供的客户端的游标。本地游标服务通常允许执行驱动程序提供的游标所不允许的许多功能，因此使用此设置可以充分利用即将启用的功能。为进行向后兼容，亦支持同义字 adUseClientBatch。
adUseNone | 1 | 不使用游标服务。（此常量已作废并且只是为了向后兼容才出现。）
adUseServer | 2 | 默认值。使用数据提供者或驱动程序提供的游标。这些游标有时很灵活，可以额外感知其他人对数据源所做的更改。但是，Microsoft Cursor Service for OLE DB 的某些功能（例如断开 Recordset 对象）不能用服务器端游标模拟，这些功能在此设置中将不可用。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.CursorLocation.CLIENT
AdoEnums.CursorLocation.NONE
AdoEnums.CursorLocation.SERVER

请参阅

应用于：CursorLocation 属性


CursorOptionEnum

指定 Supports 方法将测试的功能。

常量 | 值 | 说明
adAddNew | 0x1000400 | 支持 AddNew 方法以添加新记录。
adApproxPosition | 0x4000 | 支持 AbsolutePosition 和 AbsolutePage 属性。
adBookmark | 0x2000 | 支持 Bookmark 属性以访问特定的记录。
adDelete | 0x1000800 | 支持 Delete 方法以删除记录。
adFind | 0x80000 | 支持 Find 方法以定位 Recordset 中的行。
adHoldRecords | 0x100 | 检索其他记录或者更改下一个位置，而不提交所有挂起的更改。
adIndex | 0x100000 | 支持 Index 属性以命名索引。
adMovePrevious | 0x200 | 支持 MoveFirst 和 MovePrevious 方法，以及 Move 或 GetRows 方法以向后移动当前记录位置，而不要求书签。
adNotify | 0x40000 | 指示基本数据提供者支持确定 Recordset 事件是否被支持的通知。
adResync | 0x20000 | 支持 Resync 方法以使用在基本数据库中可见的数据来更新游标。
adSeek | 0x200000 | 支持 Seek 方法以定位 Recordset 中的行。
adUpdate | 0x1008000 | 支持 Update 方法以修改现有的数据。
adUpdateBatch | 0x10000 | 支持批更新（UpdateBatch 和 CancelBatch 方法）以将更改组传送到提供者。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.CursorOption.ADDNEW
AdoEnums.CursorOption.APPROXPOSITION
AdoEnums.CursorOption.BOOKMARK
AdoEnums.CursorOption.DELETE
AdoEnums.CursorOption.FIND
AdoEnums.CursorOption.HOLDRECORDS
AdoEnums.CursorOption.INDEX
AdoEnums.CursorOption.MOVEPREVIOUS
AdoEnums.CursorOption.NOTIFY
AdoEnums.CursorOption.RESYNC
AdoEnums.CursorOption.SEEK
AdoEnums.CursorOption.UPDATE
AdoEnums.CursorOption.UPDATEBATCH

请参阅

应用于：Supports 方法


CursorTypeEnum

指示 Recordset 对象中所用游标的类型。

常量 | 值 | 说明
adOpenDynamic | 2 | 使用动态游标。其他用户所做的添加、更改或删除均可见，而且允许 Recordset 中的所有移动类型（如果提供者不支持书签，则书签除外）。
adOpenForwardOnly | 0 | 默认值。使用仅向前游标。除了在记录中只能向前滚动外，与静态游标相同。当只需要在 Recordset 中进行一个传递时，用它可提高性能。
adOpenKeyset | 1 | 使用键集游标。尽管从您的 Recordset 不能访问其他用户删除的记录，但除无法查看其他用户添加的记录外，它和动态游标相似。其他用户所做的数据更改依然可见。
adOpenStatic | 3 | 使用静态游标。一组记录的静态副本，可用于查找数据或生成报告。其他用户所做的添加、更改或删除不可见。
adOpenUnspecified | -1 | 不指定游标类型。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.CursorType.DYNAMIC
AdoEnums.CursorType.FORWARDONLY
AdoEnums.CursorType.KEYSET
AdoEnums.CursorType.STATIC
AdoEnums.CursorType.UNSPECIFIED

请参阅

应用于：CursorType 属性


DataTypeEnum

指定 Field、Parameter 或 Property 的数据类型。在下表的“说明”列的括号中显示了相应的 OLE DB 类型指示符。有关 OLE DB 数据类型的详细信息，请参阅 OLE DB Programmer's Reference 中的 Chapter 13 和附录 A 。

常量 | 值 | 说明
AdArray （不适用于 ADOX。） | 0x2000 | 一个标志值，通常与另一个数据类型常量组合，指示该数据类型的数组。
adBigInt | 20 | 指示一个八字节的有符号整数 (DBTYPE_I8)。
adBinary | 128 | 指示一个二进制值 (DBTYPE_BYTES)。
adBoolean | 11 | 指示一个布尔值 (DBTYPE_BOOL)。
adBSTR | 8 | 指示以 Null 终止的字符串 (Unicode) (DBTYPE_BSTR)。
adChapter | 136 | 指示一个四字节的子集值，标识子行集合中的行 (DBTYPE_HCHAPTER)。
adChar | 129 | 指示一个字符串值 (DBTYPE_STR)。
adCurrency | 6 | 指示一个货币值 (DBTYPE_CY)。货币是一个定点数字，小数点右侧有四位数字。该值存储为八字节、范围为 10,000 的有符号整数。
adDate | 7 | 指示日期值 (DBTYPE_DATE)。日期保存为双精度数，数字的整数部分是从 1899 年 12 月 30 日算起的天数，小数部分是一天当中的片段时间。
adDBDate | 133 | 指示日期值 (yyyymmdd) (DBTYPE_DBDATE)。
adDBTime | 134 | 指示时间值 (hhmmss) (DBTYPE_DBTIME)。
adDBTimeStamp | 135 | 指示日期/时间戳（yyyymmddhhmmss 加十亿分之一的小数）(DBTYPE_DBTIMESTAMP)。
adDecimal | 14 | 指示具有固定精度和范围的确切数字值 (DBTYPE_DECIMAL)。
adDouble | 5 | 指示一个双精度浮点值 (DBTYPE_R8)。
adEmpty | 0 | 指定没有值 (DBTYPE_EMPTY)。
adError | 10 | 指示一个 32 位的错误代码 (DBTYPE_ERROR)。
adFileTime | 64 | 指示一个 64 位的值，表示从 1601 年 1 月 1 日开始的 100 个十亿分之一秒间隔的数量 (DBTYPE_FILETIME)。
adGUID | 72 | 指示全局唯一标识符 (GUID) (DBTYPE_GUID)。
adIDispatch | 9 | 指示指向 COM 对象上 IDispatch 接口的指针 (DBTYPE_IDISPATCH)。 注意 ADO 目前不支持这种数据类型。使用它可能导致不可预料的结果。
adInteger | 3 | 指示一个四字节的有符号整数 (DBTYPE_I4)。
adIUnknown | 13 | 指示指向 COM 对象上 IUnknown 接口的指针 (DBTYPE_IUNKNOWN)。 注意 ADO 目前不支持这种数据类型。使用它可能导致不可预料的结果。
adLongVarBinary | 205 | 指示一个长二进制值。
adLongVarChar | 201 | 指示一个长字符串值。
adLongVarWChar | 203 | 指示一个以 Null 终止的长 Unicode 字符串值。
adNumeric | 131 | 指示具有固定精度和范围的确切数字值 (DBTYPE_NUMERIC)。
adPropVariant | 138 | 指示一个 Automation PROPVARIANT (DBTYPE_PROP_VARIANT)。
adSingle | 4 | 指示一个单精度浮点值 (DBTYPE_R4)。
adSmallInt | 2 | 指示一个双字节的有符号整数 (DBTYPE_I2)。
adTinyInt | 16 | 指示一个单字节的有符号整数 (DBTYPE_I1)。
adUnsignedBigInt | 21 | 指示一个八字节的无符号整数 (DBTYPE_UI8)。
adUnsignedInt | 19 | 指示一个四字节的无符号整数 (DBTYPE_UI4)。
adUnsignedSmallInt | 18 | 指示一个双字节的无符号整数 (DBTYPE_UI2)。
adUnsignedTinyInt | 17 | 指示一个单字节的无符号整数 (DBTYPE_UI1)。
adUserDefined | 132 | 指示一个用户定义的变量 (DBTYPE_UDT)。
adVarBinary | 204 | 指示一个二进制值（仅限于 Parameter 对象）。
adVarChar | 200 | 指示一个字符串值。
adVariant | 12 | 指示一个 Automation Variant (DBTYPE_VARIANT)。 注意 ADO 目前不支持这种数据类型。使用它可能导致不可预料的结果。
adVarNumeric | 139 | 指示一个数字值（仅限于 Parameter 对象）。
adVarWChar | 202 | 指示一个以 Null 终止的 Unicode 字符串。
adWChar | 130 | 指示一个以 Null 终止的 Unicode 字符串 (DBTYPE_WSTR)。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.DataType.ARRAY
AdoEnums.DataType.BIGINT
AdoEnums.DataType.BINARY
AdoEnums.DataType.BOOLEAN
AdoEnums.DataType.BSTR
AdoEnums.DataType.CHAPTER
AdoEnums.DataType.CHAR
AdoEnums.DataType.CURRENCY
AdoEnums.DataType.DATE
AdoEnums.DataType.DBDATE
AdoEnums.DataType.DBTIME
AdoEnums.DataType.DBTIMESTAMP
AdoEnums.DataType.DECIMAL
AdoEnums.DataType.DOUBLE
AdoEnums.DataType.EMPTY
AdoEnums.DataType.ERROR
AdoEnums.DataType.FILETIME
AdoEnums.DataType.GUID
AdoEnums.DataType.IDISPATCH
AdoEnums.DataType.INTEGER
AdoEnums.DataType.IUNKNOWN
AdoEnums.DataType.LONGVARBINARY
AdoEnums.DataType.LONGVARCHAR
AdoEnums.DataType.LONGVARWCHAR
AdoEnums.DataType.NUMERIC
AdoEnums.DataType.PROPVARIANT
AdoEnums.DataType.SINGLE
AdoEnums.DataType.SMALLINT
AdoEnums.DataType.TINYINT
AdoEnums.DataType.UNSIGNEDBIGINT
AdoEnums.DataType.UNSIGNEDINT
AdoEnums.DataType.UNSIGNEDSMALLINT
AdoEnums.DataType.UNSIGNEDTINYINT
AdoEnums.DataType.USERDEFINED
AdoEnums.DataType.VARBINARY
AdoEnums.DataType.VARCHAR
AdoEnums.DataType.VARIANT
AdoEnums.DataType.VARNUMERIC
AdoEnums.DataType.VARWCHAR
AdoEnums.DataType.WCHAR

请参阅

应用于：Append 方法 | CreateParameter 方法 | CreateRecordset 方法 (RDS) | Type 属性


EditModeEnum

指定记录的编辑状态。

常量 | 值 | 说明
adEditNone | 0 | 指示没有进行编辑操作。
adEditInProgress | 1 | 指示当前记录中的数据已修改但未保存。
adEditAdd | 2 | 指示已调用 AddNew 方法，而复制缓冲区中的当前记录是个尚未保存到数据库的新记录。
adEditDelete | 4 | 指示当前记录已被删除。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.EditMode.NONE
AdoEnums.EditMode.INPROGRESS
AdoEnums.EditMode.ADD
AdoEnums.EditMode.DELETE

请参阅

应用于：EditMode 属性


ErrorValueEnum

指定 ADO 运行时错误的类型。

下面列出了错误编号的三种形式：

  • 正十进制：十进制格式的完整数字的两个低位字节。此数字在默认的 Visual Basic 错误消息对话框中显示。例如，运行时错误“3707”。
  • 负十进制：完整错误编号的十进制转换。
  • 十六进制：完整错误编号的十六进制表示法。Windows 功能代码位于第四位数字。ADO 错误编号的功能代码为 A。例如：0x800A0E7B。
注意 OLE DB 错误可能会传递给您的 ADO 应用程序。通常，这些错误由 Windows 功能代码 4 标识。例如，0x8004……有关这些编号的详细信息，请参阅 OLE DB Programmer's Reference 中的 Chapter 16。
常量 | 值 | 说明
adErrBoundToCommand | 3707 -2146824581 0x800A0E7B | 无法更改以 Command 对象为源的 Recordset 对象的 ActiveConnection 属性。
adErrCannotComplete | 3732 -2146824556 0x800A0E94 | 服务器无法完成此操作。
adErrCantChangeConnection | 3748 -2146824540 0x800A0EA4 | 连接被拒绝。用户请求的新连接所具有的特性与已使用的不同。
adErrCantChangeProvider | 3220 -2146825068 0X800A0C94 | 所提供的提供者与已使用的不同。
adErrCantConvertvalue | 3724 -2146824564 0x800A0E8C | 无法转换数据值，但不是因为符号不匹配或数据溢出。例如，转换截断了数据。
adErrCantCreate | 3725 -2146824563 0x800A0E8D | 因为字段数据类型未知，或提供者没有足够的资源执行该操作，所以无法设置或检索数据值。
adErrCatalogNotSet | 3747 -2146824541 0x800A0EA3 | 操作需要一个有效的 ParentCatalog。
adErrColumnNotOnThisRow | 3726 -2146824562 0x800A0E8E | 记录不包含这个字段。
adErrDataConversion | 3421 -2146824867 0x800A0D5D | 应用程序使用的值的类型对于当前操作不正确。
adErrDataOverflow | 3721 -2146824567 0x800A0E89 | 数据值过大，无法以字段数据类型表示。
adErrDelResOutOfScope | 3738 -2146824550 0x800A0E9A | 要删除的对象的 URL 超出了当前记录的范围。
adErrDenyNotSupported | 3750 -2146824538 0x800A0EA6 | 提供者不支持共享限制。
adErrDenyTypeNotSupported | 3751 -2146824537 0x800A0EA7 | 提供者不支持所请求类型的共享限制。
adErrFeatureNotAvailable | 3251 -2146825037 0x800A0CB3 | 对象或提供者不能执行所请求的操作。
adErrFieldsUpdateFailed | 3749 -2146824539 0x800A0EA5 | 字段更新失败。有关详细信息，请检查单个字段对象的 Status 属性。
adErrIllegalOperation | 3219 -2146825069 0x800A0C93 | 在此上下文中不允许此操作。
adErrIntegrityViolation | 3719 -2146824569 0x800A0E87 | 数据值与字段完整性限制相冲突。
adErrInTransaction | 3246 -2146825042 0x800A0CAE | 在事务中 Connection 对象无法被显式关闭。
adErrInvalidArgument | 3001 -2146825287 0x800A0BB9 | 参数类型不正确，参数不在可接受的范围内，或者与其他数据冲突。
adErrInvalidConnection | 3709 -2146824579 0x800A0E7D | 连接无法用于执行此操作。它或者被关闭，或者在此上下文中无效。
adErrInvalidParamInfo | 3708 -2146824580 0x800A0E7C | Parameter 对象定义不正确。所提供的信息不一致或不完整。
adErrInvalidTransaction | 3714 -2146824574 0x800A0E82 | 相应的事务无效或尚未开始。
adErrInvalidURL | 3729 -2146824559 0x800A0E91 | URL 包含无效字符。请确保键入的 URL 正确。
adErrItemNotFound | 3265 -2146825023 0x800A0CC1 | 在集合中无法找到与请求的名称或序号相对应的项目。
adErrNoCurrentRecord | 3021 -2146825267 0x800A0BCD | BOF 或 EOF 中的一个为 True，或者当前记录已被删除。所请求的操作需要当前记录。
adErrNotExecuting | 3715 -2146824573 0x800A0E83 | 在没有运行时，无法执行操作。
adErrNotReentrant | 3710 -2146824578 0x800A0E7E | 处理事件时无法执行操作。
adErrObjectClosed | 3704 -2146824584 0x800A0E78 | 对象被关闭时，不允许执行操作。
adErrObjectInCollection | 3367 -2146824921 0x800A0D27 | 对象已经在集合中。无法追加。
adErrObjectNotSet | 3420 -2146824868 0x800A0D5C | 对象不再有效。
adErrObjectOpen | 3705 -2146824583 0x800A0E79 | 对象打开时，不允许执行操作。
adErrOpeningFile | 3002 -2146825286 0x800A0BBA | 无法打开文件。
adErrOperationCancelled | 3712 -2146824576 0x800A0E80 | 操作已被用户取消。
adErrOutOfSpace | 3734 -2146824554 0x800A0E96 | 操作无法执行。提供者无法获取足够的存储空间。
adErrPermissionDenied | 3720 -2146824568 0x800A0E88 | 没有足够的权限写入字段。
adErrProviderFailed | 3000 -2146825288 0x800A0BB8 | 提供者无法执行所请求的操作。
adErrProviderNotFound | 3706 -2146824582 0x800A0E7A | 无法找到提供者。可能没有正确安装提供者。
adErrReadFile | 3003 -2146825285 0x800A0BBB | 无法读取文件。
adErrResourceExists | 3731 -2146824557 0x800A0E93 | 复制操作无法执行。目标 URL 命名的对象已经存在。指定 adCopyOverwrite 以替换该对象。
adErrResourceLocked | 3730 -2146824558 0x800A0E92 | 由指定的 URL 所表示的对象被一个或多个其他进程锁定。等候至进程结束，然后再尝试此操作。
adErrResourceOutOfScope | 3735 -2146824553 0x800A0E97 | 源或目标 URL 超出了当前记录的范围。
adErrSchemaViolation | 3722 -2146824566 0x800A0E8A | 数据值和字段的数据类型或限制相冲突。
adErrSignMismatch | 3723 -2146824565 0x800A0E8B | 由于数据值带符号，而提供者使用的字段数据类型不带符号，因此转换失败。
adErrStillConnecting | 3713 -2146824575 0x800A0E81 | 异步连接时无法执行操作。
adErrStillExecuting | 3711 -2146824577 0x800A0E7F | 异步运行时无法执行操作。
adErrTreePermissionDenied | 3728 -2146824560 0x800A0E90 | 没有足够的权限访问树或子树。
adErrUnavailable | 3736 -2146824552 0x800A0E98 | 操作无法完成，并且状态不可用。字段可能不可用或未尝试该操作。
adErrUnsafeOperation | 3716 -2146824572 0x800A0E84 | 本计算机上的安全设置禁止访问其他域上的数据源。
adErrURLDoesNotExist | 3727 -2146824561 0x800A0E8F | 源 URL 或者目标 URL 的父不存在。
adErrURLNamedRowDoesNotExist | 3737 -2146824551 0x800A0E99 | 由此 URL 命名的记录不存在。
adErrVolumeNotFound | 3733 -2146824555 0x800A0E95 | 提供者无法定位由 URL 指示的存储设备。请确保键入的 URL 正确。
adErrWriteFile | 3004 -2146825284 0x800A0BBC | 写入文件失败。
adWrnSecurityDialog | 3717 -2146824571 0x800A0E85 | 仅在内部使用。请勿使用。
adWrnSecurityDialogHeader | 3718 -2146824570 0x800A0E86 | 仅在内部使用。请勿使用。

ADO/WFC 等价内容

包：com.ms.wfc.data

仅定义了下列 ADO/WFC 等价内容的子集。

常量
AdoEnums.ErrorValue.BOUNDTOCOMMAND
AdoEnums.ErrorValue.DATACONVERSION
AdoEnums.ErrorValue.FEATURENOTAVAILABLE
AdoEnums.ErrorValue.ILLEGALOPERATION
AdoEnums.ErrorValue.INTRANSACTION
AdoEnums.ErrorValue.INVALIDARGUMENT
AdoEnums.ErrorValue.INVALIDCONNECTION
AdoEnums.ErrorValue.INVALIDPARAMINFO
AdoEnums.ErrorValue.ITEMNOTFOUND
AdoEnums.ErrorValue.NOCURRENTRECORD
AdoEnums.ErrorValue.NOTEXECUTING
AdoEnums.ErrorValue.NOTREENTRANT
AdoEnums.ErrorValue.OBJECTCLOSED
AdoEnums.ErrorValue.OBJECTINCOLLECTION
AdoEnums.ErrorValue.OBJECTNOTSET
AdoEnums.ErrorValue.OBJECTOPEN
AdoEnums.ErrorValue.OPERATIONCANCELLED
AdoEnums.ErrorValue.PROVIDERNOTFOUND
AdoEnums.ErrorValue.STILLCONNECTING
AdoEnums.ErrorValue.STILLEXECUTING
AdoEnums.ErrorValue.UNSAFEOPERATION

请参阅

ADO 错误代码

应用于：Number 属性


EventReasonEnum

指定导致事件发生的原因。

常量 | 值 | 说明
adRsnAddNew | 1 | 添加新记录的操作。
adRsnClose | 9 | 关闭 Recordset 的操作。
adRsnDelete | 2 | 删除记录的操作。
adRsnFirstChange | 11 | 对记录作第一次更改的操作。
adRsnMove | 10 | 在 Recordset 中移动记录指针的操作。
adRsnMoveFirst | 12 | 将记录指针移动到 Recordset 中第一个记录的操作。
adRsnMoveLast | 15 | 将记录指针移动到 Recordset 中最后一个记录的操作。
adRsnMoveNext | 13 | 将记录指针移动到 Recordset 中下一个记录的操作。
adRsnMovePrevious | 14 | 将记录指针移动到 Recordset 中上一个记录的操作。
adRsnRequery | 7 | 重新查询 Recordset 的操作。
adRsnResynch | 8 | 将 Recordset 与数据库重新同步的操作。
adRsnUndoAddNew | 5 | 撤消添加新记录的操作。
adRsnUndoDelete | 6 | 撤消删除记录的操作。
adRsnUndoUpdate | 4 | 撤消更新记录的操作。
adRsnUpdate | 3 | 更新现有记录的操作。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.EventReason.ADDNEW
AdoEnums.EventReason.CLOSE
AdoEnums.EventReason.DELETE
AdoEnums.EventReason.FIRSTCHANGE
AdoEnums.EventReason.MOVE
AdoEnums.EventReason.MOVEFIRST
AdoEnums.EventReason.MOVELAST
AdoEnums.EventReason.MOVENEXT
AdoEnums.EventReason.MOVEPREVIOUS
AdoEnums.EventReason.REQUERY
AdoEnums.EventReason.RESYNCH
AdoEnums.EventReason.UNDOADDNEW
AdoEnums.EventReason.UNDODELETE
AdoEnums.EventReason.UNDOUPDATE
AdoEnums.EventReason.UPDATE

请参阅

应用于：WillChangeRecord 和 RecordChangeComplete 事件 | WillChangeRecordset 和 RecordsetChangeComplete 事件 | WillMove 和 MoveComplete 事件

© 1998-2003 Microsoft Corporation. 保留所有权利。


EventStatusEnum

指定事件执行的当前状态。

常量 | 值 | 说明
adStatusCancel | 4 | 请求取消导致事件发生的操作。
adStatusCantDeny | 3 | 指示操作不能请求取消挂起操作。
adStatusErrorsOccurred | 2 | 指示由于一个或多个错误，而使引发该事件的操作失败。
adStatusOK | 1 | 指示引发该事件的操作成功。
adStatusUnwantedEvent | 5 | 在事件方法执行结束之前禁止后续的通知。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.EventStatus.CANCEL
AdoEnums.EventStatus.CANTDENY
AdoEnums.EventStatus.ERRORSOCCURRED
AdoEnums.EventStatus.OK
AdoEnums.EventStatus.UNWANTEDEVENT

请参阅

应用于：BeginTransComplete、CommitTransComplete 和 RollbackTransComplete 事件 | ConnectComplete 和 Disconnect 事件 | EndOfRecordset 事件 | ExecuteComplete 事件 | FetchComplete 事件 | InfoMessage 事件 | WillChangeField 和 FieldChangeComplete 事件 | WillChangeRecord 和 RecordChangeComplete 事件 | WillChangeRecordset 和 RecordsetChangeComplete 事件 | WillConnect 事件 | WillExecute 事件 | WillMove 和 MoveComplete 事件


ExecuteOptionEnum

指定提供者执行命令的方式。

常量 | 值 | 说明
adAsyncExecute | 0x10 | 指示命令将异步执行。 该值不能与 CommandTypeEnum 的值 adCmdTableDirect 组合。
adAsyncFetch | 0x20 | 指示在 CacheSize 属性中指定的初始数量以后的剩余行将被异步检索。
adAsyncFetchNonBlocking | 0x40 | 指示检索时主线程从不会阻塞。如果未检索到所请求的行，当前行将自行移动到文件结尾。 如果从包含持久存储 Recordset 的 Stream 中打开 Recordset，那么 adAsyncFetchNonBlocking 将不起作用；该操作将同步进行并发生阻塞。 当 adCmdTableDirect 选项被用于打开 Recordset 时，adAsynchFetchNonBlocking 不起作用。
adExecuteNoRecords | 0x80 | 指示命令文本是不返回行的命令或存储过程（例如，仅插入数据的命令）。如果检索到任何行，它们将被放弃且不返回。 adExecuteNoRecords 只能作为可选参数传递给 Command 或 Connection 的 Execute 方法。
adExecuteStream | 0x400 | 指示命令执行的结果应当作为流返回。 adExecuteStream 只能作为可选参数传递给 Command 的 Execute 方法。
adExecuteRecord |  | 指示 CommandText 是一个命令或存储过程，它返回应当被作为 Record 对象返回的单一行。
adOptionUnspecified | -1 | 指示未指定命令。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.ExecuteOption.ASYNCEXECUTE
AdoEnums.ExecuteOption.ASYNCFETCH
AdoEnums.ExecuteOption.ASYNCFETCHNONBLOCKING
AdoEnums.ExecuteOption.NORECORDS
AdoEnums.ExecuteOption.UNSPECIFIED

请参阅

应用于：Execute 方法 (ADO Command) | Execute 方法 (ADO Connection) | Open 方法 (ADO Recordset) | Requery 方法


FieldEnum

指定在 Record 对象的 Fields 集合中引用的特殊字段。

说明

这些常量提供了访问与 Record 相关联的特殊字段的“快捷方式”。从 Fields 集合中检索 Field 对象，然后用 Field 对象的 Value 属性获取其内容。

常量 | 值 | 说明
adDefaultStream | -1 | 引用包含与 Record 相关联的默认 Stream 对象的字段。
adRecordURL | -2 | 引用包含当前 Record 绝对 URL 字符串的字段。


FieldAttributeEnum

指定 Field 对象的一个或多个属性。

常量 | 值 | 说明
adFldCacheDeferred | 0x1000 | 指示提供者缓存字段值，并且指示对缓存的后续读取完成。
adFldFixed | 0x10 | 指示该字段包含定长数据。
adFldIsChapter | 0x2000 | 指示该字段包含一个子集值，指定与此父字段有关的特定子记录集。通常子集字段与数据构形或过滤器一起使用。
adFldIsCollection | 0x40000 | 指示该字段指定由记录表示的资源是其他资源的集合（如文件夹）而不仅是简单资源（如文本文件）。
adFldIsDefaultStream | 0x20000 | 指示该字段包含由记录表示的资源的默认流。例如，默认流可以是网站根文件夹的 HTML 内容，在指定根 URL 时自动提供。
adFldIsNullable | 0x20 | 指示该字段接受 Null 值。
adFldIsRowURL | 0x10000 | 指示该字段包含 URL，它命名了记录表示的数据存储中的资源。
adFldLong | 0x80 | 指示该字段是长二进制字段。还指示能够使用 AppendChunk 和 GetChunk 方法。
adFldMayBeNull | 0x40 | 指示可从该字段读取 Null 值。
adFldMayDefer | 0x2 | 指示该字段被延期，即该字段值不是和整个记录一起从数据源检索，而是在显式访问它们时检索。
adFldNegativeScale | 0x4000 | 指示该字段表示来自支持负范围值的列的数字值。该范围由 NumericScale 属性指定。
adFldRowID | 0x100 | 指示该字段包含持久行标识符，该标识符无法被写入，并且除了标识行以外没有任何意义，例如记录编号、唯一标识符等。
adFldRowVersion | 0x200 | 指示该字段包含用于跟踪更新的某种时间或日期戳。
adFldUnknownUpdatable | 0x8 | 指示提供者无法确定用户是否可以写入字段。
adFldUnspecified | -1 0xFFFFFFFF | 指示提供者没有指定字段属性。
adFldUpdatable | 0x4 | 指示用户可以写入字段。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.FieldAttribute.CACHEDEFERRED
AdoEnums.FieldAttribute.FIXED
AdoEnums.FieldAttribute.ISNULLABLE
AdoEnums.FieldAttribute.LONG
AdoEnums.FieldAttribute.MAYBENULL
AdoEnums.FieldAttribute.MAYDEFER
AdoEnums.FieldAttribute.NEGATIVESCALE
AdoEnums.FieldAttribute.ROWID
AdoEnums.FieldAttribute.ROWVERSION
AdoEnums.FieldAttribute.UNKNOWNUPDATABLE
AdoEnums.FieldAttribute.UNSPECIFIED
AdoEnums.FieldAttribute.UPDATABLE

请参阅

应用于：Append 方法 | Attributes 属性


FieldStatusEnum

指定 Field 对象的状态。

adFieldPending* 值指示造成需要设置状态的操作，并且可与其他状态值相结合。

常量 | 值 | 说明
adFieldAlreadyExists | 26 | 指示指定的字段已存在。
adFieldBadStatus | 12 | 指示从 ADO 向 OLE DB 提供者发送了无效状态值。原因可能是 OLE DB 1.0 或 1.1 提供者，或者是 Value 与 Status 的组合不恰当。
adFieldCannotComplete | 20 | 指示由 Source 指定 URL 的服务器不能完成操作。
adFieldCannotDeleteSource | 23 | 指示在移动操作中，树或子树被移动到新的位置，但是源不能被删除。
adFieldCantConvertValue | 2 | 指示无法在不损失数据的情况下检索或存储该字段。
adFieldCantCreate | 7 | 指示因为提供者超过了限制（如所允许的字段数量），所以不能添加该字段。
adFieldDataOverflow | 6 | 指示从提供者返回的数据超出了字段的数据类型。
adFieldDefault | 13 | 指示在设置数据时使用字段的默认值。
adFieldDoesNotExist | 16 | 指示指定的字段不存在。
adFieldIgnore | 15 | 指示在设置源中的数据值时，此字段被跳过。提供者没有设置值。
adFieldIntegrityViolation | 10 | 指示由于该字段是计算或派生的项目，因此无法对其进行修改。
adFieldInvalidURL | 17 | 指示数据源 URL 包含无效的字符。
adFieldIsNull | 3 | 指示提供者返回一个 VT_NULL 类型的 VARIANT 值，而且该字段不为空。
adFieldOK | 0 | 默认。指示已成功添加或删除该字段。
adFieldOutOfSpace | 22 | 指示提供者无法获取足够的存储空间来完成移动或复制操作。
adFieldPendingChange | 0x40000 | 指示该字段被删除后又被重新添加（可能数据类型不同），或者指示以前具有 adFieldOK 状态的字段的值已经被更改。字段的最终格式将在调用 Update 方法之后修改 Fields 集合。
adFieldPendingDelete | 0x20000 | 指示 Delete 操作导致需要设置状态。该字段被标记为在调用 Update 方法后从 Fields 集合删除。
adFieldPendingInsert | 0x10000 | 指示 Append 操作导致需要设置状态。Field 被标记为在调用 Update 方法后添加到 Fields 集合。
adFieldPendingUnknown | 0x80000 | 指示提供者无法确定哪个操作导致需要设置状态。
adFieldPendingUnknownDelete | 0x100000 | 指示提供者无法确定哪个操作导致需要设置字段状态，以及在调用 Update 方法后，该字段将被从 Fields 集合中删除。
adFieldPermissionDenied | 9 | 指示由于该字段被定义为只读，因此无法对其进行修改。
adFieldReadOnly | 24 | 指示数据源中的字段被定义为只读。
adFieldResourceExists | 19 | 指示因为对象已在目标 URL 中存在，而且不能被覆盖，所以提供者不能执行操作。
adFieldResourceLocked | 18 | 指示因为数据源被一个或多个其他应用程序或进程锁定，所以提供者不能执行操作。
adFieldResourceOutOfScope | 25 | 指示源或目标 URL 超出了当前记录的范围。
adFieldSchemaViolation | 11 | 指示值违反了字段的数据源模式限制。
adFieldSignMismatch | 5 | 指示由提供者返回的数据值带符号，而 ADO 字段值的数据类型不带符号。
adFieldTruncated | 4 | 指示从数据源读取时，变长数据被截断。
adFieldUnavailable | 8 | 指示从数据源读取时，提供者不能确定值。例如，行刚被创建，列的默认值无法使用，并且还没有指定新值。
adFieldVolumeNotFound | 21 | 指示提供者不能定位 URL 指示的存储量。

ADO/WFC 等价内容

这些常量没有 ADO/WFC 等价内容。

请参阅

应用于：Status 属性 (ADO Field)


FilterGroupEnum

指定要从 Recordset 中过滤的记录组。

常量 | 值 | 说明
adFilterAffectedRecords | 2 | 过滤器，用于仅查看受最后一次 Delete、Resync、UpdateBatch 或 CancelBatch 调用影响的记录。
adFilterConflictingRecords | 5 | 过滤器，用于查看使最后一次批更新失败的记录。
adFilterFetchedRecords | 3 | 过滤器，用于查看当前缓存（即最后一次检索数据库中记录的结果）中的记录。
adFilterNone | 0 | 删除当前过滤器，并恢复查看所有记录。
adFilterPendingRecords | 1 | 过滤器，用于仅查看已更改但还未发送到服务器的记录。仅对批更新模式适用。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.FilterGroup.AFFECTEDRECORDS
AdoEnums.FilterGroup.CONFLICTINGRECORDS
AdoEnums.FilterGroup.FETCHEDRECORDS
AdoEnums.FilterGroup.NONE
AdoEnums.FilterGroup.PENDINGRECORDS

请参阅

应用于：Filter 属性


GetRowsOptionEnum

指定要从 Recordset 中检索的记录的数量。

常量 | 值 | 说明
adGetRowsRest | -1 | 从当前位置或者从由 GetRows 方法的 Start 参数指定的书签开始，检索 Recordset 中其余的记录。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.GetRowsOption.REST

请参阅

应用于：GetRows 方法


IsolationLevelEnum

指示 Connection 对象的事务隔离级别。

常量 | 值 | 说明
adXactUnspecified | -1 | 指示提供者使用的隔离级别与指定的不同，并且该级别无法确定。
adXactChaos | 16 | 指示不能覆盖来自更高级别隔离事务的挂起更改。
adXactBrowse | 256 | 指示可以从一个事务中查看其他事务中未提交的更改。
adXactReadUncommitted | 256 | 与 adXactBrowse 相同。
adXactCursorStability | 4096 | 指示只能从一个事务中查看其他事务中提交的更改。
adXactReadCommitted | 4096 | 与 adXactCursorStability 相同。
adXactRepeatableRead | 65536 | 指示不能从一个事务中查看其他事务中所做的修改，但是重新查询可以检索新的 Recordset 对象。
adXactIsolated | 1048576 | 指示该事务与其他事务隔离执行。
adXactSerializable | 1048576 | 与 adXactIsolated 相同。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.IsolationLevel.UNSPECIFIED
AdoEnums.IsolationLevel.CHAOS
AdoEnums.IsolationLevel.BROWSE
AdoEnums.IsolationLevel.READUNCOMMITTED
AdoEnums.IsolationLevel.CURSORSTABILITY
AdoEnums.IsolationLevel.READCOMMITTED
AdoEnums.IsolationLevel.REPEATABLEREAD
AdoEnums.IsolationLevel.ISOLATED
AdoEnums.IsolationLevel.SERIALIZABLE

请参阅

应用于：IsolationLevel Property


LineSeparatorsEnum

指定在文本 Stream 对象中用作分行符的字符。

常量 | 值 | 说明
adCR | 13 | 指示回车。
adCRLF | -1 | 默认。指示回车换行。
adLF | 10 | 指示换行。

ADO/WFC 等价内容

这些常量没有 ADO/WFC 等价内容。

请参阅

应用于：LineSeparator 属性


LockTypeEnum

指定在编辑过程中记录上的锁定类型。

常量 | 值 | 说明
adLockBatchOptimistic | 4 | 指示开放式批更新。需要批更新模式。
adLockOptimistic | 3 | 指示逐个记录开放式锁定。提供者使用开放式锁定，仅在调用 Update 方法时锁定记录。
adLockPessimistic | 2 | 指示逐个记录保守式锁定。提供者要确保记录编辑成功，通常在编辑之后立即在数据源锁定记录。
adLockReadOnly | 1 | 指示只读记录。无法改变数据。
adLockUnspecified | -1 | 未指定锁定类型。创建副本时，副本与源对象使用相同的锁定类型。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.LockType.BATCHOPTIMISTIC
AdoEnums.LockType.OPTIMISTIC
AdoEnums.LockType.PESSIMISTIC
AdoEnums.LockType.READONLY
AdoEnums.LockType.UNSPECIFIED

请参阅

应用于：Clone 方法 | LockType 属性 | Open 方法 (ADO Recordset) | WillExecute 事件


MarshalOptionsEnum

指定要将哪些记录返回服务器。

常量 | 值 | 说明
adMarshalAll | 0 | 默认。将所有行返回服务器。
adMarshalModifiedOnly | 1 | 仅将修改的行返回服务器。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.MarshalOptions.ALL
AdoEnums.MarshalOptions.MODIFIEDONLY

请参阅

应用于：MarshalOptions 属性


MoveRecordOptionsEnum

指定 Record 对象的 MoveRecord 方法的行为。

常量 | 值 | 说明
adMoveUnspecified | -1 | 默认。执行默认的移动操作：如果目标文件或目录已经存在，该操作将失败，且操作将更新超文本链接。
adMoveOverWrite | 1 | 覆盖目标文件或目录，即使它已经存在。
adMoveDontUpdateLinks | 2 | 通过不更新源 Record 的超文本链接，来修改 MoveRecord 方法的默认行为。默认行为取决于提供者的能力。如果提供者有能力，那么移动操作将更新链接。如果提供者无法修复链接或者此值未被指定，那么即使链接未被修复，该移动仍将成功。
adMoveAllowEmulation | 4 | 请求提供者尝试模拟移动（使用下载、上载和删除操作）。如果因为目标 URL 位于不同的服务器上或由不同于源的提供者服务而造成 Record 移动失败，那么可能会由于在提供者之间移动资源时各提供者的能力不同，而导致反应时间延长或数据丢失。

ADO/WFC 等价内容

这些常量没有 ADO/WFC 等价内容。

请参阅

应用于：MoveRecord 方法


ObjectStateEnum

指定对象的状态是打开或关闭、正在连接到数据源、正在执行命令，还是正在检索数据。

常量 | 值 | 说明
adStateClosed | 0 | 指示对象已关闭。
adStateOpen | 1 | 指示对象已打开。
adStateConnecting | 2 | 指示对象正在连接。
adStateExecuting | 4 | 指示对象正在执行命令。
adStateFetching | 8 | 指示正在检索对象的行。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.ObjectState.CLOSED
AdoEnums.ObjectState.OPEN
AdoEnums.ObjectState.CONNECTING
AdoEnums.ObjectState.EXECUTING
AdoEnums.ObjectState.FETCHING

请参阅

应用于：State 属性 | State 属性


ParameterAttributesEnum

指定 Parameter 对象的属性。

常量 | 值 | 说明
adParamSigned | 16 | 指示该参数接受带符号的值。
adParamNullable | 64 | 指示该参数接受 Null 值。
adParamLong | 128 | 指示该参数接受长二进制数据。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.ParameterAttributes.SIGNED
AdoEnums.ParameterAttributes.NULLABLE
AdoEnums.ParameterAttributes.LONG

请参阅

应用于：Attributes 属性


ParameterDirectionEnum

指定 Parameter 所表示的是输入参数、输出参数、既是输出又是输入参数，还是存储过程返回的值。

常量 | 值 | 说明
adParamInput | 1 | 默认值。指示该参数是输入参数。
adParamInputOutput | 3 | 指示该参数既是输入参数，又是输出参数。
adParamOutput | 2 | 指示该参数是输出参数。
adParamReturnValue | 4 | 指示该参数是返回值。
adParamUnknown | 0 | 指示该参数的方向未知。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.ParameterDirection.INPUT
AdoEnums.ParameterDirection.INPUTOUTPUT
AdoEnums.ParameterDirection.OUTPUT
AdoEnums.ParameterDirection.RETURNVALUE
AdoEnums.ParameterDirection.UNKNOWN

请参阅

应用于：CreateParameter 方法 | Direction 属性


PersistFormatEnum

指定保存 Recordset 的格式。

常量 | 值 | 说明
adPersistADTG | 0 | 指示 Microsoft Advanced Data TableGram (ADTG) 格式。
adPersistADO | 1 | 指示将使用 ADO 自身的可扩展标记语言 (XML) 格式。该值与 adPersistXML 相同，保留它是为了向后兼容。
adPersistXML | 1 | 指示可扩展标记语言 (XML) 格式。
adPersistProviderSpecific | 2 | 指示提供者将利用自身的格式持久保留 Recordset。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.PersistFormat.ADTG
AdoEnums.PersistFormat.XML

请参阅

应用于：Save 方法


PositionEnum

指定记录指针在 Recordset 中的当前位置。

常量 | 值 | 说明
adPosBOF | -2 | 指示当前记录指针位于 BOF（即 BOF 属性为 True）。
adPosEOF | -3 | 指示当前记录指针位于 EOF（即 EOF 属性为 True）。
adPosUnknown | -1 | 指示 Recordset 为空，当前位置未知，或者提供者不支持 AbsolutePage 或 AbsolutePosition 属性。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.Position.BOF
AdoEnums.Position.EOF
AdoEnums.Position.UNKNOWN

请参阅

应用于：AbsolutePage 属性 | AbsolutePosition 属性


PropertyAttributesEnum

指定 Property 对象的属性。

常量 | 值 | 说明
adPropNotSupported | 0 | 指示提供者不支持该属性。
adPropRequired | 1 | 指示在初始化数据源之前用户必须指定该属性的值。
adPropOptional | 2 | 指示在初始化数据源之前用户不必指定该属性的值。
adPropRead | 512 | 指示用户可以读取该属性。
adPropWrite | 1024 | 指示用户可以设置该属性。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.PropertyAttributes.NOTSUPPORTED
AdoEnums.PropertyAttributes.REQUIRED
AdoEnums.PropertyAttributes.OPTIONAL
AdoEnums.PropertyAttributes.READ
AdoEnums.PropertyAttributes.WRITE

请参阅

应用于：Attributes 属性


RecordCreateOptionsEnum

指定是为 Record 对象的 Open 方法打开现有的 Record，还是创建新的 Record。这些值可以用 AND 操作符组合。

常量 | 值 | 说明
adCreateCollection | 0x2000 | 在 Source 参数指定的节点处创建新的 Record，而不是打开现有的 Record。如果 Source 指向现有的节点，则除非将 adCreateCollection 与 adOpenIfExists（或 adCreateOverwrite）组合，否则将产生运行时错误。
adCreateNonCollection | 0 | 创建 adSimpleRecord 类型的新 Record。
adCreateOverwrite | 0x4000000 | 修改创建标志 adCreateCollection、adCreateNonCollection 和 adCreateStructDoc。当该值、OR 和某个创建标志值三者一起使用时，如果源 URL 指向现有的节点或 Record，则现有的 Record 将被覆盖，并在其位置处创建一个新的 Record。此值不能与 adOpenIfExists 一起使用。
adCreateStructDoc | 0x80000000 | 创建 adStructDoc 类型的新 Record，而不是打开现有的 Record。
adFailIfNotExists | -1 | 默认值。如果 Source 指向不存在的节点，将产生运行时错误。
adOpenIfExists | 0x2000000 | 修改创建标志 adCreateCollection、adCreateNonCollection 和 adCreateStructDoc。当该值、OR 和某个创建标志值三者一起使用时，如果源 URL 指向现有的节点或 Record 对象，则提供者必须打开现有的 Record，而不是创建一个新的 Record。此值不能与 adCreateOverwrite 一起使用。

ADO/WFC 等价内容

这些常量没有 ADO/WFC 等价内容。

请参阅

应用于：Open 方法 (ADO Record)


RecordOpenOptionsEnum

指定用于打开 Record 的选项。这些值可以用 OR 组合。

常量 | 值 | 说明
adDelayFetchFields | 0x8000 | 指示提供者不需要在开始时检索与 Record 相关联的字段，而可以在第一次试图访问该字段时进行检索。无该标志则指示使用默认行为。默认行为是检索所有 Record 对象字段。
adDelayFetchStream | 0x4000 | 指示提供者不需要在开始时检索与 Record 相关联的默认流。无该标志则指示使用默认行为。默认行为是检索与 Record 对象相关联的默认流。
adOpenAsync | 0x1000 | 指示以异步模式打开 Record 对象。
adOpenExecuteCommand | 0x10000 | 指示 Source 字符串包含应当被执行的命令文本。该值等价于 Recordset.Open 上的 adCmdText 选项。
adOpenRecordUnspecified | -1 | 默认值。指示未指定选项。
adOpenOutput | 0x800000 | 指示如果源指向包含可执行脚本（例如 .ASP 页）的节点，则所打开的 Record 将包含已执行脚本的结果。此值只对非集合记录有效。

ADO/WFC 等价内容

这些常量没有 ADO/WFC 等价内容。

请参阅

应用于：Open 方法 (ADO Record)


RecordStatusEnum

指定批更新和其他大量操作的相关记录的状态。

常量 | 值 | 说明
adRecCanceled | 0x100 | 指示由于操作被取消，因此未保存该记录。
adRecCantRelease | 0x400 | 指示由于现有记录被锁定，因此未保存新记录。
adRecConcurrencyViolation | 0x800 | 指示由于正在使用开放式并发，因此未保存该记录。
adRecDBDeleted | 0x40000 | 指示已经从数据源中删除了该记录。
adRecDeleted | 0x4 | 指示该记录已被删除。
adRecIntegrityViolation | 0x1000 | 指示由于用户违反完整性约束，因此未保存该记录。
adRecInvalid | 0x10 | 指示由于记录的书签无效，因此未保存该记录。
adRecMaxChangesExceeded | 0x2000 | 指示由于存在过多挂起的更改，因此未保存该记录。
adRecModified | 0x2 | 指示该记录已被修改。
adRecMultipleChanges | 0x40 | 指示由于记录会影响多个记录，因此未保存该记录。
adRecNew | 0x1 | 指示该记录是新的。
adRecObjectOpen | 0x4000 | 指示由于记录与打开的存储对象冲突，因此未保存该记录。
adRecOK | 0 | 指示已成功更新该记录。
adRecOutOfMemory | 0x8000 | 指示由于计算机内存不足，因此未保存该记录。
adRecPendingChanges | 0x80 | 指示由于记录引用挂起的插入，因此未保存该记录。
adRecPermissionDenied | 0x10000 | 指示由于用户没有足够的权限，因此未保存该记录。
adRecSchemaViolation | 0x20000 | 指示由于记录违反基本数据库的结构，因此未保存该记录。
adRecUnmodified | 0x8 | 指示该记录未被修改。

ADO/WFC 等价内容

AdoEnums.RecordStatus。

包：com.ms.wfc.data

常量
AdoEnums.RecordStatus.CANCELED
AdoEnums.RecordStatus.CANTRELEASE
AdoEnums.RecordStatus.CONCURRENCYVIOLATION
AdoEnums.RecordStatus.DBDELETED
AdoEnums.RecordStatus.DELETED
AdoEnums.RecordStatus.INTEGRITYVIOLATION
AdoEnums.RecordStatus.INVALID
AdoEnums.RecordStatus.MAXCHANGESEXCEEDED
AdoEnums.RecordStatus.MODIFIED
AdoEnums.RecordStatus.MULTIPLECHANGES
AdoEnums.RecordStatus.NEW
AdoEnums.RecordStatus.OBJECTOPEN
AdoEnums.RecordStatus.OK
AdoEnums.RecordStatus.OUTOFMEMORY
AdoEnums.RecordStatus.PENDINGCHANGES
AdoEnums.RecordStatus.PERMISSIONDENIED
AdoEnums.RecordStatus.SCHEMAVIOLATION
AdoEnums.RecordStatus.UNMODIFIED

请参阅

应用于：Status 属性 (ADO Recordset)


RecordTypeEnum

指定 Record 对象的类型。

常量 | 值 | 说明
adSimpleRecord | 0 | 指示 simple 记录（不包含子节点）。
adCollectionRecord | 1 | 指示 collection 记录（包含子节点）。
adRecordUnknown | -1 | 指示此 Record 的类型未知。
adStructDoc | 2 | 指示表示 COM 结构化文档的一种特殊的 collection 记录。

ADO/WFC 等价内容

这些常量没有 ADO/WFC 等价内容。

请参阅

应用于：RecordType 属性


ResyncEnum

指定是否通过调用 Resync 来覆盖基本值。

常量 | 值 | 说明
adResyncAllValues | 2 | 默认值。覆盖数据，并且取消挂起的更新。
adResyncUnderlyingValues | 1 | 不覆盖数据，也不取消挂起的更新。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.Resync.ALLVALUES
AdoEnums.Resync.UNDERLYINGVALUES

请参阅

应用于：Resync 方法


SaveOptionsEnum

指定从 Stream 对象保存时是创建文件还是覆盖文件。这些值可以用 AND 操作符组合。

常量 | 值 | 说明
adSaveCreateNotExist | 1 | 默认值。如果 FileName 参数指定的文件不存在，则创建新文件。
adSaveCreateOverWrite | 2 | 如果 FileName 参数指定的文件存在，则用当前打开的 Stream 对象中的数据覆盖该文件。

ADO/WFC 等价内容

这些常量没有 ADO/WFC 等价内容。

请参阅

应用于：SaveToFile 方法


SchemaEnum

指定 OpenSchema 方法检索的模式 Recordset 的类型。

说明

有关每个 ADO 常量的功能和返回列的详细信息，请参阅 OLE DB Programmers Reference 中 Appendix B 的主题。下表“说明”栏的括号中列出了每个主题的名称。

有关每个 ADO MD 常量的功能和返回列的详细信息，请参阅“OLE DB for OLAP”文档 Chapter 23 中的主题。下表“说明”栏的括号中列出了每个主题的名称，并以星号 (*) 标记。

可以参照 ADO DataTypeEnum 主题的“说明”列，将 OLE DB 文档中列的数据类型转换为 ADO 数据类型。例如，OLE DB 数据类型 DBTYPE_WSTR 就等价于 ADO 数据类型 adWChar。

ADO 对常量 adSchemaDBInfoKeywords 和 adSchemaDBInfoLiterals 生成模式形式的结果。ADO 创建 Recordset，然后分别将 IDBInfo::GetKeywords 和 IDBInfo::GetLiteralInfo 方法返回的值填入每一行。有关这些方法的详细信息，请参阅 OLE DB Programmer's Reference 中的 IDBInfo 一节。

常量 | 值 | 说明 | 约束列
adSchemaAsserts | 0 | 返回目录中定义的属于给定用户的断言。 (ASSERTIONS Rowset) | CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME
adSchemaCatalogs | 1 | 返回与可通过 DBMS 访问的目录相关的物理属性。 (CATALOGS Rowset) | CATALOG_NAME
adSchemaCharacterSets | 2 | 返回目录中定义的给定用户可访问的字符集。 (CHARACTER_SETS Rowset) | CHARACTER_SET_CATALOG CHARACTER_SET_SCHEMA CHARACTER_SET_NAME
adSchemaCheckConstraints | 5 | 返回目录中定义的属于给定用户的校验约束。 (CHECK_CONSTRAINTS Rowset) | CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME
adSchemaCollations | 3 | 返回目录中定义的给定用户可访问的字符序列。 (COLLATIONS Rowset) | COLLATION_CATALOG COLLATION_SCHEMA COLLATION_NAME
adSchemaColumnPrivileges | 13 | 返回目录中定义的表的列具有的特权，这些特权可以授予给定用户或可由他们授权。 (COLUMN_PRIVILEGES Rowset) | TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME GRANTOR GRANTEE
adSchemaColumns | 4 | 返回目录中定义的给定用户可访问的表（包括视图）的列。 (COLUMNS Rowset) | TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME
adSchemaColumnsDomainUsage | 11 | 返回目录中定义的列，这些列依赖于该目录中定义的域，并属于给定用户。 (COLUMN_DOMAIN_USAGE Rowset) | DOMAIN_CATALOG DOMAIN_SCHEMA DOMAIN_NAME COLUMN_NAME
adSchemaConstraintColumnUsage | 6 | 返回目录中定义的列，这些列由引用约束、唯一约束、校验约束和断言使用，并属于给定用户。 (CONSTRAINT_COLUMN_USAGE Rowset) | TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME
adSchemaConstraintTableUsage | 7 | 返回目录中定义的表，这些表由引用约束、唯一约束、校验约束和断言使用，并属于给定用户。 (CONSTRAINT_TABLE_USAGE Rowset) | TABLE_CATALOG TABLE_SCHEMA TABLE_NAME
adSchemaCubes | 32 | 返回模式（如果提供者不支持模式则为目录）中可用立方的相关信息。 (CUBES Rowset*) | CATALOG_NAME SCHEMA_NAME CUBE_NAME
adSchemaDBInfoKeywords | 30 | 返回提供者特有的关键字的列表。 (IDBInfo::GetKeywords *) | <None>
adSchemaDBInfoLiterals | 31 | 返回文本命令中使用的文字的列表，这些文字是提供者特有的。 (IDBInfo::GetLiteralInfo *) | <None>
adSchemaDimensions | 33 | 返回给定立方中的维的信息。每一维对应一行。 (DIMENSIONS Rowset *) | CATALOG_NAME SCHEMA_NAME CUBE_NAME DIMENSION_NAME DIMENSION_UNIQUE_NAME
adSchemaForeignKeys | 27 | 返回给定用户在目录中定义的外键列。 (FOREIGN_KEYS Rowset) | PK_TABLE_CATALOG PK_TABLE_SCHEMA PK_TABLE_NAME FK_TABLE_CATALOG FK_TABLE_SCHEMA FK_TABLE_NAME
adSchemaHierarchies | 34 | 返回维中可用分级结构的信息。 (HIERARCHIES Rowset *) | CATALOG_NAME SCHEMA_NAME CUBE_NAME DIMENSION_UNIQUE_NAME HIERARCHY_NAME HIERARCHY_UNIQUE_NAME
adSchemaIndexes | 12 | 返回目录中定义的，属于给定用户的索引。 (INDEXES Rowset) | TABLE_CATALOG TABLE_SCHEMA INDEX_NAME TYPE TABLE_NAME
adSchemaKeyColumnUsage | 8 | 返回目录中定义的，被给定用户约束为关键字的列。 (KEY_COLUMN_USAGE Rowset) | CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME
adSchemaLevels | 35 | 返回维中可用级别的信息。 (LEVELS Rowset*) | CATALOG_NAME SCHEMA_NAME CUBE_NAME DIMENSION_UNIQUE_NAME HIERARCHY_UNIQUE_NAME LEVEL_NAME LEVEL_UNIQUE_NAME
adSchemaMeasures | 36 | 返回可用度量的信息。 (MEASURES Rowset *) | CATALOG_NAME SCHEMA_NAME CUBE_NAME MEASURE_NAME MEASURE_UNIQUE_NAME
adSchemaMembers | 38 | 返回可用成员的信息。 (MEMBERS Rowset *) | CATALOG_NAME SCHEMA_NAME CUBE_NAME DIMENSION_UNIQUE_NAME HIERARCHY_UNIQUE_NAME LEVEL_UNIQUE_NAME LEVEL_NUMBER MEMBER_NAME MEMBER_UNIQUE_NAME MEMBER_CAPTION MEMBER_TYPE Tree operator（有关详细信息，请参阅“OLE DB for OLAP”文档。）
adSchemaPrimaryKeys | 28 | 返回给定用户在目录中定义的主键列。 (PRIMARY_KEYS Rowset) | PK_TABLE_CATALOG PK_TABLE_SCHEMA PK_TABLE_NAME
adSchemaProcedureColumns | 29 | 返回行集合中列的信息，该行集合由过程返回。 (PROCEDURE_COLUMNS Rowset) | PROCEDURE_CATALOG PROCEDURE_SCHEMA PROCEDURE_NAME COLUMN_NAME
adSchemaProcedureParameters | 26 | 返回过程参数和返回代码的信息。 (PROCEDURE_PARAMETERS Rowset) | PROCEDURE_CATALOG PROCEDURE_SCHEMA PROCEDURE_NAME PARAMETER_NAME
adSchemaProcedures | 16 | 返回目录中定义的属于给定用户的过程。 (PROCEDURES Rowset) | PROCEDURE_CATALOG PROCEDURE_SCHEMA PROCEDURE_NAME PROCEDURE_TYPE
adSchemaProperties | 37 | 返回维的每一级别可用属性的信息。 (PROPERTIES Rowset *) | CATALOG_NAME SCHEMA_NAME CUBE_NAME DIMENSION_UNIQUE_NAME HIERARCHY_UNIQUE_NAME LEVEL_UNIQUE_NAME MEMBER_UNIQUE_NAME PROPERTY_TYPE PROPERTY_NAME
adSchemaProviderSpecific | -1 | 如果提供者定义自己的非标准模式查询，则将使用该常量。 | <Provider specific>
adSchemaProviderTypes | 22 | 返回数据提供者支持的（基本）数据类型。 (PROVIDER_TYPES Rowset) | DATA_TYPE BEST_MATCH
AdSchemaReferentialConstraints | 9 | 返回目录中定义的属于给定用户的引用约束。 (REFERENTIAL_CONSTRAINTS Rowset) | CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME
adSchemaSchemata | 17 | 返回属于给定用户的模式（数据库对象）。 (SCHEMATA Rowset) | CATALOG_NAME SCHEMA_NAME SCHEMA_OWNER
adSchemaSQLLanguages | 18 | 返回目录中定义的 SQL 实现数据处理所支持的一致性级别、选项和方言。 (SQL_LANGUAGES Rowset) | <None>
adSchemaStatistics | 19 | 返回目录中定义的属于给定用户的统计。 (STATISTICS Rowset) | TABLE_CATALOG TABLE_SCHEMA TABLE_NAME
adSchemaTableConstraints | 10 | 返回目录中定义的属于给定用户的表约束。 (TABLE_CONSTRAINTS Rowset) | CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME CONSTRAINT_TYPE
adSchemaTablePrivileges | 14 | 返回对目录中所定义的表的列具有的特权，这些特权可以授予给定用户或可由他们授权。 (TABLE_PRIVILEGES Rowset) | TABLE_CATALOG TABLE_SCHEMA TABLE_NAME GRANTOR GRANTEE
adSchemaTables | 20 | 返回目录中定义的给定用户可访问的表（包括视图）。 (TABLES Rowset) | TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE
adSchemaTranslations | 21 | 返回目录中定义的给定用户可访问的字符转换。 (TRANSLATIONS Rowset) | TRANSLATION_CATALOG TRANSLATION_SCHEMA TRANSLATION_NAME
adSchemaTrustees | 39 | 保留以供日后使用。 |
adSchemaUsagePrivileges | 15 | 返回对目录中定义的对象的 USAGE 特权，这些特权可授予给定用户或可由他们授权。 (USAGE_PRIVILEGES Rowset) | OBJECT_CATALOG OBJECT_SCHEMA OBJECT_NAME OBJECT_TYPE GRANTOR GRANTEE
adSchemaViewColumnUsage | 24 | 返回目录中定义的属于给定用户的相关列，在这些列上可查看表。 (VIEW_COLUMN_USAGE Rowset) | VIEW_CATALOG VIEW_SCHEMA VIEW_NAME
adSchemaViews | 23 | 返回目录中定义的给定用户可访问的视图。 (VIEWS Rowset) | TABLE_CATALOG TABLE_SCHEMA TABLE_NAME
adSchemaViewTableUsage | 25 | 返回目录中定义的属于给定用户的相关表，在这些表上可查看表。 (VIEW_TABLE_USAGE Rowset) | VIEW_CATALOG VIEW_SCHEMA VIEW_NAME

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.Schema.ASSERTS
AdoEnums.Schema.CATALOGS
AdoEnums.Schema.CHARACTERSETS
AdoEnums.Schema.CHECKCONSTRAINTS
AdoEnums.Schema.COLLATIONS
AdoEnums.Schema.COLUMNPRIVILEGES
AdoEnums.Schema.COLUMNS
AdoEnums.Schema.COLUMNSDOMAINUSAGE
AdoEnums.Schema.CONSTRAINTCOLUMNUSAGE
AdoEnums.Schema.CONSTRAINTTABLEUSAGE
AdoEnums.Schema.CUBES
AdoEnums.Schema.DBINFOKEYWORDS
AdoEnums.Schema.DBINFOLITERALS
AdoEnums.Schema.DIMENSIONS
AdoEnums.Schema.FOREIGNKEYS
AdoEnums.Schema.HIERARCHIES
AdoEnums.Schema.INDEXES
AdoEnums.Schema.KEYCOLUMNUSAGE
AdoEnums.Schema.LEVELS
AdoEnums.Schema.MEASURES
AdoEnums.Schema.MEMBERS
AdoEnums.Schema.PRIMARYKEYS
AdoEnums.Schema.PROCEDURECOLUMNS
AdoEnums.Schema.PROCEDUREPARAMETERS
AdoEnums.Schema.PROCEDURES
AdoEnums.Schema.PROPERTIES
AdoEnums.Schema.PROVIDERSPECIFIC
AdoEnums.Schema.PROVIDERTYPES
AdoEnums.Schema.REFERENTIALCONTRAINTS
AdoEnums.Schema.SCHEMATA
AdoEnums.Schema.SQLLANGUAGES
AdoEnums.Schema.STATISTICS
AdoEnums.Schema.TABLECONSTRAINTS
AdoEnums.Schema.TABLEPRIVILEGES
AdoEnums.Schema.TABLES
AdoEnums.Schema.TRANSLATIONS
AdoEnums.Schema.TRUSTEES
AdoEnums.Schema.USAGEPRIVILEGES
AdoEnums.Schema.VIEWCOLUMNUSAGE
AdoEnums.Schema.VIEWS
AdoEnums.Schema.VIEWTABLEUSAGE

请参阅

应用于：OpenSchema 方法


SearchDirectionEnum

指定 Recordset 中记录搜索的方向。

常量 | 值 | 说明
adSearchBackward | -1 | 向后搜索，停在 Recordset 的开始处。如果未找到匹配项，记录指针将定位在 BOF。
adSearchForward | 1 | 向前搜索，停在 Recordset 的结尾处。如果未找到匹配项，记录指针将定位在 EOF。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.SearchDirection.BACKWARD
AdoEnums.SearchDirection.FORWARD

请参阅

应用于：Find 方法


SeekEnum

指定要执行的 Seek 类型。

常量 | 值 | 说明
adSeekFirstEQ | 1 | 查找等于 KeyValues 的第一个键。
adSeekLastEQ | 2 | 查找等于 KeyValues 的最后一个键。
adSeekAfterEQ | 4 | 查找等于 KeyValues 的键，或仅在出现匹配的位置之后查找。
adSeekAfter | 8 | 仅在出现与 KeyValues 匹配的位置之后查找。
adSeekBeforeEQ | 16 | 查找等于 KeyValues 的键，或仅在出现匹配的位置之前查找。
adSeekBefore | 32 | 仅在出现与 KeyValues 匹配的位置之前查找。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.Seek.FIRSTEQ
AdoEnums.Seek.LASTEQ
AdoEnums.Seek.AFTEREQ
AdoEnums.Seek.AFTER
AdoEnums.Seek.BEFOREEQ
AdoEnums.Seek.BEFORE

请参阅

应用于：Seek 方法


StreamOpenOptionsEnum

指定打开 Stream 对象的选项。这些值可以用 OR 操作组合。

常量 | 值 | 说明
adOpenStreamAsync | 1 | 以异步模式打开 Stream 对象。
adOpenStreamFromRecord | 4 | 标识 Source 参数的内容，该参数为将被打开的 Record 对象。默认行为是将 Source 当作直接指向树状结构中节点的 URL。与该节点相关联的默认流将被打开。
adOpenStreamUnspecified | -1 | 默认值。指定用默认选项打开 Stream 对象。

ADO/WFC 等价内容

这些常量没有 ADO/WFC 等价内容。

请参阅

应用于：Open 方法 (ADO Stream)


StreamReadEnum

指定是从 Stream 对象读取整个流还是下一行。

常量 | 值 | 说明
adReadAll | -1 | 默认值。从流中读取当前位置到 EOS 标志之间的全部字节。对二进制流（Type 为 adTypeBinary），这是唯一有效的 StreamReadEnum 值。
adReadLine | -2 | 从流中读取下一行（由 LineSeparator 属性指定）。

ADO/WFC 等价内容

这些常量没有 ADO/WFC 等价内容。

请参阅

应用于：Read 方法 | ReadText 方法


StreamTypeEnum

指定存储在 Stream 对象中的数据类型。

常量 | 值 | 说明
adTypeBinary | 1 | 指示二进制数据。
adTypeText | 2 | 默认值。指示文本数据，该文本数据在 Charset 指定的字符集中。

ADO/WFC 等价内容

这些常量没有 ADO/WFC 等价内容。

请参阅

应用于：Type 属性 (ADO Stream)


StreamWriteEnum

指定是否将分行符追加到写入 Stream 对象的字符串中。

常量 | 值 | 说明
adWriteChar | 0 | 默认值。向 Stream 对象中写入指定的文本字符串（由 Data 参数指定）。
adWriteLine | 1 | 向 Stream 对象中写入一个文本字符串和一个分行符。如果未定义 LineSeparator 属性，将返回运行时错误。

ADO/WFC 等价内容

这些常量没有 ADO/WFC 等价内容。

请参阅

应用于：WriteText 方法


StringFormatEnum

指定将 Recordset 作为字符串检索时使用的格式。

常量 | 值 | 说明
adClipString | 2 | 用 RowDelimiter 分隔行，ColumnDelimiter 分隔列，NullExpr 分隔 Null 值。GetString 方法的这三个参数仅当 StringFormat 值为 adClipString 时有效。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.StringFormat.CLIPSTRING

请参阅

应用于：GetString 方法


XactAttributeEnum

指定 Connection 对象的事务属性。

常量 | 值 | 说明
adXactAbortRetaining | 262144 | 执行保留的终止，即调用 RollbackTrans 自动启动新事务。并非所有的提供者都支持此常量。
adXactCommitRetaining | 131072 | 执行保留的终止，即调用 CommitTrans 自动启动新事务。并非所有的提供者都支持此常量。

ADO/WFC 等价内容

包：com.ms.wfc.data

常量
AdoEnums.XactAttribute.ABORTRETAINING
AdoEnums.XactAttribute.COMMITRETAINING

请参阅

应用于：Attributes 属性


ADO 语法索引

调用 ADO 方法和属性的语法依开发环境不同而不同。其他“ADO 语言参考”以 Microsoft Visual Basic 编程语言为例来说明 ADO 方法和属性的语法。但是，有关基于编程语言和方法的更多特定语法范例，请参考以下部分。

  • 用于 COM 的 ADO for Visual C++ 语法索引涉及了不通过 Microsoft Visual C++ 使用 #import 编译器伪指令的 ADO 属性和方法。
  • 使用 #import 的 ADO for Visual C++ 语法索引涉及了通过 Microsoft Visual C++ 使用的 #import 编译器伪指令的 ADO 属性和方法。
  • ADO/WFC 语法索引涉及了通过 Visual J++ 使用 ADO Windows Foundation Classes。

请参阅

通过 Microsoft Visual Basic 使用 ADO | 通过 Microsoft Visual C++ 使用 ADO | 通过 Microsoft Visual J++ 使用 ADO | 通过脚本语言使用 ADO


用于 COM 的 ADO for Visual C++ 语法索引

此索引是对基于 Microsoft Visual C++ 的“ADO 语言参考”的交叉引用。

如果在应用程序中使用 #import 伪指令，将会生成一个头文件，它使您可以使用与 Microsoft Visual Basic 类似的语法。可将 get_PropertyName 和 put_PropertyName 格式的属性名称看作已被简单声明为 PropertyName。这样便可将属性视为数据成员而不是函数。

所有方法、属性和事件均为返回 HRESULT 的函数，您可以测试以确定该函数是否顺利执行。

针对下列元素的 Visual C++ 中的方法和属性语法列表：

  • 集合
  • Command 对象
  • Connection 对象
  • Error 对象
  • Field 对象
  • Parameter 对象
  • Record 对象
  • Recordset 对象
  • Stream 对象

请参阅

使用 #import 的 ADO for Visual C++ 语法索引 | ActiveX Data Objects 开始页


集合（ADO for Visual C++ 语法）

Parameters

方法

Append(IDispatch *Object)
Delete(VARIANT Index)
Refresh(void)

Properties

get_Count(long *c)
get_Item(VARIANT Index, _ADOParameter **ppvObject)

Fields

方法

Append(BSTR bstrName, DataTypeEnum Type, long DefinedSize, FieldAttributeEnum Attrib)
Delete(VARIANT Index)
Refresh(void)

Properties

get_Count(long *c)
get_Item(VARIANT Index, ADOField **ppvObject)

Errors

方法

Clear(void)
Refresh(void)

Properties

get_Count(long *c)
get_Item(VARIANT Index, ADOError **ppvObject)

Properties

方法

Refresh(void)

Properties

get_Count(long *c)
get_Item(VARIANT Index, ADOProperty **ppvObject)

请参阅

Errors 集合 | Fields 集合 | Parameters 集合 | Properties 集合


Command（ADO for Visual C++ 语法）

方法

Cancel(void)
CreateParameter(BSTR Name, DataTypeEnum Type, ParameterDirectionEnum Direction, long Size, VARIANT Value, _ADOParameter **ppiprm)
Execute(VARIANT *RecordsAffected, VARIANT *Parameters, long Options, _ADORecordset **ppirs)

Properties

get_ActiveConnection(_ADOConnection **ppvObject)
put_ActiveConnection(VARIANT vConn)
putref_ActiveConnection(_ADOConnection *pCon)
get_CommandText(BSTR *pbstr)
put_CommandText(BSTR bstr)
get_CommandTimeout(LONG *pl)
put_CommandTimeout(LONG Timeout)
get_CommandType(CommandTypeEnum *plCmdType)
put_CommandType(CommandTypeEnum lCmdType)
get_Name(BSTR *pbstrName)
put_Name(BSTR bstrName)
get_Prepared(VARIANT_BOOL *pfPrepared)
put_Prepared(VARIANT_BOOL fPrepared)
get_State(LONG *plObjState)
get_Parameters(ADOParameters **ppvObject)

请参阅

Command 对象


Connection（ADO for Visual C++ 语法）

方法

BeginTrans(long *TransactionLevel)
CommitTrans(void)
RollbackTrans(void)
Cancel(void)
Close(void)
Execute(BSTR CommandText, VARIANT *RecordsAffected, long Options,_ADORecordset **ppiRset)
Open(BSTR ConnectionString, BSTR UserID, BSTR Password, long Options)
OpenSchema(SchemaEnum Schema, VARIANT Restrictions, VARIANT SchemaID,_ADORecordset **pprset)

Properties

get_Attributes(long *plAttr)
put_Attributes(long lAttr)
get_CommandTimeout(LONG *plTimeout)
put_CommandTimeout(LONG lTimeout)
get_ConnectionString(BSTR *pbstr)
put_ConnectionString(BSTR bstr)
get_ConnectionTimeout(LONG *plTimeout)
put_ConnectionTimeout(LONG lTimeout)
get_CursorLocation(CursorLocationEnum *plCursorLoc)
put_CursorLocation(CursorLocationEnum lCursorLoc)
get_DefaultDatabase(BSTR *pbstr)
put_DefaultDatabase(BSTR bstr)
get_IsolationLevel(IsolationLevelEnum *Level)
put_IsolationLevel(IsolationLevelEnum Level)
get_Mode(ConnectModeEnum *plMode)
put_Mode(ConnectModeEnum lMode)
get_Provider(BSTR *pbstr)
put_Provider(BSTR Provider)
get_State(LONG *plObjState)
get_Version(BSTR *pbstr)
get_Errors(ADOErrors **ppvObject)

事件

BeginTransComplete(LONG TransactionLevel, ADOError *pError,
                  EventStatusEnum *adStatus, _ADOConnection *pConnection)
CommitTransComplete(ADOError *pError, EventStatusEnum *adStatus,
                  _ADOConnection *pConnection)
ConnectComplete(ADOError *pError, EventStatusEnum *adStatus,
               _ADOConnection *pConnection)
Disconnect(EventStatusEnum *adStatus, _ADOConnection *pConnection)
ExecuteComplete(LONG RecordsAffected, ADOError *pError,
               EventStatusEnum *adStatus, _ADOCommand *pCommand,
               _ADORecordset *pRecordset, _ADOConnection *pConnection)
InfoMessage(ADOError *pError, EventStatusEnum *adStatus,
            _ADOConnection *pConnection)
RollbackTransComplete(ADOError *pError, EventStatusEnum *adStatus,
                     _ADOConnection *pConnection)
WillConnect(BSTR *ConnectionString, BSTR *UserID, BSTR *Password,
               long *Options, EventStatusEnum *adStatus,
               _ADOConnection *pConnection)
WillExecute(BSTR *Source, CursorTypeEnum *CursorType,
               LockTypeEnum *LockType, long *Options,
               EventStatusEnum *adStatus, _ADOCommand *pCommand,
               _ADORecordset *pRecordset, _ADOConnection *pConnection)

请参阅

Connection 对象


Error（ADO for Visual C++ 语法）

Properties

get_Description(BSTR *pbstr)
get_NativeError(long *pl)
get_Number(long *pl)
get_Source(BSTR *pbstr)
get_SQLState(BSTR *pbstr)

请参阅

Error 对象


Field（ADO for Visual C++ 语法）

方法

AppendChunk(VARIANT Data)
GetChunk(long Length, VARIANT *pvar)

Properties

get_ActualSize(long *pl)
get_Attributes(long *pl)
put_Attributes(long lAttributes)
get_DataFormat(IUnknown **ppiDF)
put_DataFormat(IUnknown *piDF)
get_DefinedSize(long *pl)
put_DefinedSize(long lSize)
get_Name(BSTR *pbstr)
get_NumericScale(BYTE *pbNumericScale)
put_NumericScale(BYTE bScale)
get_OriginalValue(VARIANT *pvar)
get_Precision(BYTE *pbPrecision)
put_Precision(BYTE bPrecision)
get_Type(DataTypeEnum *pDataType)
put_Type(DataTypeEnum DataType)
get_UnderlyingValue(VARIANT *pvar)
get_Value(VARIANT *pvar)
put_Value(VARIANT Val)

请参阅

Field 对象


Parameter（ADO for Visual C++ 语法）

方法

AppendChunk(VARIANT Val)

Properties

get_Attributes(LONG *plParmAttribs)
put_Attributes(LONG lParmAttribs)
get_Direction(ParameterDirectionEnum *plParmDirection)
put_Direction(ParameterDirectionEnum lParmDirection)
get_Name(BSTR *pbstr)
put_Name(BSTR bstr)
get_NumericScale(BYTE *pbScale)
put_NumericScale(BYTE bScale)
get_Precision(BYTE *pbPrecision)
put_Precision(BYTE bPrecision)
get_Size(long *pl)
put_Size(long l)
get_Type(DataTypeEnum *psDataType)
put_Type(DataTypeEnum sDataType)
get_Value(VARIANT *pvar)
put_Value(VARIANT val)

请参阅

Parameter 对象


Record（ADO for Visual C++ 语法）

方法

Cancel(void)
Close(void)
CopyRecord(BSTR Source, BSTR Destination, BSTR UserName, BSTR Password,
            CopyRecordOptionsEnum Options, VARIANT_BOOL Async, BSTR
            *pbstrNewURL)
DeleteRecord(BSTR Source, VARIANT_BOOL Async)
GetChildren(_ADORecordset **ppRSet)
MoveRecord(BSTR Source, BSTR Destination, BSTR UserName, BSTR Password,
            MoveRecordOptionsEnum Options, VARIANT_BOOL Async, BSTR
            *pbstrNewURL)
Open(VARIANT Source, VARIANT ActiveConnection, ConnectModeEnum Mode,
         RecordCreateOptionsEnum CreateOptions, RecordOpenOptionsEnum
         Options, BSTR UserName, BSTR Password)

Properties

get_ActiveConnection(VARIANT *pvar)
put_ActiveConnection(BSTR bstrConn)
putref_ActiveConnection(_ADOConnection *Con)
get_Fields(ADOFields **ppFlds)
get_Mode(ConnectModeEnum *pMode)
put_Mode(ConnectModeEnum Mode)
get_ParentURL(BSTR *pbstrParentURL)
get_RecordType(RecordTypeEnum *pType)
get_Source(VARIANT *pvar)
put_Source(BSTR Source)
putref_Source(IDispatch *Source)
get_State(ObjectStateEnum *pState)

请参阅

Record 对象


Recordset（ADO for Visual C++ 语法）

方法

AddNew(VARIANT FieldList, VARIANT Values)
Cancel(void)
CancelBatch(AffectEnum AffectRecords)
CancelUpdate(void)
Clone(LockTypeEnum LockType, _ADORecordset **ppvObject)
Close(void)
CompareBookmarks(VARIANT Bookmark1, VARIANT Bookmark2,
                     CompareEnum *pCompare)
Delete(AffectEnum AffectRecords)
Find(BSTR Criteria, LONG SkipRecords, SearchDirectionEnum SearchDirection,
      VARIANT Start)
GetRows(long Rows, VARIANT Start, VARIANT Fields, VARIANT *pvar)
GetString(StringFormatEnum StringFormat, long NumRows, BSTR ColumnDelimeter,
            BSTR RowDelimeter, BSTR NullExpr, BSTR *pRetString)
Move(long NumRecords, VARIANT Start)
MoveFirst(void)
MoveLast(void)
MoveNext(void)
MovePrevious(void)
NextRecordset(VARIANT *RecordsAffected, _ADORecordset **ppiRs)
Open(VARIANT Source, VARIANT ActiveConnection, CursorTypeEnum CursorType,
         LockTypeEnum LockType, LONG Options)
Requery(LONG Options)
Resync(AffectEnum AffectRecords, ResyncEnum ResyncValues)
Save(BSTR FileName, PersistFormatEnum PersistFormat)
Supports(CursorOptionEnum CursorOptions, VARIANT_BOOL *pb)
Update(VARIANT Fields, VARIANT Values)
UpdateBatch(AffectEnum AffectRecords)

Properties

get_AbsolutePage(PositionEnum *pl)
put_AbsolutePage(PositionEnum Page)
get_AbsolutePosition(PositionEnum *pl)
put_AbsolutePosition(PositionEnum Position)
get_ActiveCommand(IDispatch **ppCmd)
get_ActiveConnection(VARIANT *pvar)
put_ActiveConnection(VARIANT vConn)
putref_ActiveConnection(IDispatch *pconn)
get_BOF(VARIANT_BOOL *pb)
get_Bookmark(VARIANT *pvBookmark)
put_Bookmark(VARIANT vBookmark)
get_CacheSize(long *pl)
put_CacheSize(long CacheSize)
get_CursorLocation(CursorLocationEnum *plCursorLoc)
put_CursorLocation(CursorLocationEnum lCursorLoc)
get_CursorType(CursorTypeEnum *plCursorType)
put_CursorType(CursorTypeEnum lCursorType)
get_DataMember(BSTR *pbstrDataMember)
put_DataMember(BSTR bstrDataMember)
get_DataSource(IUnknown **ppunkDataSource)
putref_DataSource(IUnknown *punkDataSource)
get_EditMode(EditModeEnum *pl)
get_EOF(VARIANT_BOOL *pb)
get_Filter(VARIANT *Criteria)
put_Filter(VARIANT Criteria)
get_LockType(LockTypeEnum *plLockType)
put_LockType(LockTypeEnum lLockType)
get_MarshalOptions(MarshalOptionsEnum *peMarshal)
put_MarshalOptions(MarshalOptionsEnum eMarshal)
get_MaxRecords(long *plMaxRecords)
put_MaxRecords(long lMaxRecords)
get_PageCount(long *pl)
get_PageSize(long *pl)
put_PageSize(long PageSize)
get_RecordCount(long *pl)
get_Sort(BSTR *Criteria)
put_Sort(BSTR Criteria)
get_Source(VARIANT *pvSource)
put_Source(BSTR bstrConn)
putref_Source(IDispatch *pcmd)
get_State(LONG *plObjState)
get_Status(long *pl)
get_StayInSync(VARIANT_BOOL *pbStayInSync)
put_StayInSync(VARIANT_BOOL bStayInSync)
get_Fields(ADOFields **ppvObject)

事件

EndOfRecordset(VARIANT_BOOL *fMoreData, EventStatusEnum *adStatus,
                  _ADORecordset *pRecordset)
FetchComplete(ADOError *pError, EventStatusEnum *adStatus,
                  _ADORecordset *pRecordset)
FetchProgress(long Progress, long MaxProgress, EventStatusEnum *adStatus,
                  _ADORecordset *pRecordset)
FieldChangeComplete(LONG cFields, VARIANT Fields, ADOError *pError,
                  EventStatusEnum *adStatus, _ADORecordset *pRecordset)
MoveComplete(EventReasonEnum adReason, ADOError *pError,
                  EventStatusEnum *adStatus, _ADORecordset *pRecordset)
RecordChangeComplete(EventReasonEnum adReason, LONG cRecords,
                  ADOError *pError, EventStatusEnum *adStatus,
                  _ADORecordset *pRecordset)
RecordsetChangeComplete(EventReasonEnum adReason, ADOError *pError,
                  EventStatusEnum *adStatus, _ADORecordset *pRecordset)
WillChangeField(LONG cFields, VARIANT Fields, EventStatusEnum *adStatus,
                  _ADORecordset *pRecordset)
WillChangeRecord(EventReasonEnum adReason, LONG cRecords,
                  EventStatusEnum *adStatus, _ADORecordset *pRecordset)
WillChangeRecordset(EventReasonEnum adReason, EventStatusEnum *adStatus,
                  _ADORecordset *pRecordset)
WillMove(EventReasonEnum adReason, EventStatusEnum *adStatus,
                  _ADORecordset *pRecordset)

请参阅

Recordset 对象


Stream（ADO for Visual C++ 语法）

方法

Cancel(void)
Close(void)
CopyTo(_ADOStream *DestStream, LONG CharNumber = -1)
Flush(void)
LoadFromFile(BSTR FileName)
Open(VARIANT Source, ConnectModeEnum Mode, StreamOpenOptionsEnum Options,
         BSTR UserName, BSTR Password)
Read(long NumBytes, VARIANT *pVal)
ReadText(long NumChars, BSTR *pbstr)
SaveToFile(BSTR FileName, SaveOptionsEnum Options = adSaveCreateNotExist)
SetEOS(void)
SkipLine(void)
Write(VARIANT Buffer)
WriteText(BSTR Data, StreamWriteEnum Options = adWriteChar)

Properties

get_Charset(BSTR *pbstrCharset)
put_Charset(BSTR Charset)
get_EOS(VARIANT_BOOL *pEOS)
get_LineSeparator(LineSeparatorEnum *pLS)
put_LineSeparator(LineSeparatorEnum LineSeparator)
get_Mode(ConnectModeEnum *pMode)
put_Mode(ConnectModeEnum Mode)
get_Position(LONG *pPos)
put_Position(LONG Position)
get_Size(LONG *pSize)
get_State(ObjectStateEnum *pState)
get_Type(StreamTypeEnum *pType)
put_Type(StreamTypeEnum Type)

请参阅

Stream 对象


使用 #import 的 ADO for Visual C++ 语法索引

此索引是对基于 Microsoft Visual C++ 和 #import 伪指令的“ADO 语言参考”的交叉引用。

这一特定索引是通过使用针对 ADO .dll 的 #import 伪指令来编译程序，然后对所生成的 *.tlh 文件重新格式化获得的。只有关于方法、属性和事件的信息被保留。每个属性声明的替换语法列在相对应的“__declspec(property...)”伪指令中。

有关详细信息，建议阅读 Visual C++ ADO 编程。

针对下列元素的带 #import 伪指令的 Visual C++ 中的方法和属性语法列表：

  • ADO 集合
  • Command 对象
  • Connection 对象
  • Error 对象
  • Field 对象
  • Parameter 对象
  • Property 对象
  • Record 对象
  • Recordset 对象
  • Stream 对象
  • ConnectionEvents
  • RecordsetEvents

请参阅

用于 COM 的 ADO for Visual C++ 语法索引


集合（使用 #import 的 Visual C++ 语法索引）

集合继承某些公共方法和属性时，了解这一点将大有用处。

所有集合均继承 Count 属性和 Refresh 方法，并且均添加 Item 属性。Errors 集合添加 Clear 方法。Parameters 集合继承 Append 和 Delete 方法，而 Fields 集合添加 Append、Delete 和 Update 方法。

Properties 集合

方法

HRESULT Refresh( );

Properties

long GetCount( );
__declspec(property(get=GetCount)) long Count;

PropertyPtr GetItem( const _variant_t & Index );
__declspec(property(get=GetItem)) PropertyPtr Item[];

Errors 集合

方法

HRESULT Clear( );

HRESULT Refresh( );

Properties

long GetCount( );
__declspec(property(get=GetCount)) long Count;

PropertyPtr GetItem( const _variant_t & Index );
__declspec(property(get=GetItem)) PropertyPtr Item[];

Parameters 集合

方法

HRESULT Append( IDispatch * Object );

HRESULT Delete( const _variant_t & Index );

HRESULT Refresh( );

Properties

long GetCount( );
__declspec(property(get=GetCount)) long Count;

PropertyPtr GetItem( const _variant_t & Index );
__declspec(property(get=GetItem)) PropertyPtr Item[];

Fields 集合

方法

HRESULT Append( _bstr_t Name, enum DataTypeEnum Type, long DefinedSize,
    enum FieldAttributeEnum Attrib, const _variant_t & FieldValue =
    vtMissing );

HRESULT Delete( const _variant_t & Index );

HRESULT Refresh( );

HRESULT Update( );

Properties

long GetCount( );
__declspec(property(get=GetCount)) long Count;

PropertyPtr GetItem( const _variant_t & Index );
__declspec(property(get=GetItem)) PropertyPtr Item[];

请参阅

Errors 集合 | Fields 集合 | Parameters 集合 | Properties 集合


Command（使用 #import 的 Visual C++ 语法索引）

方法

HRESULT Cancel( );

_RecordsetPtr Execute( VARIANT * RecordsAffected, VARIANT
    * Parameters, long Options );

_ParameterPtr CreateParameter( _bstr_t Name, enum
    DataTypeEnum Type, enum ParameterDirectionEnum Direction, long Size,
    const _variant_t & Value = vtMissing );

Properties

_ConnectionPtr GetActiveConnection( );
void PutRefActiveConnection( struct _Connection * ppvObject );
void PutActiveConnection( const _variant_t & ppvObject );
__declspec(property(get=GetActiveConnection,put=PutRefActiveConnection))
    _ConnectionPtr ActiveConnection;

_bstr_t GetCommandText( );
void PutCommandText( _bstr_t pbstr );
__declspec(property(get=GetCommandText,put=PutCommandText)) _bstr_t
    CommandText;

long GetCommandTimeout( );
void PutCommandTimeout( long pl );
__declspec(property(get=GetCommandTimeout,put=PutCommandTimeout)) long
    CommandTimeout;

void PutCommandType( enum CommandTypeEnum plCmdType );
enum CommandTypeEnum GetCommandType( );
__declspec(property(get=GetCommandType,put=PutCommandType)) enum
    CommandTypeEnum CommandType;

VARIANT_BOOL GetPrepared( );
void PutPrepared( VARIANT_BOOL pfPrepared );
__declspec(property(get=GetPrepared,put=PutPrepared)) VARIANT_BOOL
    Prepared;

ParametersPtr GetParameters( );
__declspec(property(get=GetParameters)) ParametersPtr
    Parameters;

_bstr_t GetName( );
void PutName( _bstr_t pbstrName );
__declspec(property(get=GetName,put=PutName)) _bstr_t Name;

long GetState( );
__declspec(property(get=GetState)) long State;

请参阅

Command 对象


Connection（使用 #import 的 Visual C++ 语法索引）

方法

HRESULT Cancel( );

HRESULT Close( );

_RecordsetPtr Execute( _bstr_t CommandText, VARIANT *
    RecordsAffected,     long Options );

long BeginTrans( );
HRESULT CommitTrans( );
HRESULT RollbackTrans( );

HRESULT Open( _bstr_t ConnectionString, _bstr_t UserID,
    _bstr_t Password,     long Options );

_RecordsetPtr OpenSchema( enum SchemaEnum Schema, const
    _variant_t &     Restrictions = vtMissing, const _variant_t &
    SchemaID = vtMissing );

Properties

_bstr_t GetConnectionString( );
void PutConnectionString( _bstr_t pbstr );
__declspec(property(get=GetConnectionString,put=PutConnectionString))
    _bstr_t ConnectionString;

long GetCommandTimeout( );
void PutCommandTimeout( long plTimeout );
__declspec(property(get=GetCommandTimeout,put=PutCommandTimeout)) long
    CommandTimeout;

long GetConnectionTimeout( );
void PutConnectionTimeout( long plTimeout );
__declspec(property(get=GetConnectionTimeout,put=PutConnectionTimeout))
    long ConnectionTimeout;

_bstr_t GetVersion( );
__declspec(property(get=GetVersion)) _bstr_t Version;

ErrorsPtr GetErrors( );
__declspec(property(get=GetErrors)) ErrorsPtr Errors;

_bstr_t GetDefaultDatabase( );
void PutDefaultDatabase( _bstr_t pbstr );
__declspec(property(get=GetDefaultDatabase,put=PutDefaultDatabase))
    _bstr_t DefaultDatabase;

enum IsolationLevelEnum GetIsolationLevel( );
void PutIsolationLevel( enum IsolationLevelEnum Level );
__declspec(property(get=GetIsolationLevel,put=PutIsolationLevel)) enum
    IsolationLevelEnum IsolationLevel;

long GetAttributes( );
void PutAttributes( long plAttr );
__declspec(property(get=GetAttributes,put=PutAttributes)) long
    Attributes;

enum CursorLocationEnum GetCursorLocation( );
void PutCursorLocation( enum CursorLocationEnum plCursorLoc );
__declspec(property(get=GetCursorLocation,put=PutCursorLocation)) enum
    CursorLocationEnum CursorLocation;

enum ConnectModeEnum GetMode( );
void PutMode( enum ConnectModeEnum plMode );
__declspec(property(get=GetMode,put=PutMode)) enum ConnectModeEnum
    Mode;

_bstr_t GetProvider( );
void PutProvider( _bstr_t pbstr );
__declspec(property(get=GetProvider,put=PutProvider)) _bstr_t
    Provider;

long GetState( );
__declspec(property(get=GetState)) long State;

请参阅

Connection 对象


Error（使用 #import 的 Visual C++ 语法索引）

Properties

_bstr_t GetDescription( );
__declspec(property(get=GetDescription)) _bstr_t Description;

long GetHelpContext( );
__declspec(property(get=GetHelpContext)) long HelpContext;

_bstr_t GetHelpFile( );
__declspec(property(get=GetHelpFile)) _bstr_t HelpFile;

long GetNativeError( );
__declspec(property(get=GetNativeError)) long NativeError;

long GetNumber( );
__declspec(property(get=GetNumber)) long Number;

_bstr_t GetSource( );
__declspec(property(get=GetSource)) _bstr_t Source;

_bstr_t GetSQLState( );
__declspec(property(get=GetSQLState)) _bstr_t SQLState;

请参阅

Error 对象


Field（使用 #import 的 Visual C++ 语法索引）

方法

HRESULT AppendChunk( const _variant_t & Data );

_variant_t GetChunk( long Length );

Properties

long GetActualSize( );
__declspec(property(get=GetActualSize)) long ActualSize;

long GetAttributes( );
void PutAttributes( long pl );
__declspec(property(get=GetAttributes,put=PutAttributes)) long     Attributes;

IUnknownPtr GetDataFormat( );
void PutRefDataFormat( IUnknown * ppiDF );
__declspec(property(get=GetDataFormat,put=PutRefDataFormat)) IunknownPtr
    DataFormat;

long GetDefinedSize( );
void PutDefinedSize( long pl );
__declspec(property(get=GetDefinedSize,put=PutDefinedSize)) long
    DefinedSize;

_bstr_t GetName( );
__declspec(property(get=GetName)) _bstr_t Name;

unsigned char GetNumericScale( );
void PutNumericScale( unsigned char pbNumericScale );
__declspec(property(get=GetNumericScale,put=PutNumericScale)) unsigned
    char NumericScale;

_variant_t GetOriginalValue( );
__declspec(property(get=GetOriginalValue)) _variant_t OriginalValue;

unsigned char GetPrecision( );
void PutPrecision( unsigned char pbPrecision );
__declspec(property(get=GetPrecision,put=PutPrecision)) unsigned char
    Precision;

enum DataTypeEnum GetType( );
void PutType( enum DataTypeEnum pDataType );
__declspec(property(get=GetType,put=PutType)) enum DataTypeEnum Type;

_variant_t GetUnderlyingValue( );
__declspec(property(get=GetUnderlyingValue)) _variant_t UnderlyingValue;

_variant_t GetValue( );
void PutValue( const _variant_t & pvar );
__declspec(property(get=GetValue,put=PutValue)) _variant_t Value;

请参阅

Field 对象


Parameter（使用 #import 的 Visual C++ 语法索引）

方法

HRESULT AppendChunk( const _variant_t & Val );

Properties

long GetAttributes( );
void PutAttributes( long plParmAttribs );
__declspec(property(get=GetAttributes,put=PutAttributes)) long
    Attributes;

enum ParameterDirectionEnum GetDirection( );
void PutDirection( enum ParameterDirectionEnum plParmDirection );
__declspec(property(get=GetDirection,put=PutDirection)) enum
    ParameterDirectionEnum Direction;

_bstr_t GetName( );
void PutName( _bstr_t pbstr );
__declspec(property(get=GetName,put=PutName)) _bstr_t Name;

unsigned char GetNumericScale( );
void PutNumericScale( unsigned char pbScale );
__declspec(property(get=GetNumericScale,put=PutNumericScale)) unsigned
    char NumericScale;

unsigned char GetPrecision( );
void PutPrecision( unsigned char pbPrecision );
__declspec(property(get=GetPrecision,put=PutPrecision)) unsigned char
    Precision;

long GetSize( );
void PutSize( long pl );
__declspec(property(get=GetSize,put=PutSize)) long Size;

enum DataTypeEnum GetType( );
void PutType( enum DataTypeEnum psDataType );
__declspec(property(get=GetType,put=PutType)) enum DataTypeEnum Type;

_variant_t GetValue( );
void PutValue( const _variant_t & pvar );
__declspec(property(get=GetValue,put=PutValue)) _variant_t Value;

请参阅

Parameter 对象


Property（使用 #import 的 Visual C++ 语法索引）

Properties

long GetAttributes( );
void PutAttributes( long plAttributes );
__declspec(property(get=GetAttributes,put=PutAttributes)) long
    Attributes;

_bstr_t GetName( );
__declspec(property(get=GetName)) _bstr_t Name;

enum DataTypeEnum GetType( );
__declspec(property(get=GetType)) enum DataTypeEnum Type;

_variant_t GetValue( );
void PutValue( const _variant_t & pval );
__declspec(property(get=GetValue,put=PutValue)) _variant_t Value;

请参阅

Property 对象


Record（使用 #import 的 Visual C++ 语法索引）

方法

HRESULT Cancel( );

HRESULT Close( );

_bstr_t CopyRecord( _bstr_t Source, _bstr_t Destination,
    _bstr_t     UserName, _bstr_t Password, enum CopyRecordOptionsEnum
    Options,     VARIANT_BOOL Async );

HRESULT DeleteRecord( _bstr_t Source, VARIANT_BOOL Async );

_RecordsetPtr GetChildren( );

_bstr_t MoveRecord( _bstr_t Source, _bstr_t Destination,
    _bstr_t     UserName, _bstr_t Password, enum MoveRecordOptionsEnum
    Options,     VARIANT_BOOL Async );

HRESULT Open( const _variant_t & Source, const _variant_t
&     ActiveConnection, enum ConnectModeEnum Mode, enum
    RecordCreateOptionsEnum CreateOptions, enum RecordOpenOptionsEnum
    Options, _bstr_t UserName, _bstr_t Password );

Properties

_variant_t GetActiveConnection( );
void PutActiveConnection( _bstr_t pvar );
void PutRefActiveConnection( struct _Connection * pvar );

FieldsPtr GetFields( );
__declspec(property(get=GetFields)) FieldsPtr Fields;

enum ConnectModeEnum GetMode( );
void PutMode( enum ConnectModeEnum pMode );
__declspec(property(get=GetMode,put=PutMode)) enum ConnectModeEnum Mode;

_bstr_t GetParentURL( );
__declspec(property(get=GetParentURL)) _bstr_t ParentURL;

enum RecordTypeEnum GetRecordType( );
__declspec(property(get=GetRecordType)) enum RecordTypeEnum
    RecordType;

_variant_t GetSource( );
void PutSource( _bstr_t pvar );
void PutRefSource( IDispatch * pvar );

enum ObjectStateEnum GetState( );
__declspec(property(get=GetState)) enum ObjectStateEnum State;

请参阅

Record 对象


Recordset（使用 #import 的 Visual C++ 语法索引）

方法

HRESULT AddNew( const _variant_t & FieldList = vtMissing,
    const    _variant_t & Values = vtMissing );

HRESULT Cancel( );

HRESULT CancelBatch( enum AffectEnum AffectRecords );

HRESULT CancelUpdate( );

_RecordsetPtr Clone( enum LockTypeEnum LockType );

HRESULT Close( );

enum CompareEnum CompareBookmarks( const _variant_t
    & Bookmark1, const     _variant_t & Bookmark2 );

HRESULT Delete( enum AffectEnum AffectRecords );

HRESULT Find( _bstr_t Criteria, long SkipRecords, enum
    SearchDirectionEnum SearchDirection, const _variant_t & Start =
    vtMissing );

_variant_t GetRows( long Rows, const _variant_t & Start =
    vtMissing, const _variant_t & Fields = vtMissing );

_bstr_t GetString( enum
    StringFormatEnum StringFormat, long NumRows,     _bstr_t
    ColumnDelimeter, _bstr_t RowDelimeter, _bstr_t NullExpr );

HRESULT Move( long NumRecords, const _variant_t & Start =
    vtMissing );

HRESULT MoveFirst( );
HRESULT MoveLast( );
HRESULT MoveNext( );
HRESULT MovePrevious( );

_RecordsetPtr NextRecordset( VARIANT * RecordsAffected );

HRESULT Open( const _variant_t & Source, const _variant_t &
    ActiveConnection, enum CursorTypeEnum CursorType, enum LockTypeEnum
    LockType, long Options );

HRESULT Requery( long Options );

HRESULT Update( const _variant_t & Fields = vtMissing, const
    _variant_t &     Values = vtMissing );

HRESULT UpdateBatch( enum AffectEnum AffectRecords );

HRESULT Resync( enum AffectEnum AffectRecords, enum
    ResyncEnum     ResyncValues );

HRESULT Save( const _variant_t & Destination, enum
    PersistFormatEnum     PersistFormat );

HRESULT Seek( const _variant_t & KeyValues, enum SeekEnum
    SeekOption );

VARIANT_BOOL Supports( enum CursorOptionEnum CursorOptions );

Properties

enum PositionEnum GetAbsolutePage( );
void PutAbsolutePage( enum PositionEnum pl );
__declspec(property(get=GetAbsolutePage,put=PutAbsolutePage)) enum
    PositionEnum AbsolutePage;

enum PositionEnum GetAbsolutePosition( );
void PutAbsolutePosition( enum PositionEnum pl );
__declspec(property(get=GetAbsolutePosition,put=PutAbsolutePosition))
    enum PositionEnum AbsolutePosition;

IDispatchPtr GetActiveCommand( );
__declspec(property(get=GetActiveCommand)) IDispatchPtr ActiveCommand;

void PutRefActiveConnection( IDispatch * pvar );
void PutActiveConnection( const _variant_t & pvar );
_variant_t GetActiveConnection( );

enum CursorLocationEnum GetCursorLocation( );
void PutCursorLocation( enum CursorLocationEnum plCursorLoc );
__declspec(property(get=GetCursorLocation,put=PutCursorLocation)) enum
    CursorLocationEnum CursorLocation;

VARIANT_BOOL GetBOF( );
__declspec(property(get=GetBOF)) VARIANT_BOOL BOF;

VARIANT_BOOL GetEndOfFile( ); // Actually, GetEOF. Renamed in #import.
__declspec(property(get=GetEndOfFile)) VARIANT_BOOL EndOfFile;

_variant_t GetBookmark( );
void PutBookmark( const _variant_t & pvBookmark );
__declspec(property(get=GetBookmark,put=PutBookmark)) _variant_t
    Bookmark;

long GetCacheSize( );
void PutCacheSize( long pl );
__declspec(property(get=GetCacheSize,put=PutCacheSize)) long
    CacheSize;

enum CursorTypeEnum GetCursorType( );
void PutCursorType( enum CursorTypeEnum plCursorType );
__declspec(property(get=GetCursorType,put=PutCursorType)) enum
    CursorTypeEnum CursorType;

_bstr_t GetDataMember( );
void PutDataMember( _bstr_t pbstrDataMember );
__declspec(property(get=GetDataMember,put=PutDataMember)) _bstr_t
    DataMember;

IUnknownPtr GetDataSource( );
void PutRefDataSource( IUnknown * ppunkDataSource );
__declspec(property(get=GetDataSource,put=PutRefDataSource)) IUnknownPtr
    DataSource;

enum EditModeEnum GetEditMode( );
__declspec(property(get=GetEditMode)) enum EditModeEnum EditMode;

FieldsPtr GetFields( );
__declspec(property(get=GetFields)) FieldsPtr Fields;

_variant_t GetFilter( );
void PutFilter( const _variant_t & Criteria );
__declspec(property(get=GetFilter,put=PutFilter)) _variant_t Filter;

_bstr_t GetIndex( );
void PutIndex( _bstr_t pbstrIndex );
__declspec(property(get=GetIndex,put=PutIndex)) _bstr_t Index;

enum LockTypeEnum GetLockType( );
void PutLockType( enum LockTypeEnum plLockType );
__declspec(property(get=GetLockType,put=PutLockType)) enum LockTypeEnum
    LockType;

enum MarshalOptionsEnum GetMarshalOptions( );
void PutMarshalOptions( enum MarshalOptionsEnum peMarshal );
__declspec(property(get=GetMarshalOptions,put=PutMarshalOptions)) enum
    MarshalOptionsEnum MarshalOptions;

long GetMaxRecords( );
void PutMaxRecords( long plMaxRecords );
__declspec(property(get=GetMaxRecords,put=PutMaxRecords)) long
    MaxRecords;

long GetPageCount( );
__declspec(property(get=GetPageCount)) long PageCount;

long GetPageSize( );
void PutPageSize( long pl );
__declspec(property(get=GetPageSize,put=PutPageSize)) long PageSize;

long GetRecordCount( );
__declspec(property(get=GetRecordCount)) long RecordCount;

_bstr_t GetSort( );
void PutSort( _bstr_t Criteria );
__declspec(property(get=GetSort,put=PutSort)) _bstr_t Sort;

void PutRefSource( IDispatch * pvSource );
void PutSource( _bstr_t pvSource );
_variant_t GetSource( );

long GetState( );
__declspec(property(get=GetState)) long State;

long GetStatus( );
__declspec(property(get=GetStatus)) long Status;

VARIANT_BOOL GetStayInSync( );
void PutStayInSync( VARIANT_BOOL pbStayInSync );
__declspec(property(get=GetStayInSync,put=PutStayInSync)) VARIANT_BOOL
    StayInSync;

请参阅

Recordset 对象


Stream（使用 #import 的 Visual C++ 语法索引）

方法

HRESULT Cancel( );

HRESULT Close( );

HRESULT CopyTo( struct _Stream * DestStream, int CharNumber );

HRESULT Flush( );

HRESULT LoadFromFile( _bstr_t FileName );

HRESULT Open( const _variant_t & Source, enum
    ConnectModeEnum Mode, enum     StreamOpenOptionsEnum Options, _bstr_t
    UserName, _bstr_t Password );

_variant_t Read( long NumBytes );

_bstr_t ReadText( long NumChars );

HRESULT SaveToFile( _bstr_t FileName, enum SaveOptionsEnum
    Options );

HRESULT SetEOS( );

HRESULT SkipLine( );

HRESULT Write( const _variant_t & Buffer );

HRESULT WriteText( _bstr_t Data, enum StreamWriteEnum
    Options );

Properties

_bstr_t GetCharset( );
void PutCharset( _bstr_t pbstrCharset );
__declspec(property(get=GetCharset,put=PutCharset)) _bstr_t Charset;

VARIANT_BOOL GetEOS( );
__declspec(property(get=GetEOS)) VARIANT_BOOL EOS;

enum LineSeparatorEnum GetLineSeparator( );
void PutLineSeparator( enum LineSeparatorEnum pLS );
__declspec(property(get=GetLineSeparator,put=PutLineSeparator)) enum
    LineSeparatorEnum LineSeparator;

enum ConnectModeEnum GetMode( );
void PutMode( enum ConnectModeEnum pMode );
__declspec(property(get=GetMode,put=PutMode)) enum ConnectModeEnum Mode;

long GetPosition( );
void PutPosition( long pPos );
__declspec(property(get=GetPosition,put=PutPosition)) long Position;

long GetSize( );
__declspec(property(get=GetSize)) long Size;

enum ObjectStateEnum GetState( );
__declspec(property(get=GetState)) enum ObjectStateEnum State;

enum StreamTypeEnum GetType( );
void PutType( enum StreamTypeEnum ptype );
__declspec(property(get=GetType,put=PutType)) enum StreamTypeEnum Type;

请参阅

Stream 对象


ConnectionEvents（使用 #import 的 Visual C++ 语法索引）

事件

HRESULT InfoMessage( struct Error * pError, enum
    EventStatusEnum *     adStatus, struct _Connection * pConnection );

HRESULT BeginTransComplete( long TransactionLevel,
    struct Error * pError, enum EventStatusEnum * adStatus, struct
    _Connection * pConnection );

HRESULT CommitTransComplete( struct Error *
    pError, enum EventStatusEnum     * adStatus, struct _Connection *
    pConnection );

HRESULT RollbackTransComplete( struct Error *
    pError, enum     EventStatusEnum * adStatus, struct _Connection *
    pConnection );

HRESULT WillExecute( BSTR * Source, enum
    CursorTypeEnum * CursorType,
    enum LockTypeEnum * LockType, long * Options, enum EventStatusEnum *
    adStatus, struct _Command * pCommand, struct _Recordset * pRecordset,
    struct _Connection * pConnection );

HRESULT ExecuteComplete( long RecordsAffected, struct
    Error * pError,     enum EventStatusEnum * adStatus, struct _Command
    * pCommand, struct     _Recordset * pRecordset, struct _Connection *
    pConnection );

HRESULT WillConnect( BSTR * ConnectionString, BSTR *
    UserID, BSTR *     Password, long * Options, enum EventStatusEnum *
    adStatus, struct     _Connection * pConnection );

HRESULT ConnectComplete( struct Error *
    pError, enum EventStatusEnum *     adStatus, struct _Connection *
    pConnection );

HRESULT Disconnect( enum EventStatusEnum *
    adStatus, struct _Connection *     pConnection );


RecordsetEvents（使用 #import 的 Visual C++ 语法索引）

事件

HRESULT WillChangeField( long cFields, const
    _variant_t & Fields, enum     EventStatusEnum * adStatus, struct
    _Recordset * pRecordset );

HRESULT FieldChangeComplete( long cFields, const
    _variant_t & Fields,     struct Error * pError, enum EventStatusEnum
    * adStatus, struct     _Recordset * pRecordset );

HRESULT WillChangeRecord( enum EventReasonEnum
    adReason, long cRecords,     enum EventStatusEnum * adStatus, struct
    _Recordset * pRecordset );

HRESULT RecordChangeComplete( enum EventReasonEnum
    adReason, long     cRecords, struct Error * pError, enum
    EventStatusEnum * adStatus,     struct _Recordset * pRecordset );

HRESULT WillChangeRecordset( enum EventReasonEnum
    adReason, enum     EventStatusEnum * adStatus, struct _Recordset *
    pRecordset );

HRESULT RecordsetChangeComplete( enum
    EventReasonEnum adReason, struct     Error * pError, enum
    EventStatusEnum * adStatus, struct _Recordset *     pRecordset );

HRESULT WillMove( enum EventReasonEnum adReason, enum
    EventStatusEnum *     adStatus, struct _Recordset * pRecordset );

HRESULT MoveComplete( enum EventReasonEnum adReason, struct
    Error *     pError, enum EventStatusEnum * adStatus, struct
    _Recordset * pRecordset );

HRESULT EndOfRecordset( VARIANT_BOOL * fMoreData, enum
    EventStatusEnum *     adStatus, struct _Recordset * pRecordset );

HRESULT FetchProgress( long Progress, long MaxProgress,
    enum     EventStatusEnum * adStatus, struct _Recordset * pRecordset );

HRESULT FetchComplete( struct Error * pError, enum
    EventStatusEnum *     adStatus, struct _Recordset * pRecordset );


ADO/WFC 语法索引

“ADO 语言参考”以 Microsoft Visual Basic 编程语言为例来说明 ADO 方法和属性语法。本索引是基于 Microsoft Visual J++ 和 ADO for Windows Foundation Classes (ADO/WFC) 对“ADO 语言参考”主题的交叉引用。当出现语法差异时，请以本索引中的函数为主，而不是语言参考主题中的语法列表。

下列元素的方法和属性语法列表：

ActiveX 数据对象

  • ADO 集合
  • Command 对象
  • Connection 对象
  • Error 对象
  • Field 对象
  • Parameter 对象
  • Recordset 对象

远程数据服务

  • DataSpace
  • ObjectProxy

请参阅

ADO 事件模型、同步和异步操作 | ADO for Windows Foundation Classes | ActiveX Data Objects 开始页


集合（ADO/WFC 语法）

包 com.ms.wfc.data

Parameters

方法

public void append(com.ms.wfc.data.Parameter param)
public void delete(int n)
public void delete(String s)
public void refresh()
public Parameter getItem(int n)
public Parameter getItem(String s)

Properties

public int getCount()

Fields

方法

public void append(String name, int type)
public void append(String name, int type, int definedSize)
public void append(String name, int type, int definedSize, int attrib)
public void delete(int n)
public void delete(String s)
public void refresh()
public com.ms.wfc.data.Field getItem(int n)
public com.ms.wfc.data.Field getItem(String s)

Properties

public int getCount()

Errors

方法

public void clear()
public void refresh()
public com.ms.wfc.data.Error getItem(int n)
public com.ms.wfc.data.Error getItem(String s)

Properties

public int getCount()

请参阅

Errors 集合 | Fields 集合 | Parameters 集合


Command（ADO/WFC 语法）

包 com.ms.wfc.data

构造函数

public Command()
public Command(String commandtext)

方法

public void cancel()
public com.ms.wfc.data.Parameter createParameter(String
    Name, int Type, int Direction, int Size, Object Value)
public Recordset execute()
public Recordset execute(Object[] parameters)
public Recordset execute(Object[] parameters, int options)
public int executeUpdate(Object[] parameters)
public int executeUpdate(Object[] parameters, int options)
public int executeUpdate()

executeUpdate 方法是一个特例，它通过特定的参数调用基本 ADO execute 方法。因为 executeUpdate 方法不支持返回 Recordset 对象，所以 execute 方法的 options 参数通过 AdoEnums.ExecuteOptions.NORECORDS 进行修改。execute 方法完成后，其更新的 RecordsAffected 参数被传递回 executeUpdate 方法，最后以 int 值返回。

Properties

public com.ms.wfc.data.Connection getActiveConnection()
public void setActiveConnection(com.ms.wfc.data.Connection con)
public void setActiveConnection(String conString)
public String getCommandText()
public void setCommandText(String command)
public int getCommandTimeout()
public void setCommandTimeout(int timeout)
public int getCommandType()
public void setCommandType(int type)
public String getName()
public void setName(String name)
public boolean getPrepared()
public void setPrepared(boolean prepared)
public int getState()
public com.ms.wfc.data.Parameter getParameter(int n)
public com.ms.wfc.data.Parameter getParameter(String n)
public com.ms.wfc.data.Parameters getParameters()
public AdoProperties getProperties()

请参阅

Command 对象


Connection（ADO/WFC 语法）

包 com.ms.wfc.data

构造函数

public Connection()
public Connection(String connectionstring)

方法

public int beginTrans()
public void commitTrans()
public void rollbackTrans()
public void cancel()
public void close()
public com.ms.wfc.data.Recordset execute(String commandText)
public com.ms.wfc.data.Recordset execute(String commandText, int options)
public int executeUpdate(String commandText)
public int executeUpdate(String commandText, int options)

executeUpdate 方法是一个特例，它通过特定的参数调用基本 ADO execute 方法。因为 executeUpdate 方法不支持返回 Recordset 对象，所以 execute 方法的 options 参数通过 AdoEnums.ExecuteOptions.NORECORDS 进行修改。execute 方法完成后，其更新的 RecordsAffected 参数被传递回 executeUpdate 方法，最后以 int 值返回。

public void open()
public void open(String connectionString)
public void open(String connectionString, String userID)
public void open(String connectionString, String userID, String password)
public void open(String connectionString, String userID, String password, int options)
public Recordset openSchema(int schema, Object[]
    restrictions, String schemaID)
public Recordset openSchema(int schema)
public Recordset openSchema(int schema, Object[] restrictions)

Properties

public int getAttributes()
public void setAttributes(int attr)
public int getCommandTimeout()
public void setCommandTimeout(int timeout)
public String getConnectionString()
public void setConnectionString(String con)
public int getConnectionTimeout()
public void setConnectionTimeout(int timeout)
public int getCursorLocation()
public void setCursorLocation(int cursorLoc)
public String getDefaultDatabase()
public void setDefaultDatabase(String db)
public int getIsolationLevel()
public void setIsolationLevel(int level)
public int getMode()
public void setMode(int mode)
public String getProvider()
public void setProvider(String provider)
public int getState()
public String getVersion()
public AdoProperties getProperties()
public com.ms.wfc.data.Errors getErrors()

事件

有关 ADO/WFC 事件的详细信息，请参阅不同语言的 ADO 事件实例。

public void addOnBeginTransComplete(ConnectionEventHandler handler)
public void removeOnBeginTransComplete(ConnectionEventHandler handler)
public void addOnCommitTransComplete(ConnectionEventHandler handler)
public void removeOnCommitTransComplete(ConnectionEventHandler handler)
public void addOnConnectComplete(ConnectionEventHandler handler)
public void removeOnConnectComplete(ConnectionEventHandler handler)
public void addOnDisconnect(ConnectionEventHandler handler)
public void removeOnDisconnect(ConnectionEventHandler handler)
public void addOnExecuteComplete(ConnectionEventHandler handler)
public void removeOnExecuteComplete(ConnectionEventHandler handler)
public void addOnInfoMessage(ConnectionEventHandler handler)
public void removeOnInfoMessage(ConnectionEventHandler handler)
public void addOnRollbackTransComplete(ConnectionEventHandler handler)
public void removeOnRollbackTransComplete(ConnectionEventHandler handler)
public void addOnWillConnect(ConnectionEventHandler handler)
public void removeOnWillConnect(ConnectionEventHandler handler)
public void addOnWillExecute(ConnectionEventHandler handler)
public void removeOnWillExecute(ConnectionEventHandler handler)

请参阅

Connection 对象


DataSpace（ADO/WFC 语法）

DataSpace 类的 createObject 方法指定用于处理客户端应用程序请求 (progid) 的业务对象以及通信协议和服务器 (connection)。createObject 返回表示服务器的 ObjectProxy 对象。

包 com.ms.wfc.data

构造函数

public DataSpace()

方法

public static ObjectProxy DataSpace.createObject(String
    progid, String connection)

Properties

public static int getInternetTimeout()
public static void setInternetTimeout(int plInetTimeout)

请参阅

DataSpace 对象 (RDS)


Error（ADO/WFC 语法）

包 com.ms.wfc.data

Properties

public String getDescription()
public int getNativeError()
public int getNumber()
public String getSource()
public String getSQLState()

请参阅

Error 对象


Field（ADO/WFC 语法）

包 com.ms.wfc.data

方法

public void appendChunk(byte[] bytes)
public void appendChunk(char[] chars)
public void appendChunk(String chars)
public byte[] getByteChunk(int len)
public char[] getCharChunk(int len)
public String getStringChunk(int len)

Properties

public int getActualSize()
public int getAttributes()
public void setAttributes(int pl)
public com.ms.com.IUnknown getDataFormat()
public void setDataFormat(com.ms.com.IUnknown format)

（有关 com.ms.wfc.data.IDataFormat 接口的详细信息，请参阅 Microsoft Visual J++ WFC 参考文档。）

public int getDefinedSize()
public void setDefinedSize(int pl)
public String getName()
public int getNumericScale()
public void setNumericScale(byte pbNumericScale)
public Variant getOriginalValue()
public int getPrecision()
public void setPrecision(byte pbPrecision)
public int getType()
public void setType(int pDataType)
public Variant getUnderlyingValue()
public Variant getValue()
public void setValue(Variant value)
public AdoProperties getProperties()

Field 存取方法

Field 对象的 Value 属性获得或设置该对象的内容。对象的内容表示为 VARIANT 对象类型，它可以分配一个值和多种数据类型中的任意一种。

ADO/WFC 使用 getValue 方法和 setValue 方法实现 Value 属性，getValue 方法返回 VARIANT 对象，而 setValue 方法则把 VARIANT 用作参数。VARIANT 在某些语言（例如 Microsoft Visual Basic）中效率很高。但是，您可以在 Microsoft Visual J++ 中通过使用原生 Java 数据类型获得更高的性能。

除了 Value 属性以外，ADO/WFC 还提供了“存取”方法，使用 Java 数据类型来获得和设置 Field 对象的内容。这些方法的大多数名称都具有 get DataType 或 set DataType 格式。

有两点例外须加以注意：getObject 方法之一返回强制到指定类的对象。不存在 getNull 属性；但存在 isNull 属性，该属性返回的 Boolean 值可指示字段是否为 Null。

public native boolean getBoolean();
public void setBoolean(boolean v)
public native byte getByte();
public void setByte(byte v)
public native byte[] getBytes();
public void setBytes(byte[] v)
public native double getDouble();
public void setDouble(double v)
public native float getFloat();
public void setFloat(float v)
public native int getInt();
public void setInt(int v)
public native long getLong();
public void setLong(long v)
public native short getShort();
public void setShort(short v)
public native String getString();
public void setString(String v)
public native boolean isNull();
public void setNull()
public Object getObject()
public Object getObject(Class c)
public void setObject(Object value)

请参阅

Field 对象


ObjectProxy（ADO/WFC 语法）

ObjectProxy 对象表示服务器，由 DataSpace 对象的 createObject 方法返回。ObjectProxy 类有一个 call 方法，可以在服务器上调用一个方法并返回由调用产生的对象。

包 com.ms.wfc.data

方法

Call 方法（ADO/WFC 语法）

在 ObjectProxy 所表示的服务器上调用一个方法。可选，方法参数可以作为对象数组传递。

语法

public Object ObjectProxy.call( String method )
public Object ObjectProxy.call( String method, Object[] args)

返回

对象
由调用方法产生的对象。

Parameters

ObjectProxy
表示服务器的 ObjectProxy 对象。
method
一个字符串，包含在服务器上调用的方法的名称。
args
可选。对象数组，是服务器上方法的参数。Java 数据类型被自动转换为适合服务器使用的数据类型。


Parameter（ADO/WFC 语法）

包 com.ms.wfc.data

构造函数

public Parameter()
public Parameter(String name)
public Parameter(String name, int type)
public Parameter(String name, int type, int dir)
public Parameter(String name, int type, int dir, int size)
public Parameter(String name, int type, int dir, int size, Object value)

方法

public void appendChunk(byte[] bytes)
public void appendChunk(char[] chars)
public void appendChunk(String chars)

Properties

public int getAttributes()
public void setAttributes(int attr)
public int getDirection()
public void setDirection(int dir)
public String getName()
public void setName(String name)
public int getNumericScale()
public void setNumericScale(int scale)
public int getPrecision()
public void setPrecision(int prec)
public int getSize()
public void setSize(int size)
public int getType()
public void setType(int type)
public com.ms.com.Variant getValue()
public void setValue(Object v)
public AdoProperties getProperties()

Parameter 存取方法

Parameter 对象的 Value 属性获得或设置该对象的内容。对象的内容表示为 VARIANT 对象类型，它可以分配一个值和多种数据类型中的任意一种。

ADO/WFC 使用 getValue 方法和 setValue 方法实现 Value 属性，getValue 方法返回 VARIANT 对象，而 setValue 方法则把 VARIANT 用作参数。VARIANT 在某些语言（例如 Microsoft Visual Basic）中效率很高。但是，您可以在 Microsoft Visual J++ 中通过使用原生 Java 数据类型获得更高的性能。

除了 Value 属性以外，ADO/WFC 还提供了“存取”方法，这种方法使用 Java 数据类型来获得和设置 Parameter 对象的内容。这些方法的大多数名称都具有 get DataType 或 set DataType 格式。

有一点例外须加以注意：不存在 getNull 属性；但存在 isNull 属性，该属性返回的 Boolean 值可指示字段是否为 Null。

public boolean getBoolean()
public void setBoolean(boolean v)
public byte getByte()
public void setByte(byte v)
public double getDouble()
public void setDouble(double v)
public float getFloat()
public void setFloat(float v)
public int getInt()
public void setInt(int v)
public long getLong()
public void setLong(long v)
public short getShort()
public void setShort(short v)
public String getString()
public void setString(String v)
public boolean isNull()
public void setNull()

请参阅

Parameter 对象


Recordset（ADO/WFC 语法）

包 com.ms.wfc.data

构造函数

public Recordset()
public Recordset(Object r)

方法

public void addNew(Object[] fieldList, Object[] valueList)
public void addNew(Object[] valueList)
public void addNew()
public void cancel()
public void cancelBatch(int affectRecords)
public void cancelBatch()
public void cancelUpdate()
public Object clone()
public Object clone(int lockType)
public void close()
public int compareBookmarks(Object bookmark1, Object bookmark2)
public void delete(int affectRecords)
public void delete()
public void find(String criteria)
public void find(String criteria, int SkipRecords)
public void find(String criteria, int SkipRecords, int searchDirection)
public void find(String criteria, int SkipRecords, int searchDirection, Object bmkStart)
public Object[][] getRows(int Rows, Object bmkStart, Object[] fieldList)
public void move(int numRecords)
public void move(int numRecords, Object bmkStart)
public void moveFirst()
public void moveLast()
public void moveNext()
public void movePrevious()
public Recordset nextRecordset()
public Recordset nextRecordset(int[] recordsAffected)
public void open()
public void open(Object source)
public void open(Object source, Object activeConnection)
public void open(Object source, Object activeConnection, int cursorType)
public void open(Object source, Object activeConnection, int cursorType,
                  int lockType)
public void open(Object source, Object activeConnection, int cursorType,
                  int lockType, int options)
public void requery()
public void requery(int options)
public void resync()
public void resync(int affectRecords, int resyncValues)
public void save(String fileName)
public void save(String fileName, int persistFormat)
public boolean supports(int cursorOptions)
public void update()
public void update(Object[] valueList)
public void update(Object[] fieldList, Object[] valueList)
public void updateBatch()
public void updateBatch(int affectRecords)

Properties

public int getAbsolutePage()
public void setAbsolutePage(int page)
public int getAbsolutePosition()
public void setAbsolutePosition(int pos)
public Command getActiveCommand()
public Connection getActiveConnection()
public void setActiveConnection(String conn)
public void setActiveConnection(com.ms.wfc.data.Connection c)
public boolean getBOF()
public boolean getEOF()
public Object getBookmark()
public void setBookmark(Object bmk)
public int getCacheSize()
public void setCacheSize(int size)
public int getCursorLocation()
public void setCursorLocation(int cursorLoc)
public int getCursorType()
public void setCursorType(int cursorType)
public String getDataMember()
public void setDataMember(String pbstrDataMember)
public Iunknown getDataSource()
public void setDataSource(IUnknown dataSource)
public int getEditMode()
public Object getFilter()
public void setFilter(Object filter)
public int getLockType()
public void setLockType(int lockType)
public int getMarshalOptions()
public void setMarshalOptions(int options)
public int getMaxRecords()
public void setMaxRecords(int maxRecords)
public int getPageCount()
public int getPageSize()
public void setPageSize(int pageSize)
public int getRecordCount()
public String getSort()
public void setSort(String criteria)
public String getSource()
public void setSource(String query)
public void setSource(com.ms.wfc.data.Command command)
public int getState()
public int getStatus()
public boolean getStayInSync()
public void setStayInSync(boolean pbStayInSync)
public com.ms.wfc.data.Field getField(int n)
public com.ms.wfc.data.Field getField(String n)
public com.ms.wfc.data.Fields getFields()
public AdoProperties getProperties()

事件

有关 ADO/WFC 事件的详细信息，请参阅不同语言的 ADO 事件实例。

public void addOnEndOfRecordset(RecordsetEventHandler handler)
public void removeOnEndOfRecordset(RecordsetEventHandler handler)
public void addOnFetchComplete(RecordsetEventHandler handler)
public void removeOnFetchComplete(RecordsetEventHandler handler)
public void addOnFetchProgress(RecordsetEventHandler handler)
public void removeOnFetchProgress(RecordsetEventHandler handler)
public void addOnFieldChangeComplete(RecordsetEventHandler handler)
public void removeOnFieldChangeComplete(RecordsetEventHandler handler)
public void addOnMoveComplete(RecordsetEventHandler handler)
public void removeOnMoveComplete(RecordsetEventHandler handler)
public void addOnRecordChangeComplete(RecordsetEventHandler handler)
public void removeOnRecordChangeComplete(RecordsetEventHandler handler)
public void addOnRecordsetChangeComplete(RecordsetEventHandler handler)
public void removeOnRecordsetChangeComplete(RecordsetEventHandler handler)
public void addOnWillChangeField(RecordsetEventHandler handler)
public void removeOnWillChangeField(RecordsetEventHandler handler)
public void addOnWillChangeRecord(RecordsetEventHandler handler)
public void removeOnWillChangeRecord(RecordsetEventHandler handler)
public void addOnWillChangeRecordset(RecordsetEventHandler handler)
public void removeOnWillChangeRecordset(RecordsetEventHandler handler)
public void addOnWillMove(RecordsetEventHandler handler)
public void removeOnWillMove(RecordsetEventHandler handler)

请参阅

Recordset 对象


ADO 代码范例

通过下列代码范例来学习如何使用 ADO 对象、方法、属性和事件。

注意 请将整个代码范例粘贴到代码编辑器中。如果只使用部分范例或者丢失了段落格式，范例可能无法正确运行。
  • Microsoft Visual Basic 中的 ADO 代码范例
  • Microsoft Visual Basic Scripting Edition 中的 ADO 代码范例
  • Microsoft Visual C++ 中的 ADO 代码范例
  • Microsoft Visual J++ 中的 ADO 代码范例
  • Microsoft JScript 中的 ADO 代码范例


Microsoft Visual Basic 中的 ADO 代码范例

通过下列代码范例来学习用 Visual Basic 编程时如何使用 ADO 方法、属性和事件。

注意 请将整个代码范例（从 Sub 到 End Sub）粘贴到代码编辑器中。如果只使用部分范例或者丢失了段落格式，范例可能无法正确运行。

方法

  • AddNew 方法范例
  • Append 和 CreateParameter 方法范例
  • AppendChunk 和 GetChunk 方法范例
  • BeginTrans、CommitTrans 和 RollbackTrans 方法范例
  • Cancel 方法范例
  • Clone 方法范例
  • CompareBookmarks 方法范例
  • ConvertToString 方法范例
  • CopyRecord、CopyTo 和 SaveToFile 方法范例
  • CreateRecordset 方法范例
  • Delete 方法范例
  • DeleteRecord 和 MoveRecord 方法范例
  • Execute、Requery 和 Clear 方法范例
  • Find 方法范例
  • GetRows 方法范例
  • GetString 方法范例
  • SkipLine 方法、EOS 和 LineSeparator 属性范例
  • Move 方法范例
  • MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法范例
  • NextRecordset 方法范例
  • Open 和 Close 方法范例
  • OpenSchema 方法范例
  • Read、ReadText、Write 和 WriteText 方法范例
  • Refresh 方法范例
  • Resync 方法范例
  • Save 和 Open 方法范例
  • Seek 方法和 Index 属性范例
  • Supports 方法范例
  • Update 和 CancelUpdate 方法范例
  • UpdateBatch 和 CancelBatch 方法范例

Properties

  • AbsolutePage、PageCount 和 PageSize 属性范例
  • AbsolutePosition 和 CursorLocation 属性范例
  • ActiveCommand 属性范例
  • ActiveConnection、CommandText、CommandTimeout、CommandType、Size 和 Direction 属性范例
  • ActualSize 和 DefinedSize 属性范例
  • Attributes 和 Name 属性范例
  • BOF、EOF 和 Bookmark 属性范例
  • CacheSize 属性范例
  • ConnectionString、ConnectionTimeout 和 State 属性范例
  • Count 属性范例
  • CursorType、LockType 和 EditMode 属性范例
  • Description、HelpContext、HelpFile、NativeError、Number、Source 和 SQLState 属性范例
  • EOS 和 LineSeparator 属性、SkipLine 方法范例
  • Filter 和 RecordCount 属性范例
  • IsolationLevel 和 Mode 属性范例
  • Item 属性范例
  • MarshalOptions 属性范例
  • MaxRecords 属性范例
  • NumericScale 和 Precision 属性范例
  • Optimize 属性范例
  • OriginalValue 和 UnderlyingValue 属性范例
  • Prepared 属性范例
  • Provider 和 DefaultDatabase 属性范例
  • Sort 属性范例
  • Source 属性范例
  • State 属性范例
  • Status 属性范例
  • StayInSync 属性范例
  • Type 属性范例 (Field)
  • Type 属性范例 (Property)
  • Value 属性范例
  • Version 属性范例

请参阅

Microsoft Visual Basic Scripting Edition 中的 ADO 代码范例 | Microsoft Visual C++ 中的 ADO 代码范例 | Microsoft Visual J++ 中的 ADO 代码范例


AbsolutePage、PageCount 和 PageSize 属性范例 (VB)

'BeginAbsolutePageVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    'recordset and connection variables
    Dim rstEmployees As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim strSQL As String
        'record variables
    Dim strMessage As String
    Dim intPage As Integer
    Dim intPageCount As Integer
    Dim intRecord As Integer

    'Open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open employee recordset
    ' Use client cursor to enable AbsolutePosition property
    Set rstEmployees = New ADODB.Recordset
    strSQL = "employee"
    rstEmployees.Open strSQL, strCnxn, adUseClient, adLockReadOnly, adCmdTable

    ' Display names and hire dates, five records at a time
    rstEmployees.PageSize = 5
    intPageCount = rstEmployees.PageCount
    For intPage = 1 To intPageCount
        rstEmployees.AbsolutePage = intPage
        strMessage = ""
        For intRecord = 1 To rstEmployees.PageSize
            strMessage = strMessage & _
                rstEmployees!fname & " " & _
                rstEmployees!lname & " " & _
                rstEmployees!hire_date & vbCr
            rstEmployees.MoveNext
            If rstEmployees.EOF Then Exit For
        Next intRecord
        MsgBox strMessage
    Next intPage

    ' clean up
    rstEmployees.Close
    Cnxn.Close
    Set rstEmployees = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstEmployees Is Nothing Then
        If rstEmployees.State = adStateOpen Then rstEmployees.Close
    End If
    Set rstEmployees = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndAbsolutePageVB

请参阅

AbsolutePage 属性 | PageCount 属性 | PageSize 属性 | Recordset 对象


AbsolutePosition 和 CursorLocation 属性范例 (VB)

本范例演示 AbsolutePosition 属性如何跟踪循环的进度。该循环用于枚举 Recordset 中的所有记录。范例中使用了 CursorLocation 属性，通过将游标设置为客户端游标来启用 AbsolutePosition 属性。

'BeginAbsolutePositionVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    'recordset and connection variables
    Dim rstEmployees As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim strSQL As String
        'record variables
    Dim strMessage As String

    'Open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open Employee recordset with
    ' Client-side cursor to enable AbsolutePosition property
    Set rstEmployees = New ADODB.Recordset
    strSQL = "employee"
    rstEmployees.Open strSQL, strCnxn, adUseClient, adLockReadOnly, adCmdTable

    ' Enumerate Recordset
    Do While Not rstEmployees.EOF
        ' Display current record information
        strMessage = "Employee: " & rstEmployees!lname & vbCr & _
            "(record " & rstEmployees.AbsolutePosition & _
            " of " & rstEmployees.RecordCount & ")"
        If MsgBox(strMessage, vbOKCancel) = vbCancel Then Exit Do
        rstEmployees.MoveNext
    Loop

    ' clean up
    rstEmployees.Close
    Cnxn.Close
    Set rstEmployees = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
   ' clean up
    If Not rstEmployees Is Nothing Then
        If rstEmployees.State = adStateOpen Then rstEmployees.Close
    End If
    Set rstEmployees = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndAbsolutePositionVB

请参阅

AbsolutePosition 属性 | CursorLocation 属性 | Recordset 对象


ActiveCommand 属性范例 (VB)

本范例演示 ActiveCommand 属性。

向子例程提供一个 Recordset 对象，该对象的 ActiveCommand 属性用于显示创建 Recordset 的命令文本和参数。

'BeginActiveCommandVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

        'recordset and connection variables
    Dim cmd As ADODB.Command
    Dim rst As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
        'record variables
    Dim strPrompt As String
    Dim strName As String

    Set Cnxn = New ADODB.Connection
    Set cmd = New ADODB.Command

    strPrompt = "Enter an author's name (e.g., Ringer): "
    strName = Trim(InputBox(strPrompt, "ActiveCommandX Example"))
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"

        'create SQL command string
    cmd.CommandText = "SELECT * FROM Authors WHERE au_lname = ?"
    cmd.Parameters.Append cmd.CreateParameter("LastName", adChar, adParamInput, 20, strName)

    Cnxn.Open strCnxn
    cmd.ActiveConnection = Cnxn

        'create the recordset by executing command string
    Set rst = cmd.Execute(, , adCmdText)
        'see the results
    Call ActiveCommandXprint(rst)

    ' clean up
    Cnxn.Close
    Set rst = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rst Is Nothing Then
        If rst.State = adStateOpen Then rst.Close
    End If
    Set rst = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndActiveCommandVB

对 ActiveCommandXprint 例程仅提供一个 Recordset 对象，而例程必须打印创建 Recordset 的命令文本和参数。由于 Recordset 对象的 ActiveCommand 属性输出相关的 Command 对象，所以可以这么做。

Command 对象的 CommandText 属性输出创建 Recordset 的参数化命令。Command 对象的 Parameters 集合输出替代命令参数占位符（“?”）的值。

最后将打印错误消息或作者的名字和 ID。

'BeginActiveCommandPrintVB
Public Sub ActiveCommandXprint(rstp As ADODB.Recordset)

    Dim strName As String

    strName = rstp.ActiveCommand.Parameters.Item("LastName").Value

    Debug.Print "Command text = '"; rstp.ActiveCommand.CommandText; "'"
    Debug.Print "Parameter = '"; strName; "'"

    If rstp.BOF = True Then
       Debug.Print "Name = '"; strName; "', not found."
    Else
       Debug.Print "Name = '"; rstp!au_fname; " "; rstp!au_lname; _
             "', author ID = '"; rstp!au_id; "'"
    End If

    rstp.Close
    Set rstp = Nothing
End Sub

'EndActiveCommandPrintVB 请参阅

ActiveCommand 属性 | Command 对象 | Recordset 对象


ActiveConnection、CommandText、CommandTimeout、CommandType、Size 和 Direction 属性范例 (VB)

本范例使用 ActiveConnection、CommandText、CommandTimeout、CommandType、Size 和 Direction 属性来执行存储过程。

'BeginActiveConnectionVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    'recordset, command and connection variables
    Dim Cnxn As ADODB.Connection
    Dim cmdByRoyalty As ADODB.Command
    Dim prmByRoyalty As ADODB.Parameter
    Dim rstByRoyalty As ADODB.Recordset
    Dim rstAuthors As ADODB.Recordset
    Dim strCnxn As String
    Dim strSQLAuthors As String
    Dim strSQLByRoyalty As String
     'record variables
    Dim intRoyalty As Integer
    Dim strAuthorID As String

    ' Define a command object for a stored procedure
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    Set cmdByRoyalty = New ADODB.Command
    Set cmdByRoyalty.ActiveConnection = Cnxn
    ' Set the criteria
    strSQLByRoyalty = "byroyalty"
    cmdByRoyalty.CommandText = strSQLByRoyalty
    cmdByRoyalty.CommandType = adCmdStoredProc
    cmdByRoyalty.CommandTimeout = 15

    ' Define the stored procedure's input parameter
    intRoyalty = Trim(InputBox("Enter royalty:"))
    Set prmByRoyalty = New ADODB.Parameter
    prmByRoyalty.Type = adInteger
    prmByRoyalty.Size = 3
    prmByRoyalty.Direction = adParamInput
    prmByRoyalty.Value = intRoyalty

    cmdByRoyalty.Parameters.Append prmByRoyalty

    ' Create a recordset by executing the command.
    Set rstByRoyalty = cmdByRoyalty.Execute()

    ' Open the Authors Table to get author names for display
    Set rstAuthors = New ADODB.Recordset
    strSQLAuthors = "Authors"

    'rstAuthors.Open strSQLAuthors, strCnxn, , , adCmdTable
    rstAuthors.Open strSQLAuthors, strCnxn, adOpenForwardOnly, adLockReadOnly, adCmdTable
    'the above two lines of code are identical as the default values for
    'CursorType and LockType arguments match those shown

    ' Print the recordset and add author names from Table
    Debug.Print "Authors with " & intRoyalty & _
       " percent royalty"

    Do Until rstByRoyalty.EOF
        strAuthorID = rstByRoyalty!au_id
        Debug.Print , rstByRoyalty!au_id & ", ";
        rstAuthors.Filter = "au_id = '" & strAuthorID & "'"
        Debug.Print rstAuthors!au_fname & " " & _
            rstAuthors!au_lname
        rstByRoyalty.MoveNext
    Loop

    ' clean up
    rstAuthors.Close
    rstByRoyalty.Close
    Cnxn.Close
    Set rstAuthors = Nothing
    Set rstByRoyalty = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstAuthors Is Nothing Then
        If rstAuthors.State = adStateOpen Then rstAuthors.Close
    End If
    Set rstAuthors = Nothing

    If Not rstByRoyalty Is Nothing Then
        If rstByRoyalty.State = adStateOpen Then rstByRoyalty.Close
    End If
    Set rstByRoyalty = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndActiveConnectionVB

请参阅

ActiveCommand 属性 | Command 对象 | CommandText 属性 | CommandTimeout 属性 | CommandType 属性 | Connection 对象 | Direction 属性 | Parameter 对象 | Record 对象 | Recordset 对象 | Size 属性


ActualSize 和 DefinedSize 属性范例 (VB)

本范例使用 ActualSize 和 DefinedSize 属性显示字段的定义大小和实际大小。

'BeginActualSizeVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    'recordset and connection variables
    Dim rstStores As ADODB.Recordset
    Dim SQLStores As String
    Dim strCnxn As String
     'record variables
    Dim strMessage As String

    ' Open a recordset for the Stores table
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Northwind';Integrated Security='SSPI';"
    Set rstStores = New ADODB.Recordset

    SQLStores = "Suppliers"
    rstStores.Open SQLStores, strCnxn, adOpenForwardOnly, adLockReadOnly, adCmdTable
    'the above two lines of code are identical as the default values for
    'CursorType and LockType arguments match those indicated

    ' Loop through the recordset displaying the contents
    ' of the store_name field, the field's defined size,
    ' and its actual size.
    rstStores.MoveFirst

    Do Until rstStores.EOF
        strMessage = "Company name: " & rstStores!CompanyName & _
        vbCrLf & "Defined size: " & _
        rstStores!CompanyName.DefinedSize & _
        vbCrLf & "Actual size: " & _
        rstStores!CompanyName.ActualSize & vbCrLf

        MsgBox strMessage, vbOKCancel, "ADO ActualSize Property (Visual Basic)"
        rstStores.MoveNext
    Loop

    ' clean up
    rstStores.Close
    Set rstStores = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstStores Is Nothing Then
        If rstStores.State = adStateOpen Then rstStores.Close
    End If
    Set rstStores = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndActualSizeVB

请参阅

ActualSize 属性 | DefinedSize 属性 | Field 对象


AddNew 方法范例 (VB)

本范例使用 AddNew 方法来创建具有指定名称的新记录。

'BeginAddNewVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    'recordset and connection variables
    Dim Cnxn As ADODB.Connection
    Dim rstEmployees As ADODB.Recordset
    Dim strCnxn As String
    Dim strSQL As String
     'record variables
    Dim strID As String
    Dim strFirstName As String
    Dim strLastName As String
    Dim blnRecordAdded As Boolean

    ' Open a connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Northwind';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open Employees Table with a cursor that allows updates
    Set rstEmployees = New ADODB.Recordset
    strSQL = "Employees"
    rstEmployees.Open strSQL, strCnxn, adOpenKeyset, adLockOptimistic, adCmdTable

    ' Get data from the user
    strFirstName = Trim(InputBox("Enter first name:"))
    strLastName = Trim(InputBox("Enter last name:"))

    ' Proceed only if the user actually entered something
    ' for both the first and last names
    If strFirstName <> "" And strLastName <> "" Then

        rstEmployees.AddNew
        rstEmployees!firstname = strFirstName
        rstEmployees!LastName = strLastName
        rstEmployees.Update
        blnRecordAdded = True

        ' Show the newly added data
        MsgBox "New record: " & rstEmployees!EmployeeId & " " & _
        rstEmployees!firstname & " " & rstEmployees!LastName

    Else
        MsgBox "Please enter a first name and last name."
    End If

    ' Delete the new record because this is a demonstration
    Cnxn.Execute "DELETE FROM Employees WHERE EmployeeID = '" & strID & "'"

    ' clean up
    rstEmployees.Close
    Cnxn.Close
    Set rstEmployees = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
   ' clean up
    If Not rstEmployees Is Nothing Then
        If rstEmployees.State = adStateOpen Then rstEmployees.Close
    End If
    Set rstEmployees = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndAddNewVB

请参阅

AddNew 方法 | Recordset 对象


Append 和 CreateParameter 方法范例 (VB)

本范例使用 Append 和 CreateParameter 方法执行具有输入参数的存储过程。

'BeginAppendVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    'recordset, command and connection variables
    Dim Cnxn As ADODB.Connection
    Dim cmdByRoyalty As ADODB.Command
    Dim prmByRoyalty As ADODB.Parameter
    Dim rstByRoyalty As ADODB.Recordset
    Dim rstAuthors As ADODB.Recordset
    Dim strCnxn As String
    Dim strSQLAuthors As String
    Dim strSQLByRoyalty As String
     'record variables
    Dim intRoyalty As Integer
    Dim strAuthorID As String

    ' Open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open command object with one parameter
    Set cmdByRoyalty = New ADODB.Command
    cmdByRoyalty.CommandText = "byroyalty"
    cmdByRoyalty.CommandType = adCmdStoredProc

    ' Get parameter value and append parameter
    intRoyalty = Trim(InputBox("Enter royalty:"))
    Set prmByRoyalty = cmdByRoyalty.CreateParameter("percentage", adInteger, adParamInput)
    cmdByRoyalty.Parameters.Append prmByRoyalty
    prmByRoyalty.Value = intRoyalty

    ' Create recordset by executing the command
    Set cmdByRoyalty.ActiveConnection = Cnxn
    Set rstByRoyalty = cmdByRoyalty.Execute

    ' Open the Authors Table to get author names for display
    ' and set cursor client-side
    Set rstAuthors = New ADODB.Recordset
    strSQLAuthors = "Authors"
    rstAuthors.Open strSQLAuthors, Cnxn, adUseClient, adLockOptimistic, adCmdTable

    ' Print recordset adding author names from Authors table
    Debug.Print "Authors with " & intRoyalty & " percent royalty"

    Do Until rstByRoyalty.EOF
        strAuthorID = rstByRoyalty!au_id
        Debug.Print "   " & rstByRoyalty!au_id & ", ";
        rstAuthors.Filter = "au_id = '" & strAuthorID & "'"
        Debug.Print rstAuthors!au_fname & " " & rstAuthors!au_lname
        rstByRoyalty.MoveNext
    Loop

    ' clean up
    rstByRoyalty.Close
    rstAuthors.Close
    Cnxn.Close
    Set rstByRoyalty = Nothing
    Set rstAuthors = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstByRoyalty Is Nothing Then
        If rstByRoyalty.State = adStateOpen Then rstByRoyalty.Close
    End If
    Set rstByRoyalty = Nothing

    If Not rstAuthors Is Nothing Then
        If rstAuthors.State = adStateOpen Then rstAuthors.Close
    End If
    Set rstAuthors = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndAppendVB

请参阅

Append 方法 | CreateParameter 方法 | Field 对象 | Fields 集合 | Parameter 对象


AppendChunk 和 GetChunk 方法范例 (VB)

本范例使用 AppendChunk 和 GetChunk 方法用其他记录中的数据填充图像字段。

'BeginAppendChunkVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    'recordset and connection variables
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim rstPubInfo As ADODB.Recordset
    Dim strSQLPubInfo As String
     'record variables
    Dim strPubID As String
    Dim strPRInfo As String
    Dim lngOffset As Long
    Dim lngLogoSize As Long
    Dim varLogo As Variant
    Dim varChunk As Variant
    Dim strMsg As String

    Const conChunkSize = 100

    ' Open a connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open the pub_info table with a cursor that allows updates
    Set rstPubInfo = New ADODB.Recordset
    strSQLPubInfo = "pub_info"
    rstPubInfo.Open strSQLPubInfo, Cnxn, adOpenKeyset, adLockOptimistic, adCmdTable

    ' Prompt for a logo to copy
    strMsg = "Available logos are : " & vbCr & vbCr
    Do While Not rstPubInfo.EOF
        strMsg = strMsg & rstPubInfo!pub_id & vbCr & _
            Left(rstPubInfo!pr_info, InStr(rstPubInfo!pr_info, ",") - 1) & _
            vbCr & vbCr
        rstPubInfo.MoveNext
    Loop

    strMsg = strMsg & "Enter the ID of a logo to copy:"
    strPubID = InputBox(strMsg)

    ' Copy the logo to a variable in chunks
    rstPubInfo.Filter = "pub_id = '" & strPubID & "'"
    lngLogoSize = rstPubInfo!logo.ActualSize
    Do While lngOffset < lngLogoSize
        varChunk = rstPubInfo!logo.GetChunk(conChunkSize)
        varLogo = varLogo & varChunk
        lngOffset = lngOffset + conChunkSize
    Loop

    ' Get data from the user
    strPubID = Trim(InputBox("Enter a new pub ID" & _
                             " [must be > 9899 & < 9999]:"))

    strPRInfo = Trim(InputBox("Enter descriptive text:"))

    ' Add the new publisher to the publishers table to avoid
    ' getting an error due to foreign key constraint
    Cnxn.Execute "INSERT publishers(pub_id, pub_name) VALUES('" & _
                   strPubID & "','Your Test Publisher')"

    ' Add a new record, copying the logo in chunks
    rstPubInfo.AddNew
    rstPubInfo!pub_id = strPubID
    rstPubInfo!pr_info = strPRInfo

    lngOffset = 0 ' Reset offset
    Do While lngOffset < lngLogoSize
        varChunk = LeftB(RightB(varLogo, lngLogoSize - lngOffset), _
            conChunkSize)
        rstPubInfo!logo.AppendChunk varChunk
        lngOffset = lngOffset + conChunkSize
    Loop
    rstPubInfo.Update

    ' Show the newly added data
    MsgBox "New record: " & rstPubInfo!pub_id & vbCr & _
        "Description: " & rstPubInfo!pr_info & vbCr & _
        "Logo size: " & rstPubInfo!logo.ActualSize

    ' Delete new records because this is a demo
    rstPubInfo.Requery
    Cnxn.Execute "DELETE FROM pub_info " & _
        "WHERE pub_id = '" & strPubID & "'"

    Cnxn.Execute "DELETE FROM publishers " & _
        "WHERE pub_id = '" & strPubID & "'"

    ' clean up
    rstPubInfo.Close
    Cnxn.Close
    Set rstPubInfo = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
   ' clean up
    If Not rstPubInfo Is Nothing Then
        If rstPubInfo.State = adStateOpen Then rstPubInfo.Close
    End If
    Set rstPubInfo = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndAppendChunkVB

请参阅

AppendChunk 方法 | Field 对象 | GetChunk 方法 | Parameter 对象


Attributes 和 Name 属性范例 (VB)

本范例显示 Connection、Field 和 Property 对象的 Attributes 属性的值。该范例使用 Name 属性显示每个 Field 和 Property 对象的名称。

'BeginAttributesVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    'recordset and connection variables
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim rstEmployees As ADODB.Recordset
    Dim strSQLEmployee As String
     'record variables
    Dim adoField As ADODB.Field
    Dim adoProp As ADODB.Property

    ' Open connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Set Cnxn = New ADODB.Connection
    Cnxn.Open strCnxn

    ' Open recordset
    Set rstEmployees = New ADODB.Recordset
    strSQLEmployee = "employee"
    rstEmployees.Open strSQLEmployee, Cnxn, adOpenForwardOnly, adLockReadOnly, adCmdTable
    'the above two lines openign the recordset are identical as
    'the default values for CursorType and LockType arguments match those shown

    ' Display the attributes of the connection
    Debug.Print "Connection attributes = " & Cnxn.Attributes

    ' Display the property attributes of the Employee Table
    Debug.Print "Property attributes:"
    For Each adoProp In rstEmployees.Properties
        Debug.Print "   " & adoProp.Name & " = " & adoProp.Attributes
    Next adoProp

    ' Display the field attributes of the Employee Table
    Debug.Print "Field attributes:"
    For Each adoField In rstEmployees.Fields
       Debug.Print "   " & adoField.Name & " = " & adoField.Attributes
    Next adoField

    ' Display fields of the Employee Table which are NULLABLE
    Debug.Print "NULLABLE Fields:"
    For Each adoField In rstEmployees.Fields
        If CBool(adoField.Attributes And adFldIsNullable) Then
            Debug.Print "   " & adoField.Name
        End If
    Next adoField

    ' clean up
    rstEmployees.Close
    Cnxn.Close
    Set rstEmployees = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstEmployees Is Nothing Then
        If rstEmployees.State = adStateOpen Then rstEmployees.Close
    End If
    Set rstEmployees = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndAttributesVB

请参阅

Attributes 属性 | Connection 对象 | Field 对象 | Name 属性 | Property 对象


BeginTrans、CommitTrans 和 RollbackTrans 方法范例 (VB)

本范例更改数据库的 Titles 表中所有心理学书籍的类型。首先，BeginTrans 方法启动一个事务，将所有对 Titles 表做出的更改隔离，然后，CommitTrans 方法将保存更改。可使用 RollbackTrans 方法撤消用 Update 方法保存的更改。

'BeginBeginTransVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    'recordset and connection variables
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim rstTitles As ADODB.Recordset
    Dim strSQLTitles As String
    'record variables
    Dim strTitle As String
    Dim strMessage As String

    ' Open connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Set Cnxn = New ADODB.Connection
    Cnxn.Open strCnxn

    ' Open recordset dynamic to allow for changes
    Set rstTitles = New ADODB.Recordset
    strSQLTitles = "Titles"
    rstTitles.Open strSQLTitles, Cnxn, adOpenDynamic, adLockPessimistic, adCmdTable

    Cnxn.BeginTrans

    ' Loop through recordset and prompt user
    ' to change the type for a specified title

    rstTitles.MoveFirst

    Do Until rstTitles.EOF
        If Trim(rstTitles!Type) = "psychology" Then
            strTitle = rstTitles!Title
            strMessage = "Title: " & strTitle & vbCr & _
            "Change type to self help?"

            ' If yes, change type for the specified title
            If MsgBox(strMessage, vbYesNo) = vbYes Then
                rstTitles!Type = "self_help"
                rstTitles.Update
            End If
        End If
    rstTitles.MoveNext
    Loop

    ' Prompt user to commit all changes made
    If MsgBox("Save all changes?", vbYesNo) = vbYes Then
        Cnxn.CommitTrans
    Else
        Cnxn.RollbackTrans
    End If

    ' Print recordset
    rstTitles.Requery
    rstTitles.MoveFirst
    Do While Not rstTitles.EOF
        Debug.Print rstTitles!Title & " - " & rstTitles!Type
        rstTitles.MoveNext
    Loop

    ' Restore original data as this is a demo
    rstTitles.MoveFirst

    Do Until rstTitles.EOF
        If Trim(rstTitles!Type) = "self_help" Then
            rstTitles!Type = "psychology"
            rstTitles.Update
        End If
        rstTitles.MoveNext
    Loop

    ' clean up
    rstTitles.Close
    Cnxn.Close
    Set rstTitles = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstTitles Is Nothing Then
        If rstTitles.State = adStateOpen Then rstTitles.Close
    End If
    Set rstTitles = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub

'EndBeginTransVB

请参阅

BeginTrans、CommitTrans 和 RollbackTrans 方法 | Connection 对象


BOF、EOF 和 Bookmark 属性范例 (VB)

本范例使用 BOF 和 EOF 属性，在用户试图移过 Recordset 的第一个或最后一个记录时显示一条消息。Bookmark 属性的使用使得用户可以标记 Recordset 中的记录，稍后再返回该记录。

'BeginBOFVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    'recordset and connection variables
    Dim Cnxn As ADODB.Connection
    Dim rstPublishers As ADODB.Recordset
    Dim strCnxn As String
    Dim strSQLPubs As String
     'record variables
    Dim strMessage As String
    Dim intCommand As Integer
    Dim varBookmark As Variant

     ' open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

     ' Open recordset and use client cursor
     ' to enable AbsolutePosition property
    Set rstPublishers = New ADODB.Recordset
    strSQLPubs = "SELECT pub_id, pub_name FROM publishers ORDER BY pub_name"
    rstPublishers.Open strSQLPubs, strCnxn, adUseClient, adOpenStatic, adCmdText

    rstPublishers.MoveFirst
    Do Until rstPublishers.EOF
        ' Display information about current record
        ' and get user input
        strMessage = "Publisher: " & rstPublishers!pub_name & _
            vbCr & "(record " & rstPublishers.AbsolutePosition & _
            " of " & rstPublishers.RecordCount & ")" & vbCr & vbCr & _
            "Enter command:" & vbCr & _
            "[1 - next / 2 - previous /" & vbCr & _
            "3 - set bookmark / 4 - go to bookmark]"
        intCommand = Val(InputBox(strMessage))

        ' Check user input
        Select Case intCommand
            Case 1
                ' Move forward trapping for EOF
                rstPublishers.MoveNext
                If rstPublishers.EOF Then
                    MsgBox "Moving past the last record." & _
                        vbCr & "Try again."
                    rstPublishers.MoveLast
                End If
            Case 2
                ' Move backward trapping for BOF
                rstPublishers.MovePrevious
                If rstPublishers.BOF Then
                    MsgBox "Moving past the first record." & _
                        vbCr & "Try again."
                    rstPublishers.MoveFirst
                End If
            Case 3
                ' Store the bookmark of the current record
                varBookmark = rstPublishers.Bookmark
            Case 4
                ' Go to the record indicated by the stored bookmark
                If IsEmpty(varBookmark) Then
                    MsgBox "No Bookmark set!"
                Else
                    rstPublishers.Bookmark = varBookmark
                End If
            Case Else
                Exit Do
        End Select
    Loop

    ' clean up
    rstPublishers.Close
    Cnxn.Close
    Set rstPublishers = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstPublishers Is Nothing Then
        If rstPublishers.State = adStateOpen Then rstPublishers.Close
    End If
    Set rstPublishers = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndBOFVB

本范例使用 Bookmark 和 Filter 属性来创建 Recordset 的限定视图。用户只能访问书签数组所引用的记录。

'BeginBOF2VB
Public Sub Main()
    On Error GoTo ErrorHandler

    'recordset and connection variables
    Dim rs As New ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strSQL As String
    Dim strCnxn As String

    Dim bmk(10)

     ' open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

        'open the recordset client-side
    Set rs = New ADODB.Recordset
    strSQL = "Select * from Authors"
    rs.Open strSQL, Cnxn, adUseClient, adLockReadOnly, adCmdText
    Debug.Print "Number of records before filtering: ", rs.RecordCount

    Dim ii As Integer
    ii = 0

    If rs.EOF <> True And ii < 11 Then
        Do
            If Not (rs.EOF <> True And ii < 11) Then Exit Do
            bmk(ii) = rs.Bookmark
            ii = ii + 1
            rs.Move 2
        Loop Until rs.EOF
    End If

    rs.Filter = bmk
    Debug.Print "Number of records after filtering: ", rs.RecordCount

    rs.MoveFirst
    If rs.EOF <> True Then
        Do
            Debug.Print rs.AbsolutePosition, rs("au_lname")
            rs.MoveNext
        Loop Until rs.EOF
    End If

    ' clean up
    rs.Close
    Cnxn.Close
    Set rs = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rs Is Nothing Then
        If rs.State = adStateOpen Then rs.Close
    End If
    Set rs = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndBOF2VB

请参阅

BOF 和 EOF 属性 | Bookmark 属性 | Recordset 对象


CacheSize 属性范例 (VB)

本范例使用 CacheSize 属性显示使用和不使用缓存（大小为 30 条记录）时执行的操作在性能上的差别。

'BeginCacheSizeVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    'recordset and connection variables
    Dim rstRoySched As ADODB.Recordset
    Dim strSQLSched As String
    Dim strCnxn As String
     'record variables
    Dim sngStart As Single
    Dim sngEnd As Single
    Dim sngNoCache As Single
    Dim sngCache As Single
    Dim intLoop As Integer
    Dim strTemp As String

    ' Open the connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"

    ' Open the RoySched Table
    Set rstRoySched = New ADODB.Recordset
    strSQLSched = "roysched"
    rstRoySched.Open strSQLSched, strCnxn, , , adCmdTable

    ' Enumerate the Recordset object twice and
    ' record the elapsed time
    sngStart = Timer

    For intLoop = 1 To 2
        rstRoySched.MoveFirst

        If Not rstRoySched.EOF Then
            ' Execute a simple operation for the
            ' performance test
            Do
                strTemp = rstRoySched!title_id
                rstRoySched.MoveNext
            Loop Until rstRoySched.EOF
        End If
    Next intLoop

    sngEnd = Timer
    sngNoCache = sngEnd - sngStart

    ' Cache records in groups of 30 records.
    rstRoySched.MoveFirst
    rstRoySched.CacheSize = 30
    sngStart = Timer

    ' Enumerate the Recordset object twice and record
    ' the elapsed time
    For intLoop = 1 To 2
        rstRoySched.MoveFirst
        Do While Not rstRoySched.EOF
            ' Execute a simple operation for the
            ' performance test
            strTemp = rstRoySched!title_id
            rstRoySched.MoveNext
        Loop
    Next intLoop

    sngEnd = Timer
    sngCache = sngEnd - sngStart

    ' Display performance results.
    MsgBox "Caching Performance Results:" & vbCr & _
        "   No cache: " & Format(sngNoCache, "##0.000") & " seconds" & vbCr & _
        "   30-record cache: " & Format(sngCache, "##0.000") & " seconds"

    ' clean up
    rstRoySched.Close
    Set rstRoySched = Nothing
    Exit Sub

ErrorHandler:
   ' clean up
    If Not rstRoySched Is Nothing Then
        If rstRoySched.State = adStateOpen Then rstRoySched.Close
    End If
    Set rstRoySched = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndCacheSizeVB

请参阅

CacheSize 属性 | Recordset 对象


Cancel 方法范例 (VB)

本范例使用 Cancel 方法，在连接繁忙时取消在 Connection 对象上执行的命令。

'BeginCancelVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    'recordset and connection variables
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim strCmdChange As String
    Dim strCmdRestore As String
     'record variables
    Dim blnChanged As Boolean

    ' Open a connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Define command strings
    strCmdChange = "UPDATE titles SET type = 'self_help' WHERE type = 'psychology'"
    strCmdRestore = "UPDATE titles SET type = 'psychology' " & _
                     "WHERE type = 'self_help'"

    ' Begin a transaction, then execute a command asynchronously
    Cnxn.BeginTrans
    Cnxn.Execute strCmdChange, , adAsyncExecute
    ' do something else for a little while –
    ' use i = 1 to 32000 to allow completion
    Dim i As Integer
    For i = 1 To 1000
        i = i + i
        Debug.Print i
    Next i

    ' If the command has NOT completed, cancel the execute and
    ' roll back the transaction; otherwise, commit the transaction
    If CBool(Cnxn.State And adStateExecuting) Then
        Cnxn.Cancel
        Cnxn.RollbackTrans
        blnChanged = False
        MsgBox "Update canceled."
    Else
        Cnxn.CommitTrans
        blnChanged = True
        MsgBox "Update complete."
    End If

    ' If the change was made, restore the data
    ' because this is only a demo
    If blnChanged Then
        Cnxn.Execute strCmdRestore
        MsgBox "Data restored."
    End If

    ' clean up
    Cnxn.Close
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndCancelVB

请参阅

Cancel 方法 | Connection 对象


Clone 方法范例 (VB)

本范例使用 Clone 方法来创建 Recordset 的副本，然后让用户单独定位每个副本的记录指针。

'BeginCloneVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    'recordset array and connection variables
    Dim arstStores(1 To 3) As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strSQLStore As String
    Dim strCnxn As String
     'record variables
    Dim intLoop As Integer
    Dim strMessage As String
    Dim strFind As String

    ' Open a connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open recordset as a static cursor type recordset
    Set arstStores(1) = New ADODB.Recordset
    strSQLStore = "SELECT stor_name FROM Stores ORDER BY stor_name"
    arstStores(1).Open strSQLStore, strCnxn, adOpenStatic, adLockBatchOptimistic, adCmdText

    ' Create two clones of the original Recordset
    Set arstStores(2) = arstStores(1).Clone
    Set arstStores(3) = arstStores(1).Clone

    ' Loop through the array so that on each pass the user
    ' is searching a different copy of the same Recordset
    Do
        For intLoop = 1 To 3
             ' Ask for search string while showing where
             ' the current record pointer is for each Recordset
            strMessage = _
                "Recordsets from stores table:" & vbCr & _
                "  1 - Original - Record pointer at " & arstStores(1)!stor_name & vbCr & _
                "  2 - Clone - Record pointer at " & arstStores(2)!stor_name & vbCr & _
                "  3 - Clone - Record pointer at " & arstStores(3)!stor_name & vbCr & _
                "Enter search string for #" & intLoop & ":"

            strFind = Trim(InputBox(strMessage))
             ' make sure something was entered, if not then EXIT loop
            If strFind = "" Then Exit Do

             ' otherwise locate the record from the entered string
            arstStores(intLoop).Filter = "stor_name = '" & strFind & "'"

             'if there's no match, jump to the last record
            If arstStores(intLoop).EOF Then
                arstStores(intLoop).Filter = adFilterNone
                arstStores(intLoop).MoveLast
            Else
                MsgBox "Found " & strFind
            End If
        Next intLoop
    Loop

    ' clean up
    arstStores(1).Close
    arstStores(2).Close
    arstStores(3).Close
    Cnxn.Close
    Set arstStores(1) = Nothing
    Set arstStores(2) = Nothing
    Set arstStores(3) = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not arstStores(1) Is Nothing Then
        If arstStores(1).State = adStateOpen Then arstStores(1).Close
    End If
    Set arstStores(1) = Nothing
    If Not arstStores(2) Is Nothing Then
        If arstStores(2).State = adStateOpen Then arstStores(2).Close
    End If
    Set arstStores(2) = Nothing
    If Not arstStores(3) Is Nothing Then
        If arstStores(3).State = adStateOpen Then arstStores(3).Close
    End If
    Set arstStores(3) = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndCloneVB

请参阅

Clone 方法 | Recordset 对象


CompareBookmarks 方法范例 (VB)

本范例演示 CompareBookmarks 方法。除了特殊的书签以外，不需要书签的相对值。

将源于 Authors 表的 Recordset 的随机行指定为搜索目标。然后显示每一行相对于该目标的位置。

'BeginCompareBookmarksVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

     ' recordset and connection variables
    Dim rstAuthors As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strSQLAuthors As String
    Dim strCnxn As String

     ' comparison variables
    Dim count As Integer
    Dim target As Variant
    Dim result As Long
    Dim strAnswer As String
    Dim strTitle As String
    strTitle = "CompareBookmarks Example"

    ' Open a connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

     ' Open recordset as a static cursor type recordset
    Set rstAuthors = New ADODB.Recordset
    strSQLAuthors = "SELECT * FROM Authors"
    rstAuthors.Open strSQLAuthors, Cnxn, adOpenStatic, adLockReadOnly, adCmdText

    count = rstAuthors.RecordCount
    Debug.Print "Rows in the Recordset = "; count

     ' Exit if an empty recordset
    If count = 0 Then Exit Sub

     ' Get position between 0 and count -1
    Randomize
    count = (Int(count * Rnd))
    Debug.Print "Randomly chosen row position = "; count
     ' Move row to random position
    rstAuthors.Move count, adBookmarkFirst
     ' Remember the mystery row
    target = rstAuthors.Bookmark

    count = 0
    rstAuthors.MoveFirst
         ' Loop through recordset
    Do Until rstAuthors.EOF
       result = rstAuthors.CompareBookmarks(rstAuthors.Bookmark, target)

       If result = adCompareNotEqual Then
          Debug.Print "Row "; count; ": Bookmarks are not equal."
       ElseIf result = adCompareNotComparable Then
          Debug.Print "Row "; count; ": Bookmarks are not comparable."
       Else
          Select Case result
             Case adCompareLessThan
                strAnswer = "less than"
             Case adCompareEqual
                strAnswer = "equal to"
             Case adCompareGreaterThan
                strAnswer = "greater than"
             Case Else
                strAnswer = "in error comparing to"
          End Select
            'show the results row-by-row
          Debug.Print "Row position " & count & " is " & strAnswer & " the target."
       End If

       count = count + 1
       rstAuthors.MoveNext
    Loop

    ' clean up
    rstAuthors.Close
    Cnxn.Close
    Set rstAuthors = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstAuthors Is Nothing Then
        If rstAuthors.State = adStateOpen Then rstAuthors.Close
    End If
    Set rstAuthors = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

End Sub
'EndCompareBookmarksVB

请参阅

CompareBookmarks 方法 | CompareEnum | Recordset 对象


ConnectionString、ConnectionTimeout 和 State 属性范例 (VB)

本范例演示使用 ConnectionString 属性打开 Connection 对象的不同方式。范例中还使用 ConnectionTimeout 属性来设置连接超时的时间段，并使用 State 属性来检查连接的状态。运行此过程需要 GetState 函数。

'BeginConnectionStringVB

    'To integrate this code replace
    'the database, DSN or Data Source values

Public Sub Main()
    On Error GoTo ErrorHandler

    Dim Cnxn1 As ADODB.Connection
    Dim Cnxn2 As ADODB.Connection
    Dim Cnxn3 As ADODB.Connection
    Dim Cnxn4 As ADODB.Connection

     ' Open a connection without using a Data Source Name (DSN)
    Set Cnxn1 = New ADODB.Connection
    Cnxn1.ConnectionString = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn1.Open
    MsgBox "Cnxn1 state: " & GetState(Cnxn1.State)

     ' Open a connection using a DSN and ODBC tags
     ' It is assumed that you have create DSN 'Pubs' with a user name as
     ' 'MyUserId' and password as 'MyPassword'.
    Set Cnxn2 = New ADODB.Connection
    Cnxn2.ConnectionString = "Data Source='Pubs';" & _
        "User ID='MyUserId';Password='MyPassword';"
    Cnxn2.ConnectionTimeout = 30
    Cnxn2.Open
    MsgBox "Cnxn2 state: " & GetState(Cnxn2.State)

     ' Open a connection using a DSN and OLE DB tags
     ' It is assumed that you have create DSN 'Pubs1' with windows authentication.
    Set Cnxn3 = New ADODB.Connection
    Cnxn3.ConnectionString = "Data Source='Pubs1';"
    Cnxn3.Open
    MsgBox "Cnxn2 state: " & GetState(Cnxn3.State)

     ' Open a connection using a DSN and individual
     ' arguments instead of a connection string
     ' It is assumed that you have create DSN 'Pubs' with a user name as
     ' 'MyUserId' and password as 'MyPassword'.
    Set Cnxn4 = New ADODB.Connection
    Cnxn4.Open "Pubs", "MyUserId", "MyPassword"
    MsgBox "Cnxn4 state: " & GetState(Cnxn4.State)

    ' clean up
    Cnxn1.Close
    Cnxn2.Close
    Cnxn3.Close
    Cnxn4.Close
    Set Cnxn1 = Nothing
    Set Cnxn2 = Nothing
    Set Cnxn3 = Nothing
    Set Cnxn4 = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not Cnxn1 Is Nothing Then
        If Cnxn1.State = adStateOpen Then Cnxn1.Close
    End If
    Set Cnxn1 = Nothing

    If Not Cnxn2 Is Nothing Then
        If Cnxn2.State = adStateOpen Then Cnxn2.Close
    End If
    Set Cnxn2 = Nothing

    If Not Cnxn3 Is Nothing Then
        If Cnxn3.State = adStateOpen Then Cnxn3.Close
    End If
    Set Cnxn3 = Nothing

    If Not Cnxn4 Is Nothing Then
        If Cnxn4.State = adStateOpen Then Cnxn4.Close
    End If
    Set Cnxn4 = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub

Public Function GetState(intState As Integer) As String

   Select Case intState
      Case adStateClosed
         GetState = "adStateClosed"
      Case adStateOpen
         GetState = "adStateOpen"
   End Select

End Function
'EndConnectionStringVB

请参阅

Connection 对象 | ConnectionString 属性 | ConnectionTimeout 属性 | State 属性


ConvertToString 方法范例 (VB)

'BeginConvertToStringVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

     ' to integrate this code replace the server name
     ' in the CreateObject call

     ' RDS variables
    Dim rdsDS As RDS.DataSpace
    Dim rdsDC As RDS.DataControl
    Dim rdsDF As Object
     ' recordset and connection variables
    Dim rsAuthors As ADODB.Recordset
    Dim strSQLAuthors As String
    Dim strCnxn As String
    Dim varString As Variant

     ' Create a DataSpace object
    Set rdsDS = New RDS.DataSpace
     ' Create a DataFactory object
    Set rdsDF = rdsDS.CreateObject("RDSServer.DataFactory", "http://MyServer") 'MyServer

     ' Get all of the Author records

    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    strSQLAuthors = "SELECT * FROM Authors"
    Set rsAuthors = rdsDF.Query(strCnxn, strSQLAuthors)
     ' Show results
    Debug.Print "Old RDS recordset count:" & rsAuthors.RecordCount

     ' Convert the recordset into a MIME formatted string
    varString = rdsDF.ConvertToString(rsAuthors)
    Debug.Print "Recordset as MIME format string:"
    Debug.Print varString

     ' Convert string value back into an ADO Recordset
    Set rdsDC = New RDS.DataControl
    rdsDC.SQL = varString
    rdsDC.ExecuteOptions = adcExecSync
    rdsDC.FetchOptions = adcFetchUpFront
    rdsDC.Refresh
     ' Show results
    Debug.Print "New ADO recordset count:" & rdsDC.Recordset.RecordCount

     ' clean up
    rsAuthors.Close
    Set rsAuthors = Nothing
    Set rdsDC = Nothing
    Set rdsDS = Nothing
    Set rdsDC = Nothing

ErrorHandler:

    If Not rsAuthors Is Nothing Then
        If rsAuthors.State = adStateOpen Then rsAuthors.Close
    End If
    Set rsAuthors = Nothing
    Set rdsDC = Nothing
    Set rdsDS = Nothing
    Set rdsDC = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

End Sub
'EndConvertToStringVB

请参阅

ConvertToString 方法 (RDS) | Recordset 对象


CopyRecord、CopyTo 和 SaveToFile 方法范例 (VB)

本范例演示如何使用 Stream 或 Record 对象来创建文件副本。有一个副本创建到 Web 文件夹以用于 Internet 发布。显示的其他属性和方法包括 Stream Type、Open、LoadFromFile 和 Record Open。

'BeginCopyRecordVB

'Note:
' This sample requires that "C:\checkmrk.wmf" and
' "http://MyServer/mywmf.wmf" exist.

Option Explicit

Private Sub Form_Load()
    On Error GoTo ErrorHandler

    ' Declare variables
    Dim strPicturePath, strStreamPath, strStream2Path, _
        strRecordPath, strStreamURL, strRecordURL As String
    Dim objStream, objStream2 As Stream
    Dim objRecord As Record
    Dim objField As Field

    ' Instantiate objects
    Set objStream = New Stream
    Set objStream2 = New Stream
    Set objRecord = New Record

    ' Initialize path and URL strings
    strPicturePath = "C:\checkmrk.wmf"
    strStreamPath = "C:\mywmf.wmf"
    strStreamURL = "URL=http://MyServer/mywmf.wmf"
    strStream2Path = "C:\checkmrk2.wmf"
    strRecordPath = "C:\mywmf.wmf"
    strRecordURL = "http://MyServer/mywmf2.wmf"

    ' Load the file into the stream
    objStream.Open
    objStream.Type = adTypeBinary
    objStream.LoadFromFile (strPicturePath)

    ' Save the stream to a new path and filename
    objStream.SaveToFile strStreamPath, adSaveCreateOverWrite

    ' Copy the contents of the first stream to a second stream
    objStream2.Open
    objStream2.Type = adTypeBinary
    objStream.CopyTo objStream2

    ' Save the second stream to a different path
    objStream2.SaveToFile strStream2Path, adSaveCreateOverWrite

    ' Because strStreamPath is a Web Folder, open a Record on the URL
    objRecord.Open "", strStreamURL

    ' Display the Fields of the record
    For Each objField In objRecord.Fields
        Debug.Print objField.Name & ": " & objField.Value
    Next

    ' Copy the record to a new URL
    objRecord.CopyRecord "", strRecordURL, , , adCopyOverWrite

    ' Load each copy of the graphic into Image controls for viewing
    Image1.Picture = LoadPicture(strPicturePath)
    Image2.Picture = LoadPicture(strStreamPath)
    Image3.Picture = LoadPicture(strStream2Path)
    Image4.Picture = LoadPicture(strRecordPath)

    ' clean up
    objStream.Close
    objStream2.Close
    objRecord.Close
    Set objStream = Nothing
    Set objStream2 = Nothing
    Set objRecord = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not objStream Is Nothing Then
        If objStream.State = adStateOpen Then objStream.Close
    End If
    Set objStream = Nothing

    If Not objStream2 Is Nothing Then
        If objStream2.State = adStateOpen Then objStream2.Close
    End If
    Set objStream2 = Nothing

    If Not objRecord Is Nothing Then
        If objRecord.State = adStateOpen Then objRecord.Close
    End If
    Set objRecord = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndCopyRecordVB

请参阅

CopyRecord 方法 | CopyTo 方法 | LoadFromFile 方法 | Open 方法 (ADO Record) | Open 方法 (ADO Stream) | Record 对象 | SaveToFile 方法 | Stream 对象 | Type 属性 (ADO Stream)


Count 属性范例 (VB)

本范例使用 Employee 数据库中的两个集合演示 Count 属性。该属性获取每个集合的对象数，并设置枚举这些集合的循环上限。枚举这些集合的另一种方法不使用 Count 属性，而是使用 For Each...Next 语句。

'BeginCountVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    ' recordset and connection variables
    Dim rstEmployees As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strSQLEmployees As String
    Dim strCnxn As String

    Dim intLoop As Integer

    ' Open a connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Northwind';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open recordset with data from Employee table
    Set rstEmployees = New ADODB.Recordset
    strSQLEmployees = "Employees"
    'rstEmployees.Open strSQLEmployee, Cnxn, , , adCmdTable
    rstEmployees.Open strSQLEmployees, Cnxn, adOpenForwardOnly, adLockReadOnly, adCmdTable
    'the above two lines opening the recordset are identical as
    'the default values for CursorType and LockType arguments match those specified

    ' Print information about Fields collection
    Debug.Print rstEmployees.Fields.Count & " Fields in Employee"

    For intLoop = 0 To rstEmployees.Fields.Count - 1
        Debug.Print "   " & rstEmployees.Fields(intLoop).Name
    Next intLoop

    ' Print information about Properties collection
    Debug.Print rstEmployees.Properties.Count & " Properties in Employee"

    For intLoop = 0 To rstEmployees.Properties.Count - 1
        Debug.Print "   " & rstEmployees.Properties(intLoop).Name
    Next intLoop

    ' clean up
    rstEmployees.Close
    Cnxn.Close
    Set rstEmployees = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstEmployees Is Nothing Then
        If rstEmployees.State = adStateOpen Then rstEmployees.Close
    End If
    Set rstEmployees = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndCountVB

请参阅

Count 属性


CreateRecordset 方法范例 (VB)

用户可以创建 Recordset 对象并指定列信息，然后将数据插入 Recordset 对象；基本行集合缓存插入的数据。

以下代码范例显示如何使用 RDSServer.DataFactory 对象来定义 Recordset。使用RDS.DataControl 对象也可以实现相同功能。

'BeginRsDefineShapeVB
Sub Main()
    On Error GoTo ErrorHandler

    Dim ADF As RDSServer.DataFactory
    Dim vntRecordShape(3)
    Dim vntField1Shape(3)
    Dim vntField2Shape(3)
    Dim vntField3Shape(3)
    Dim vntField4Shape(3)

    Set ADF = New RDSServer.DataFactory

    ' For each field, specify the name,
    ' type, size, and nullability.

    vntField1Shape(0) = "Name"   ' Column name.
    vntField1Shape(1) = CInt(129)   ' Column type.
    vntField1Shape(2) = CInt(40)   ' Column size.
    vntField1Shape(3) = False      ' Nullable?

    vntField2Shape(0) = "Age"
    vntField2Shape(1) = CInt(3)
    vntField2Shape(2) = CInt(-1)
    vntField2Shape(3) = True

    vntField3Shape(0) = "DateOfBirth"
    vntField3Shape(1) = CInt(7)
    vntField3Shape(2) = CInt(-1)
    vntField3Shape(3) = True

    vntField4Shape(0) = "Balance"
    vntField4Shape(1) = CInt(6)
    vntField4Shape(2) = CInt(-1)
    vntField4Shape(3) = True

    ' Put all fields into an array of arrays.
    vntRecordShape(0) = vntField1Shape
    vntRecordShape(1) = vntField2Shape
    vntRecordShape(2) = vntField3Shape
    vntRecordShape(3) = vntField4Shape

    ' Use the RDSServer.DataFactory to create an empty
    ' recordset. It takes an array of variants where
    ' every element is itself another array of
    ' variants, one for every column required in the
    ' recordset.
    ' The elements of the inner array are the column's
    ' name, type, size, and nullability.
    '
    ' NOTE: You could just use the RDS.DataControl object
    ' instead of the RDSServer.DataFactory object. In
    ' that case, the following code would be Set NewRS
    ' = ADC1.CreateRecordset(vntRecordShape)
    Dim NewRs As ADODB.Recordset
    Set NewRs = ADF.CreateRecordSet(vntRecordShape)

    Dim fields(3)
    fields(0) = vntField1Shape(0)
    fields(1) = vntField2Shape(0)
    fields(2) = vntField3Shape(0)
    fields(3) = vntField4Shape(0)

    ' Populate the new recordset with data values.
    Dim fieldVals(3)

    ' Use AddNew to add the records.
    fieldVals(0) = "Joe"
    fieldVals(1) = 5
    fieldVals(2) = CDate(#1/5/1996#)
    fieldVals(3) = 123.456
    NewRs.AddNew fields, fieldVals

    fieldVals(0) = "Mary"
    fieldVals(1) = 6
    fieldVals(2) = CDate(#6/5/1996#)
    fieldVals(3) = 31
    NewRs.AddNew fields, fieldVals

    fieldVals(0) = "Alex"
    fieldVals(1) = 13
    fieldVals(2) = CDate(#1/6/1996#)
    fieldVals(3) = 34.0001
    NewRs.AddNew fields, fieldVals

    fieldVals(0) = "Susan"
    fieldVals(1) = 13
    fieldVals(2) = CDate(#8/6/1996#)
    fieldVals(3) = 0#
    NewRs.AddNew fields, fieldVals

    NewRs.MoveFirst

    ' Set the newly created and populated Recordset to
    ' the SourceRecordset property of the
    ' RDS.DataControl to bind to visual controls
    Dim ADC1 As RDS.DataControl
    Set ADC1 = New RDS.DataControl
    Set ADC1.SourceRecordset = NewRs

    'Clean up
    If NewRs.State = adStateOpen Then NewRs.Close
    Set NewRs = Nothing
    Set ADC1 = Nothing
    Set ADF = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not NewRs Is Nothing Then
        If NewRs.State = adStateOpen Then NewRs.Close
    End If
    Set NewRs = Nothing
    Set ADC1 = Nothing
    Set ADF = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndRsDefineShapeVB


CursorType、LockType 和 EditMode 属性范例 (VB)

本范例演示在打开 Recordset 前设置 CursorType 和 LockType 属性。范例还显示不同条件下 EditMode 属性的值。运行此过程需要 EditModeOutput 函数。

'BeginEditModeVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    ' recordset variables
    Dim rstEmployees As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim SQLEmployees As String

     ' open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

      ' set recordset properties through object refs
      ' instead of through arguments to Open method
    Set rstEmployees = New ADODB.Recordset
    Set rstEmployees.ActiveConnection = Cnxn
    rstEmployees.CursorLocation = adUseClient
    rstEmployees.CursorType = adOpenStatic
    rstEmployees.LockType = adLockBatchOptimistic

     ' open recordset with data from Employee table
    SQLEmployees = "employee"
    rstEmployees.Open SQLEmployees, , , , adCmdTable

    ' Show the EditMode property under different editing states
    rstEmployees.AddNew
        rstEmployees!emp_id = "T-T55555M"
        rstEmployees!fname = "temp_fname"
        rstEmployees!lname = "temp_lname"
            'call function below
            'to output results to debug window
        EditModeOutput "After AddNew:", rstEmployees.EditMode
        rstEmployees.UpdateBatch
        EditModeOutput "After UpdateBatch:", rstEmployees.EditMode
        rstEmployees!fname = "test"
        EditModeOutput "After Edit:", rstEmployees.EditMode
    rstEmployees.Close

    ' Delete new record because this is a demonstration
    Cnxn.Execute "DELETE FROM employee WHERE emp_id = 'T-T55555M'"

    ' clean up
    Cnxn.Close
    Set rstEmployees = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstEmployees Is Nothing Then
        If rstEmployees.State = adStateOpen Then rstEmployees.Close
    End If
    Set rstEmployees = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

End Sub

Public Function EditModeOutput(strTemp As String, _
   intEditMode As Integer)

   ' Print report based on the value of the EditMode
   ' property
   Debug.Print strTemp
   Debug.Print "  EditMode = ";

   Select Case intEditMode
      Case adEditNone
         Debug.Print "adEditNone"
      Case adEditInProgress
         Debug.Print "adEditInProgress"
      Case adEditAdd
         Debug.Print "adEditAdd"
   End Select

End Function
'EndEditModeVB

请参阅

CursorType 属性 | CursorTypeEnum | EditMode 属性 | EditModeEnum | LockType 属性 | LockTypeEnum | Recordset 对象


Delete 方法范例 (VB)

本范例使用 Delete 方法从 Recordset 中删除指定的记录。

'BeginDeleteVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    Dim rstRoySched As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim strSQLRoySched As String

    Dim strMsg As String
    Dim strTitleID As String
    Dim intLoRange As Integer
    Dim intHiRange As Integer
    Dim intRoyalty As Integer

     ' open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' open RoySched table with cursor client-side
    Set rstRoySched = New ADODB.Recordset
    rstRoySched.CursorLocation = adUseClient
    rstRoySched.CursorType = adOpenStatic
    rstRoySched.LockType = adLockBatchOptimistic
    rstRoySched.Open "SELECT * FROM roysched WHERE royalty = 20", strCnxn, , , adCmdText

    ' Prompt for a record to delete
    strMsg = "Before delete there are " & rstRoySched.RecordCount & _
       " titles with 20 percent royalty:" & vbCr & vbCr

    Do While Not rstRoySched.EOF
       strMsg = strMsg & rstRoySched!title_id & vbCr
       rstRoySched.MoveNext
    Loop

    strMsg = strMsg & vbCr & vbCr & "Enter the ID of a record to delete:"
    strTitleID = UCase(InputBox(strMsg))

    If strTitleID = "" Then
        Err.Raise 1, , "You didn't enter any value for the record ID."
    End If

    ' Move to the record and save data so it can be restored
    rstRoySched.Filter = "title_id = '" & strTitleID & "'"

    If rstRoySched.RecordCount < 1 Then
        Err.Raise 1, , "There is no record for the record ID you entered."
    End If

    intLoRange = rstRoySched!lorange
    intHiRange = rstRoySched!hirange
    intRoyalty = rstRoySched!royalty

    ' Delete the record
    rstRoySched.Delete
    rstRoySched.UpdateBatch

    ' Show the results
    rstRoySched.Filter = adFilterNone
    rstRoySched.Requery
    strMsg = ""
    strMsg = "After delete there are " & rstRoySched.RecordCount & _
       " titles with 20 percent royalty:" & vbCr & vbCr
    Do While Not rstRoySched.EOF
        strMsg = strMsg & rstRoySched!title_id & vbCr
        rstRoySched.MoveNext
    Loop
    MsgBox strMsg

    ' Restore the data because this is a demonstration
    rstRoySched.AddNew
    rstRoySched!title_id = strTitleID
    rstRoySched!lorange = intLoRange
    rstRoySched!hirange = intHiRange
    rstRoySched!royalty = intRoyalty
    rstRoySched.UpdateBatch

    ' clean up
    rstRoySched.Close
    Set rstRoySched = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstRoySched Is Nothing Then
        If rstRoySched.State = adStateOpen Then rstRoySched.Close
    End If
    Set rstRoySched = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndDeleteVB

请参阅

Delete 方法 (ADO Recordset) | Recordset 对象


DeleteRecord 和 MoveRecord 方法范例 (VB)

本范例演示对发布到 Web 文件夹的文本文件的内容进行复制、移动、编辑和删除的方式。使用的其他属性和方法包括 GetChildren、ParentURL、Source 和 Flush。

'BeginDeleteRecordVB

'Note:
' IIS must be running for this sample to work. To
' use this sample you must:
'
' 1. create folders named "test" and "test2"
'    in the root web folder of http://MyServer
'
' 2. Create a text file named "test2.txt" in the
'    "test" folder.
' 3. Replace "MyServer" with the appropriate web
'    server name.

Public Sub Main()
    On Error GoTo ErrorHandler

     ' connection and recordset variables
    Dim rsDestFolder As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String

     ' file as record variables
    Dim rcFile As ADODB.Record
    Dim rcDestFile As ADODB.Record
    Dim rcDestFolder As ADODB.Record
    Dim objStream As Stream

     ' file variables
    Dim strFile As String
    Dim strDestFile As String
    Dim strDestFolder As String

     ' instantiate variables
    Set rsDestFolder = New ADODB.Recordset
    Set rcDestFolder = New ADODB.Record
    Set rcFile = New ADODB.Record
    Set rcDestFile = New ADODB.Record
    Set objStream = New ADODB.Stream

     ' open a record on a text file
    Set Cnxn = New ADODB.Connection
    strCnxn = "url=http://MyServer/"
    Cnxn.Open strCnxn
    strFile = "test/test2.txt"
    rcFile.Open strFile, Cnxn, adModeReadWrite, adOpenIfExists Or adCreateNonCollection
    Debug.Print Cnxn

     ' edit the contents of the text file
    objStream.Open rcFile, , adOpenStreamFromRecord

    Debug.Print "Source: " & strCnxn & rcFile.Source
    Debug.Print "Original text: " & objStream.ReadText

    objStream.Position = 0
    objStream.WriteText "Newer Text. "
    objStream.Position = 0

    Debug.Print "New text: " & objStream.ReadText

     ' reset the stream object
    objStream.Flush
    objStream.Close
    rcFile.Close

     ' reopen record to see new contents of text file
    rcFile.Open strFile, Cnxn, adModeReadWrite, adOpenIfExists Or adCreateNonCollection
    objStream.Open rcFile, adModeReadWrite, adOpenStreamFromRecord

    Debug.Print "Source: " & strCnxn & rcFile.Source
    Debug.Print "Edited text: " & objStream.ReadText

     ' copy the file to another folder
    strDestFile = "test2/test1.txt"
    rcFile.CopyRecord "", "http://MyServer/" & strDestFile, "", "", adCopyOverWrite

     ' delete the original file
    rcFile.DeleteRecord

     ' move the file from the subfolder back to original location
    strDestFolder = "test2/"
    rcDestFolder.Open strDestFolder, Cnxn ', adOpenIfExists  'Or adCreateCollection
    Set rsDestFolder = rcDestFolder.GetChildren
    rsDestFolder.MoveFirst

     ' position current record at on the correct file
    Do While Not (rsDestFolder.EOF Or rsDestFolder(0) = "test1.txt")
        rsDestFolder.MoveNext
    Loop

     ' open a record on the correct row of the recordset
    rcDestFile.Open rsDestFolder, Cnxn

     ' do the move
    rcDestFile.MoveRecord "", "http://MyServer/" & strFile, "", "", adMoveOverWrite

    ' clean up
    rsDestFolder.Close
    Cnxn.Close
    Set rsDestFolder = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rsDestFolder Is Nothing Then
        If rsDestFolder.State = adStateOpen Then rsDestFolder.Close
    End If
    Set rsDestFolder = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndDeleteRecordVB

请参阅

DeleteRecord 方法 | Flush 方法 | GetChildren 方法 | MoveRecord 方法 | ParentURL 属性 | Source 属性 (ADO Record)


Description、HelpContext、HelpFile、NativeError、Number、Source 和 SQLState 属性范例 (VB)

本范例触发并捕获错误，同时显示产生的 Error 对象的 Description、HelpContext、HelpFile、NativeError、Number、Source 和 SQLState 属性。

'BeginDescriptionVB
Public Sub Main()

    Dim Cnxn As ADODB.Connection
    Dim Err As ADODB.Error
    Dim strError As String

    On Error GoTo ErrorHandler

    ' Intentionally trigger an error
    Set Cnxn = New ADODB.Connection
    Cnxn.Open "nothing"

    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:

    ' Enumerate Errors collection and display
    ' properties of each Error object
    For Each Err In Cnxn.Errors
        strError = "Error #" & Err.Number & vbCr & _
            "   " & Err.Description & vbCr & _
            "   (Source: " & Err.Source & ")" & vbCr & _
            "   (SQL State: " & Err.SQLState & ")" & vbCr & _
            "   (NativeError: " & Err.NativeError & ")" & vbCr
        If Err.HelpFile = "" Then
            strError = strError & "   No Help file available"
        Else
            strError = strError & _
               "   (HelpFile: " & Err.HelpFile & ")" & vbCr & _
               "   (HelpContext: " & Err.HelpContext & ")" & _
               vbCr & vbCr
        End If

        Debug.Print strError
    Next

    Resume Next
End Sub
'EndDescriptionVB

请参阅

Description 属性 | Error 对象 | HelpContext 属性 | HelpFile 属性 | NativeError 属性 | Number 属性 | Source 属性 (ADO Error) | SQLState 属性


EOS 和 LineSeparator 属性、SkipLine 方法范例 (VB)

本范例演示如何每次操作一行文本流。范例显示了将分行符从默认的回车/换行 (adCRLF) 改成简单的换行 (adLF) 或回车 (adCR) 的效果。

'BeginSkipLineVB
Private Sub cmdSkipLine_Click()
    On Error GoTo ErrorHandler

    'Declare variables
    Dim i As Integer
    Dim objStream As Stream
    Dim strLine, strChar As String

    'Instantiate and open stream
    Set objStream = New Stream
    objStream.Open

    'Set line separator to line feed
    objStream.LineSeparator = adLF

    'Load text content of list box into stream
    'One line at a time
    For i = 0 To (List1.ListCount - 1)
        objStream.WriteText List1.List(i), adWriteLine
    Next

    'Display the entire stream
    Debug.Print "Whole Stream:"
    objStream.Position = 0
    Debug.Print objStream.ReadText

    'Display the first line
    Debug.Print "First Line:"
    objStream.Position = 0
    strLine = objStream.ReadText(adReadLine)
    Debug.Print strLine
    Debug.Print "Line length: " + Str(Len(strLine))

    'Skip a line, then display another line
    Debug.Print "Third Line:"
    objStream.SkipLine
    strLine = objStream.ReadText(adReadLine)
    Debug.Print strLine
    Debug.Print "Line length: " + Str(Len(strLine))

    'Switch line separator to carriage return
    'All items from list will be considered one line
    'Assuming no CRs have been loaded into stream
    Debug.Print "Whole Stream/First Line:"
    objStream.Position = 0
    objStream.LineSeparator = adCR
    strLine = objStream.ReadText(adReadLine)
    Debug.Print strLine
    Debug.Print "Line length: " + Str(Len(strLine))
    Debug.Print "Stream size: " + Str(objStream.Size)

    'Use EOS to Determine End of Stream
    Debug.Print "Character by character:"
    objStream.Position = 0
    Do Until objStream.EOS
        strChar = objStream.ReadText(1)
        Debug.Print strChar
    Loop

    ' clean up
    objStream.Close
    Set objStream = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not objStream Is Nothing Then
        If objStream.State = adStateOpen Then objStream.Close
    End If
    Set objStream = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub

Private Sub Form_Load()
    List1.AddItem "This is the first line"
    List1.AddItem "This is the second line"
    List1.AddItem "This is the third line"
End Sub
'EndSkipLineVB

请参阅

EOS 属性 | LineSeparator 属性 | SkipLine 方法


Execute、Requery 和 Clear 方法范例 (VB)

本范例演示从 Command 和 Connection 对象运行 Execute 方法。范例中还使用 Requery 方法检索 Recordset 中的当前数据，并用 Clear 方法清除 Errors 集合的内容。（通过 Recordset 的 ActiveConnection 属性的 Connection 对象来访问 Errors 集合。）运行此过程需要 ExecuteCommand 和 PrintOutput 过程。

'BeginExecuteVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo Err_Execute

    ' connection, command, and recordset variables
    Dim Cnxn As ADODB.Connection
    Dim cmdChange As ADODB.Command
    Dim rstTitles As ADODB.Recordset
    Dim Err As ADODB.Error
    Dim strSQLChange As String
    Dim strSQLRestore As String
    Dim strSQLTitles
    Dim strCnxn As String

     ' Define two SQL statements to execute as command text
    strSQLChange = "UPDATE Titles SET Type = 'self_help' WHERE Type = 'psychology'"
    strSQLRestore = "UPDATE Titles SET Type = 'psychology' WHERE Type = 'self_help'"

     ' Open connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Set Cnxn = New ADODB.Connection
    Cnxn.Open strCnxn

     ' Create command object
    Set cmdChange = New ADODB.Command
    Set cmdChange.ActiveConnection = Cnxn
    cmdChange.CommandText = strSQLChange

     ' Open titles table
    Set rstTitles = New ADODB.Recordset
    strSQLTitles = "titles"
    rstTitles.Open strSQLTitles, Cnxn, , , adCmdTable

    ' Print report of original data
    Debug.Print _
       "Data in Titles table before executing the query"
    PrintOutput rstTitles

    ' Call the ExecuteCommand subroutine below to execute cmdChange command
    ExecuteCommand cmdChange, rstTitles

    ' Print report of new data
    Debug.Print _
       "Data in Titles table after executing the query"
    PrintOutput rstTitles

    ' Use the Connection object's execute method to
    ' execute SQL statement to restore data and trap for
    ' errors, checking the Errors collection if necessary
    Cnxn.Execute strSQLRestore, , adExecuteNoRecords

    ' Retrieve the current data by requerying the recordset
    rstTitles.Requery

    ' Print report of restored data using sub from below
    Debug.Print "Data after executing the query to restore the original information "
    PrintOutput rstTitles

    ' clean up
    rstTitles.Close
    Cnxn.Close
    Set rstTitles = Nothing
    Set Cnxn = Nothing
    Exit Sub

Err_Execute:
    ' Notify user of any errors that result from
    ' executing the query
    If rstTitles.ActiveConnection.Errors.Count >= 0 Then
       For Each Err In rstTitles.ActiveConnection.Errors
          MsgBox "Error number: " & Err.Number & vbCr & _
             Err.Description
       Next Err
    End If

    ' clean up
    If Not rstTitles Is Nothing Then
        If rstTitles.State = adStateOpen Then rstTitles.Close
    End If
    Set rstTitles = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub

Public Sub ExecuteCommand(cmdTemp As ADODB.Command, rstTemp As ADODB.Recordset)

   Dim Err As Error

   ' Run the specified Command object and trap for
   ' errors, checking the Errors collection
   On Error GoTo Err_Execute
   cmdTemp.Execute
   On Error GoTo 0

   ' Retrieve the current data by requerying the recordset
   rstTemp.Requery

   Exit Sub

Err_Execute:

   ' Notify user of any errors that result from
   ' executing the query
   If rstTemp.ActiveConnection.Errors.Count > 0 Then
      For Each Err In rstTemp.ActiveConnection.Errors
         MsgBox "Error number: " & Err.Number & vbCr & _
            Err.Description
      Next Err
   End If

   Resume Next

End Sub

Public Sub PrintOutput(rstTemp As ADODB.Recordset)

   ' Enumerate Recordset
   Do While Not rstTemp.EOF
      Debug.Print "  " & rstTemp!Title & _
         ", " & rstTemp!Type
      rstTemp.MoveNext
   Loop

End Sub
'EndExecuteVB

请参阅

Clear 方法 | Command 对象 | Connection 对象 | Error 对象 | Execute 方法 (ADO Command) | Execute 方法 (ADO Connection) | Recordset 对象 | Requery 方法


Filter 和 RecordCount 属性范例 (VB)

本范例打开了 Pubs 数据库的 Publishers 表中的 Recordset，并使用 Filter 属性限制某个国家/地区的发行者能够看到的记录数目。RecordCount 属性用于显示已过滤的记录集和未过滤的记录集之间的差别。

'BeginFilterVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    ' recordset variables
    Dim rstPublishers As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim SQLPublishers As String

     ' criteria variables
    Dim intPublisherCount As Integer
    Dim strCountry As String
    Dim strMessage As String

     ' open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' open recordset with data from Publishers table
    Set rstPublishers = New ADODB.Recordset
    SQLPublishers = "publishers"
    rstPublishers.Open SQLPublishers, strCnxn, adOpenStatic, , adCmdTable

    intPublisherCount = rstPublishers.RecordCount

    ' get user input
    strCountry = Trim(InputBox("Enter a country to filter on (e.g. USA):"))

    If strCountry <> "" Then
        ' open a filtered Recordset object
        rstPublishers.Filter = "Country ='" & strCountry & "'"

        If rstPublishers.RecordCount = 0 Then
            MsgBox "No publishers from that country."
        Else
           ' print number of records for the original recordset
           ' and the filtered recordset
            strMessage = "Orders in original recordset: " & _
                vbCr & intPublisherCount & vbCr & _
                "Orders in filtered recordset (Country = '" & _
                strCountry & "'): " & vbCr & _
                rstPublishers.RecordCount
            MsgBox strMessage
        End If
    End If

    ' clean up
    rstPublishers.Close
    Cnxn.Close
    Set rstPublishers = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstPublishers Is Nothing Then
        If rstPublishers.State = adStateOpen Then rstPublishers.Close
    End If
    Set rstPublishers = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

End Sub
'EndFilterVB
注意 当要选择的数据已知时，使用 SQL 语句打开 Recordset 通常更为有效。本范例显示如何创建唯一的 Recordset 并从特定的国家/地区获取记录。
'BeginFilter2VB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    Dim rstPublishers As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strSQLPublishers As String
    Dim strCnxn As String

     ' open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' open recordset with criteria from Publishers table
    Set rstPublishers = New ADODB.Recordset
    strSQLPublishers = "SELECT * FROM publishers WHERE Country = 'USA'"
    rstPublishers.Open strSQLPublishers, Cnxn, adOpenStatic, adLockReadOnly, adCmdText

    ' print recordset
    rstPublishers.MoveFirst
    Do While Not rstPublishers.EOF
        Debug.Print rstPublishers!pub_name & ", " & rstPublishers!country
        rstPublishers.MoveNext
    Loop

    ' clean up
    rstPublishers.Close
    Cnxn.Close
    Set rstPublishers = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstPublishers Is Nothing Then
        If rstPublishers.State = adStateOpen Then rstPublishers.Close
    End If
    Set rstPublishers = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndFilter2VB

请参阅

Filter 属性 | RecordCount 属性 | Recordset 对象


Find 方法范例 (VB)

本范例使用 Recordset 对象的 Find 方法对 Pubs 数据库中的业务标题数进行定位和计数。范例中假设基本提供者不支持相似的功能。

'BeginFindVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

     ' connection and recordset variables
    Dim Cnxn As New ADODB.Connection
    Dim rstTitles As New ADODB.Recordset
    Dim strCnxn As String
    Dim strSQLTitles As String

     ' record variables
    Dim mark As Variant
    Dim count As Integer

     ' open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' open recordset with default parameters which are
    ' sufficient to search forward through a Recordset
    Set rstTitles = New ADODB.Recordset
    strSQLTitles = "SELECT title_id FROM titles"
    rstTitles.Open strSQLTitles, Cnxn, adOpenStatic, adLockReadOnly, adCmdText

    count = 0
    rstTitles.Find "title_id LIKE 'BU%'"

    Do While Not rstTitles.EOF
        'continue if last find succeeded
        Debug.Print "Title ID: "; rstTitles!title_id
        'count the last title found
        count = count + 1
        ' note current position
        mark = rstTitles.Bookmark
        rstTitles.Find "title_id LIKE 'BU%'", 1, adSearchForward, mark
        ' above code skips current record to avoid finding the same row repeatedly;
        ' last arg (bookmark) is redundant because Find searches from current position
    Loop

    Debug.Print "The number of business titles is " & count

    ' clean up
    rstTitles.Close
    Cnxn.Close
    Set rstTitles = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstTitles Is Nothing Then
        If rstTitles.State = adStateOpen Then rstTitles.Close
    End If
    Set rstTitles = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndFindVB

请参阅

Find 方法 | Recordset 对象


GetRows 方法范例 (VB)

本范例使用 GetRows 方法从 Recordset 中检索指定数目的行，并用结果数据填充一个数组。在两种情况下，GetRows 方法返回的行将少于所需的数目：一种情况是到达了 EOF，另一种情况是 GetRows 试图检索被其他用户删除的记录。仅在发生第二种情况时，该函数才返回 False。运行此过程需要 GetRowsOK 函数。

'BeginGetRowsVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

     ' connection and recordset variables
    Dim rstEmployees As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strSQLEmployees As String
    Dim strCnxn As String
    ' array variable
    Dim arrEmployees As Variant
    ' detail variables
    Dim strMessage As String
    Dim intRows As Integer
    Dim intRecord As Integer

    ' open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' open recordset client-side to enable RecordCount
    Set rstEmployees = New ADODB.Recordset
    strSQLEmployees = "SELECT fName, lName, hire_date FROM Employee ORDER BY lName"
    rstEmployees.Open strSQLEmployees, Cnxn, adOpenStatic, adLockReadOnly, adCmdText

    ' get user input for number of rows
    Do
        strMessage = "Enter number of rows to retrieve:"
        intRows = Val(InputBox(strMessage))

          ' if bad user input exit the loop
        If intRows <= 0 Then
            MsgBox "Please enter a positive number", vbOKOnly, "Not less than zero!"
        ' if number of requested records is over the total
        ElseIf intRows > rstEmployees.RecordCount Then
            MsgBox "Not enough records in Recordset to retrieve " & intRows & " rows.", _
            vbOKOnly, "Over the available total"
        Else
            Exit Do
        End If
    Loop

      ' else put the data in an array and print
    arrEmployees = rstEmployees.GetRows(intRows)

    Dim x As Integer, y As Integer

    For x = 0 To intRows - 1
        For y = 0 To 2
            Debug.Print arrEmployees(y, x) & " ";
        Next y
        Debug.Print vbCrLf
    Next x

    ' clean up
    rstEmployees.Close
    Cnxn.Close
    Set rstEmployees = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstEmployees Is Nothing Then
        If rstEmployees.State = adStateOpen Then rstEmployees.Close
    End If
    Set rstEmployees = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndGetRowsVB

请参阅

GetRows 方法 | Recordset 对象


GetString 方法范例 (VB)

本范例演示 GetString 方法。

假设用户要调试数据访问问题，并且想用一种快速便捷的方式打印小型 Recordset 的当前内容。

'BeginGetStringVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

     ' connection variables
    Dim Cnxn As ADODB.Connection
    Dim rstAuthors As ADODB.Recordset
    Dim strCnxn As String
    Dim strSQLAuthors As String
    Dim varOutput As Variant

     ' specific variables
    Dim strPrompt As String
    Dim strState As String

     ' open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

     ' get user input
    strPrompt = "Enter a state (CA, IN, KS, MD, MI, OR, TN, UT): "
    strState = Trim(InputBox(strPrompt, "GetString Example"))

     ' open recordset
    Set rstAuthors = New ADODB.Recordset
    strSQLAuthors = "SELECT au_fname, au_lname, address, city FROM Authors " & _
                "WHERE state = '" & strState & "'"
    rstAuthors.Open strSQLAuthors, Cnxn, adOpenStatic, adLockReadOnly, adCmdText

    If Not rstAuthors.EOF Then
    ' Use all defaults: get all rows, TAB as column delimiter,
    ' CARRIAGE RETURN as row delimiter, EMPTY-string as null delimiter
       varOutput = rstAuthors.GetString(adClipString)
        ' print output
       Debug.Print "State = '" & strState & "'"
       Debug.Print "Name             Address             City" & vbCr
       Debug.Print varOutput
    Else
       Debug.Print "No rows found for state = '" & strState & "'" & vbCr
    End If

    ' clean up
    rstAuthors.Close
    Cnxn.Close
    Set rstAuthors = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstAuthors Is Nothing Then
        If rstAuthors.State = adStateOpen Then rstAuthors.Close
    End If
    Set rstAuthors = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndGetStringVB

请参阅

GetString 方法 | Recordset 对象


IsolationLevel 和 Mode 属性范例 (VB)

本范例使用 Mode 属性打开独占连接，使用 IsolationLevel 属性打开独立于其他事务执行的事务。

'BeginIsolationLevelVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    Dim Cnxn As ADODB.Connection
    Dim rstTitles As ADODB.Recordset
    Dim strCnxn As String
    Dim strSQLTitles As String

    ' Open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Mode = adModeShareExclusive
    Cnxn.IsolationLevel = adXactIsolated
    Cnxn.Open strCnxn

     ' open Titles table
    Set rstTitles = New ADODB.Recordset
    strSQLTitles = "titles"
    rstTitles.Open strSQLTitles, Cnxn, adOpenDynamic, adLockPessimistic, adCmdTable

    Cnxn.BeginTrans

    ' Display connection mode
    If Cnxn.Mode = adModeShareExclusive Then
        MsgBox "Connection mode is exclusive."
    Else
        MsgBox "Connection mode is not exclusive."
    End If

    ' Display isolation level
    If Cnxn.IsolationLevel = adXactIsolated Then
        MsgBox "Transaction is isolated."
    Else
        MsgBox "Transaction is not isolated."
    End If

    ' Change the type of psychology titles
    Do Until rstTitles.EOF
        If Trim(rstTitles!Type) = "psychology" Then
            rstTitles!Type = "self_help"
            rstTitles.Update
        End If
        rstTitles.MoveNext
    Loop

    ' Print current data in recordset
    rstTitles.Requery
    Do While Not rstTitles.EOF
        Debug.Print rstTitles!Title & " - " & rstTitles!Type
        rstTitles.MoveNext
    Loop

    ' clean up
    rstTitles.Close
    Cnxn.RollbackTrans
    Cnxn.Close
    Set rstTitles = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstTitles Is Nothing Then
        If rstTitles.State = adStateOpen Then rstTitles.Close
    End If
    Set rstTitles = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then
            Cnxn.RollbackTrans
            Cnxn.Close
        End If
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndIsolationLevelVB

请参阅

Connection 对象 | IsolationLevel 属性 | Mode 属性


Item 属性范例 (VB)

本范例演示 Item 属性访问集合成员的方式。本范例使用参数化命令打开 Pubs 数据库的 Authors 表。

从 Command 对象的 Parameters 集合中，按照索引和名称访问针对数据库发出的命令中的参数。然后按索引和名称从该对象的 Fields 集合访问返回的 Recordset 的字段。

'BeginItemVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    Dim Cnxn As ADODB.Connection
    Dim rstAuthors As ADODB.Recordset
    Dim cmd As ADODB.Command
    Dim prm As ADODB.Parameter
    Dim fld As ADODB.Field
    Dim strCnxn As String

    Dim ix As Integer
    Dim limit As Long
    Dim Column(0 To 8) As Variant

    Set Cnxn = New ADODB.Connection
    Set rstAuthors = New ADODB.Recordset
    Set cmd = New ADODB.Command

    'Set the array with the Authors table field (column) names
    Column(0) = "au_id"
    Column(1) = "au_lname"
    Column(2) = "au_fname"
    Column(3) = "phone"
    Column(4) = "address"
    Column(5) = "city"
    Column(6) = "state"
    Column(7) = "zip"
    Column(8) = "contract"

    cmd.CommandText = "SELECT * FROM Authors WHERE state = ?"
    Set prm = cmd.CreateParameter("ItemXparm", adChar, adParamInput, 2, "CA")
    cmd.Parameters.Append prm
     ' set connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn
    cmd.ActiveConnection = Cnxn
     ' open recordset
    rstAuthors.Open cmd, , adOpenStatic, adLockReadOnly
    'Connection and CommandType are omitted because
    'a Command object is provided

    Debug.Print "The Parameters collection accessed by index..."
    Set prm = cmd.Parameters.Item(0)
    Debug.Print "Parameter name = '"; prm.Name; "', value = '"; prm.Value; "'"
    Debug.Print

    Debug.Print "The Parameters collection accessed by name..."
    Set prm = cmd.Parameters.Item("ItemXparm")
    Debug.Print "Parameter name = '"; prm.Name; "', value = '"; prm.Value; "'"
    Debug.Print

    Debug.Print "The Fields collection accessed by index..."

    rstAuthors.MoveFirst
    limit = rstAuthors.Fields.Count - 1
    For ix = 0 To limit
       Set fld = rstAuthors.Fields.Item(ix)
       Debug.Print "Field "; ix; ": Name = '"; fld.Name; _
                   "', Value = '"; fld.Value; "'"
    Next ix

    Debug.Print

    Debug.Print "The Fields collection accessed by name..."

    rstAuthors.MoveFirst
    For ix = 0 To 8
       Set fld = rstAuthors.Fields.Item(Column(ix))
       Debug.Print "Field name = '"; fld.Name; "', Value = '"; fld.Value; "'"
    Next ix

    ' clean up
    rstAuthors.Close
    Cnxn.Close
    Set rstAuthors = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstAuthors Is Nothing Then
        If rstAuthors.State = adStateOpen Then rstAuthors.Close
    End If
    Set rstAuthors = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    Set cmd = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

End Sub
'EndItemVB

请参阅

Command 对象 | Fields 集合 | Item 属性 | Parameters 集合 | Recordset 对象


MarshalOptions 属性范例 (VB)

本范例使用 MarshalOptions 属性指定发送回服务器的行（所有行或已修改的行）。

'BeginMarshalOptionsVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    Dim rstEmployees As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim strSQLEmployees As String

    Dim strOldFirst As String
    Dim strOldLast As String
    Dim strMessage As String
    Dim strMarshalAll As String
    Dim strMarshalModified As String

    ' Open connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Set Cnxn = New ADODB.Connection
    Cnxn.Open strCnxn

    ' open recordset with names from Employees table
    ' and set some properties through object refs
    Set rstEmployees = New ADODB.Recordset
    rstEmployees.CursorType = adOpenKeyset
    rstEmployees.LockType = adLockOptimistic
    rstEmployees.CursorLocation = adUseClient

    strSQLEmployees = "SELECT fname, lname FROM Employee ORDER BY lname"

    rstEmployees.Open strSQLEmployees, Cnxn, , , adCmdText
     ' empty properties have been set above

     ' Store original data
    strOldFirst = rstEmployees!fname
    strOldLast = rstEmployees!lname

    ' Change data in edit buffer
    rstEmployees!fname = "Linda"
    rstEmployees!lname = "Kobara"

    ' Show contents of buffer and get user input
    strMessage = "Edit in progress:" & vbCr & _
        " Original data = " & strOldFirst & " " & _
        strOldLast & vbCr & " Data in buffer = " & _
        rstEmployees!fname & " " & rstEmployees!lname & vbCr & vbCr & _
        "Use Update to replace the original data with " & _
        "the buffered data in the Recordset?"
    strMarshalAll = "Would you like to send all the rows " & _
        "in the recordset back to the server?"
    strMarshalModified = "Would you like to send only " & _
        "modified rows back to the server?"

    If MsgBox(strMessage, vbYesNo) = vbYes Then
        If MsgBox(strMarshalAll, vbYesNo) = vbYes Then
            rstEmployees.MarshalOptions = adMarshalAll
            rstEmployees.Update
        ElseIf MsgBox(strMarshalModified, vbYesNo) = vbYes Then
            rstEmployees.MarshalOptions = adMarshalModifiedOnly
            rstEmployees.Update
        End If
    End If

    ' sShow the resulting data
    MsgBox "Data in recordset = " & rstEmployees!fname & " " & _
        rstEmployees!lname

    ' restore original data because this is a demonstration
    If Not (strOldFirst = rstEmployees!fname And _
            strOldLast = rstEmployees!lname) Then
        rstEmployees!fname = strOldFirst
        rstEmployees!lname = strOldLast
        rstEmployees.Update
    End If

    ' clean up
    rstEmployees.Close
    Cnxn.Close
    Set rstEmployees = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstEmployees Is Nothing Then
        If rstEmployees.State = adStateOpen Then rstEmployees.Close
    End If
    Set rstEmployees = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndMarshalOptionsVB

请参阅

MarshalOptions 属性 | MarshalOptionsEnum


MaxRecords 属性范例 (VB)

本范例使用 MaxRecords 属性打开包含 Titles 表中 10 个最有价值标题的 Recordset。

'BeginMaxRecordsVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    Dim rstTitles As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim strSQLTitles As String

    ' Open a connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open recordset containing the 10 most expensive
    ' titles in the Titles table
    Set rstTitles = New ADODB.Recordset
    rstTitles.MaxRecords = 10

    strSQLTitles = "SELECT Title, Price FROM Titles ORDER BY Price DESC"
    rstTitles.Open strSQLTitles, strCnxn, adOpenStatic, adLockReadOnly, adCmdText

    ' Display the contents of the recordset
    Debug.Print "Top Ten Titles by Price:"

    Do Until rstTitles.EOF
        Debug.Print "  " & rstTitles!Title & " - " & rstTitles!Price
        rstTitles.MoveNext
    Loop

    ' clean up
    rstTitles.Close
    Cnxn.Close
    Set rstTitles = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstTitles Is Nothing Then
        If rstTitles.State = adStateOpen Then rstTitles.Close
    End If
    Set rstTitles = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndMaxRecordsVB

请参阅

MaxRecords 属性 | Recordset 对象


Move 方法范例 (VB)

本范例使用 Move 方法按用户输入定位记录指针。

'BeginMoveVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    ' connection and recordset variables
    Dim rstAuthors As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim strSQLAuthors As String
     ' record variables
    Dim varBookmark As Variant
    Dim strCommand As String
    Dim lngMove As Long

    ' Open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open recordset from Authors table
    Set rstAuthors = New ADODB.Recordset
    rstAuthors.CursorLocation = adUseClient
    ' Use client cursor to allow use of AbsolutePosition property
    strSQLAuthors = "SELECT au_id, au_fname, au_lname, city, state FROM Authors ORDER BY au_lname"
    rstAuthors.Open strSQLAuthors, strCnxn, adOpenStatic, adLockOptimistic, adCmdText

    rstAuthors.MoveFirst

    Do
        ' Display information about current record and
        ' ask how many records to move

        strCommand = InputBox( _
            "Record " & rstAuthors.AbsolutePosition & _
            " of " & rstAuthors.RecordCount & vbCr & _
            "Author: " & rstAuthors!au_fname & _
            " " & rstAuthors!au_lname & vbCr & _
            "Location: " & rstAuthors!city & _
            ", " & rstAuthors!State & vbCr & vbCr & _
            "Enter number of records to Move " & _
            "(positive or negative).")

          ' this is for exiting the loop
        'lngMove = CLng(strCommand)

        lngMove = CLng(Val(strCommand))
        If lngMove = 0 Then
            MsgBox "You either entered a non-number or canceled the input box. Exit the application."
            Exit Do
        End If

        ' Store bookmark in case the Move goes too far
        ' forward or backward
        varBookmark = rstAuthors.Bookmark

        ' Move method requires parameter of data type Long
        rstAuthors.Move lngMove

        ' Trap for BOF or EOF
        If rstAuthors.BOF Then
            MsgBox "Too far backward! Returning to current record."
            rstAuthors.Bookmark = varBookmark
        End If
        If rstAuthors.EOF Then
            MsgBox "Too far forward!  Returning to current record."
            rstAuthors.Bookmark = varBookmark
        End If
    Loop

    ' clean up
    rstAuthors.Close
    Cnxn.Close
    Set rstAuthors = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstAuthors Is Nothing Then
        If rstAuthors.State = adStateOpen Then rstAuthors.Close
    End If
    Set rstAuthors = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndMoveVB

请参阅

Move 方法 | Recordset 对象


MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法范例 (VB)

本范例使用 MoveFirst、MoveLast、MoveNext 以及 MovePrevious 方法，按照提供的命令移动 Recordset 记录指针。运行此过程需要 MoveAny 过程。

'BeginMoveFirstVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    ' connection and recordset variables
    Dim rstAuthors As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim strSQLAuthors
     ' record variables
    Dim strMessage As String
    Dim intCommand As Integer

    ' Open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open recordset from Authors table
    Set rstAuthors = New ADODB.Recordset
    rstAuthors.CursorLocation = adUseClient
    ' Use client cursor to enable AbsolutePosition property
    strSQLAuthors = "Authors"
    rstAuthors.Open strSQLAuthors, Cnxn, adOpenStatic, adLockReadOnly, adCmdTable

    ' Show current record information and get user's method choice
    Do
        strMessage = "Name: " & rstAuthors!au_fname & " " & _
            rstAuthors!au_lname & vbCr & "Record " & _
            rstAuthors.AbsolutePosition & " of " & _
            rstAuthors.RecordCount & vbCr & vbCr & _
            "[1 - MoveFirst, 2 - MoveLast, " & vbCr & _
            "3 - MoveNext, 4 - MovePrevious]"
        intCommand = Val(Left(InputBox(strMessage), 1))

         ' for exiting the loop
        If intCommand < 1 Or intCommand > 4 Then
            MsgBox "You either entered a non-number or canceled the input box. Exit the application."
            Exit Do
        End If

        ' Use specified method while trapping for BOF and EOF
        Select Case intCommand
            Case 1
                rstAuthors.MoveFirst
            Case 2
                rstAuthors.MoveLast
            Case 3
                rstAuthors.MoveNext
                If rstAuthors.EOF Then
                    MsgBox "Already at end of recordset!"
                    rstAuthors.MoveLast
                End If
            Case 4
                rstAuthors.MovePrevious
                If rstAuthors.BOF Then
                    MsgBox "Already at beginning of recordset!"
                    rstAuthors.MoveFirst
                End If
        End Select
    Loop

    ' clean up
    rstAuthors.Close
    Cnxn.Close
    Set rstAuthors = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstAuthors Is Nothing Then
        If rstAuthors.State = adStateOpen Then rstAuthors.Close
    End If
    Set rstAuthors = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub

'EndMoveFirstVB

请参阅

MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法 | Recordset 对象


NextRecordset 方法范例 (VB)

本范例使用 NextRecordset 方法，查看使用复合命令语句的记录集中的数据，其中的复合命令语句由三个独立 SELECT 语句组成。

'BeginNextRecordsetVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    ' connection and recordset variables
    Dim rstCompound As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim SQLCompound As String

    Dim intCount As Integer

    ' Open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open compound recordset
    Set rstCompound = New ADODB.Recordset
    SQLCompound = "SELECT * FROM Authors; " & _
        "SELECT * FROM stores; " & _
        "SELECT * FROM jobs"
    rstCompound.Open SQLCompound, Cnxn, adOpenStatic, adLockReadOnly, adCmdText

    ' Display results from each SELECT statement
    intCount = 1
    Do Until rstCompound Is Nothing
        Debug.Print "Contents of recordset #" & intCount

        Do Until rstCompound.EOF
            Debug.Print , rstCompound.Fields(0), rstCompound.Fields(1)
            rstCompound.MoveNext
        Loop

        Set rstCompound = rstCompound.NextRecordset
        intCount = intCount + 1
    Loop

    ' clean up
    Cnxn.Close
    Set rstCompound = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstCompound Is Nothing Then
        If rstCompound.State = adStateOpen Then rstCompound.Close
    End If
    Set rstCompound = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndNextRecordsetVB

请参阅

NextRecordset 方法 | Recordset 对象


NumericScale 和 Precision 属性范例 (VB)

本范例使用 NumericScale 和 Precision 属性来显示在 Pubs 数据库 Discounts 表中的字段的数值范围和精度。

'BeginNumericScaleVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    ' connection and recordset variables
    Dim rstDiscounts As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim fldTemp As ADODB.Field
    Dim strCnxn As String
    Dim strSQLDiscounts As String

    ' Open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open recordset
    Set rstDiscounts = New ADODB.Recordset
    strSQLDiscounts = "Discounts"
    rstDiscounts.Open strSQLDiscounts, Cnxn, adOpenStatic, adLockReadOnly, adCmdTable

    ' Display numeric scale and precision of
    ' numeric and small integer fields
    For Each fldTemp In rstDiscounts.Fields
        If fldTemp.Type = adNumeric Or fldTemp.Type = adSmallInt Then
            MsgBox "Field: " & fldTemp.Name & vbCr & _
                "Numeric scale: " & _
                fldTemp.NumericScale & vbCr & _
                "Precision: " & fldTemp.Precision
        End If
    Next fldTemp

    ' clean up
    rstDiscounts.Close
    Cnxn.Close
    Set rstDiscounts = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstDiscounts Is Nothing Then
        If rstDiscounts.State = adStateOpen Then rstDiscounts.Close
    End If
    Set rstDiscounts = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

End Sub
'EndNumericScaleVB

请参阅

Field 对象 | NumericScale 属性 | Parameter 对象 | Precision 属性


Open 和 Close 方法范例 (VB)

本范例在已打开的 Recordset 和 Connection 对象上使用 Open 和 Close 方法。

'BeginOpenVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub OpenX()
    On Error GoTo ErrorHandler

    Dim Cnxn As ADODB.Connection
    Dim rstEmployees As ADODB.Recordset
    Dim strCnxn As String
    Dim strSQLEmployees As String
    Dim varDate As Variant

    ' Open connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Set Cnxn = New ADODB.Connection
    Cnxn.Open strCnxn

    ' Open employee table
    Set rstEmployees = New ADODB.Recordset
    strSQLEmployees = "employee"
    rstEmployees.Open strSQLEmployees, Cnxn, adOpenKeyset, adLockOptimistic, adCmdTable

    ' Assign the first employee record's hire date
    ' to a variable, then change the hire date
    varDate = rstEmployees!hire_date
    Debug.Print "Original data"
    Debug.Print "  Name - Hire Date"
    Debug.Print "  " & rstEmployees!fname & " " & _
        rstEmployees!lname & " - " & rstEmployees!hire_date
    rstEmployees!hire_date = #1/1/1900#
    rstEmployees.Update
    Debug.Print "Changed data"
    Debug.Print "  Name - Hire Date"
    Debug.Print "  " & rstEmployees!fname & " " & _
        rstEmployees!lname & " - " & rstEmployees!hire_date

    ' Requery Recordset and reset the hire date
    rstEmployees.Requery
    rstEmployees!hire_date = varDate
    rstEmployees.Update
    Debug.Print "Data after reset"
    Debug.Print "  Name - Hire Date"
    Debug.Print "  " & rstEmployees!fname & " " & _
       rstEmployees!lname & " - " & rstEmployees!hire_date

    ' clean up
    rstEmployees.Close
    Cnxn.Close
    Set rstEmployees = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstEmployees Is Nothing Then
        If rstEmployees.State = adStateOpen Then rstEmployees.Close
    End If
    Set rstEmployees = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndOpenVB

请参阅

Close 方法 | Connection 对象 | Open 方法 (ADO Connection) | Open 方法 (ADO Recordset) | Recordset 对象


OpenSchema 方法范例 (VB)

本范例使用 OpenSchema 方法显示 Pubs 数据库中每个表的名称和类型。

'BeginOpenSchemaVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub OpenSchemaX()
    On Error GoTo ErrorHandler

    Dim Cnxn As ADODB.Connection
    Dim rstSchema As ADODB.Recordset
    Dim strCnxn As String

    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    Set rstSchema = Cnxn.OpenSchema(adSchemaTables)

    Do Until rstSchema.EOF
        Debug.Print "Table name: " & _
            rstSchema!TABLE_NAME & vbCr & _
            "Table type: " & rstSchema!TABLE_TYPE & vbCr
        rstSchema.MoveNext
    Loop

    ' clean up
    rstSchema.Close
    Cnxn.Close
    Set rstSchema = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstSchema Is Nothing Then
        If rstSchema.State = adStateOpen Then rstSchema.Close
    End If
    Set rstSchema = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndOpenSchemaVB

本范例在 OpenSchema 方法的 Criteria 参数中指定 TABLE_TYPE 查询约束。其结果是只返回在 Pubs 数据库中所指定视图的模式信息。然后该范例显示每个表的名称和类型。

'BeginOpenSchema2VB
Public Sub Main()
    On Error GoTo ErrorHandler

    Dim Cnxn2 As ADODB.Connection
    Dim rstSchema As ADODB.Recordset
    Dim strCnxn As String

    Set Cnxn2 = New ADODB.Connection
    strCnxn = "Provider=sqloledb;" & _
        "Data Source=MySqlServer;Initial Catalog=Pubs;Integrated Security=SSPI; "
    Cnxn2.Open strCnxn

    Set rstSchema = Cnxn2.OpenSchema(adSchemaTables, Array(Empty, Empty, Empty, "VIEW"))

    Do Until rstSchema.EOF
        Debug.Print "Table name: " & _
            rstSchema!TABLE_NAME & vbCr & _
            "Table type: " & rstSchema!TABLE_TYPE & vbCr
        rstSchema.MoveNext
    Loop

    ' clean up
    rstSchema.Close
    Cnxn2.Close
    Set rstSchema = Nothing
    Set Cnxn2 = Nothing
    Exit Sub

ErrorHandler:
   ' clean up
    If Not rstSchema Is Nothing Then
        If rstSchema.State = adStateOpen Then rstSchema.Close
    End If
    Set rstSchema = Nothing

    If Not Cnxn2 Is Nothing Then
        If Cnxn2.State = adStateOpen Then Cnxn2.Close
    End If
    Set Cnxn2 = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndOpenSchema2VB

请参阅

OpenSchema 方法 | Recordset 对象


Optimize 属性范例 (VB)

本范例演示 Field 对象的动态 Optimize 属性。Pubs 数据库中 Authors 表的 Zip 字段未被索引。将 zip 字段的 Optimize 属性设置为 True 将授权 ADO 建立索引，以提高 Find 方法的性能。

'BeginOptimizeVB
Public Sub Main()
    On Error GoTo ErrorHandler

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

    ' recordset and connection variables
    Dim Cnxn As ADODB.Connection
    Dim rstAuthors As ADODB.Recordset
    Dim strCnxn As String
    Dim strSQLAuthors As String

     ' Open connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Set Cnxn = New ADODB.Connection
    Cnxn.Open strCnxn

     ' open recordset client-side to enable index creation
    Set rstAuthors = New ADODB.Recordset
    rstAuthors.CursorLocation = adUseClient
    strSQLAuthors = "SELECT * FROM Authors"
    rstAuthors.Open strSQLAuthors, Cnxn, adOpenStatic, adLockReadOnly, adCmdText
     ' Create the index
    rstAuthors!zip.Properties("Optimize") = True
     ' Find Akiko Yokomoto
    rstAuthors.Find "zip = '94595'"

     ' show results
    Debug.Print rstAuthors!au_fname & " " & rstAuthors!au_lname & " " & _
             rstAuthors!address & " " & rstAuthors!city & " " & rstAuthors!State
    rstAuthors!zip.Properties("Optimize") = False  'Delete the index

    ' clean up
    rstAuthors.Close
    Cnxn.Close
    Set rstAuthors = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstAuthors Is Nothing Then
        If rstAuthors.State = adStateOpen Then rstAuthors.Close
    End If
    Set rstAuthors = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndOptimizeVB

请参阅

Field 对象 | Optimize 动态属性 (ADO)


OriginalValue 和 UnderlyingValue 属性范例 (VB)

本范例演示 OriginalValue 和 UnderlyingValue 属性。如果在 Recordset 批更新过程中记录的基本数据发生了更改，就会显示一条信息。

'BeginOriginalValueVB
Public Sub Main()
    On Error GoTo ErrorHandler

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

    Dim Cnxn As ADODB.Connection
    Dim rstTitles As ADODB.Recordset
    Dim fldType As ADODB.Field
    Dim strCnxn As String
    Dim strSQLTitles As String

    ' Open connection.
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open recordset for batch update
    ' using object refs to set properties
    Set rstTitles = New ADODB.Recordset
    Set rstTitles.ActiveConnection = Cnxn
    rstTitles.CursorType = adOpenKeyset
    rstTitles.LockType = adLockBatchOptimistic
    strSQLTitles = "titles"
    rstTitles.Open strSQLTitles

    ' Set field object variable for Type field
    Set fldType = rstTitles!Type

    ' Change the type of psychology titles
    Do Until rstTitles.EOF
        If Trim(fldType) = "psychology" Then
            fldType = "self_help"
        End If
        rstTitles.MoveNext
    Loop

    ' Similate a change by another user by updating
    ' data using a command string
    Cnxn.Execute "UPDATE Titles SET type = 'sociology' " & _
       "WHERE type = 'psychology'"

    'Check for changes
    rstTitles.MoveFirst
    Do Until rstTitles.EOF
        If fldType.OriginalValue <> fldType.UnderlyingValue Then
            MsgBox "Data has changed!" & vbCr & vbCr & _
                "  Title ID: " & rstTitles!title_id & vbCr & _
                "  Current value: " & fldType & vbCr & _
                "  Original value: " & _
                fldType.OriginalValue & vbCr & _
                "  Underlying value: " & _
                fldType.UnderlyingValue & vbCr
        End If
    rstTitles.MoveNext
    Loop

    ' Cancel the update because this is a demonstration
    rstTitles.CancelBatch

    ' Restore original values
    Cnxn.Execute "UPDATE Titles SET type = 'psychology' " & _
        "WHERE type = 'sociology'"

    ' clean up
    rstTitles.Close
    Cnxn.Close
    Set rstTitles = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstTitles Is Nothing Then
        If rstTitles.State = adStateOpen Then rstTitles.Close
    End If
    Set rstTitles = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndOriginalValueVB

请参阅

OriginalValue 属性 | Recordset 对象 | UnderlyingValue 属性


Prepared 属性范例 (VB)

本范例打开两个 Command 对象（一个已准备好，另一个未准备好），来演示 Prepared 属性。

'BeginPreparedVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    Dim Cnxn As ADODB.Connection
    Dim cmd1 As ADODB.Command
    Dim cmd2 As ADODB.Command

    Dim strCnxn As String
    Dim strCmd As String
    Dim sngStart As Single
    Dim sngEnd As Single
    Dim sngNotPrepared As Single
    Dim sngPrepared As Single
    Dim intLoop As Integer

    ' Open a connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Set Cnxn = New ADODB.Connection
    Cnxn.Open strCnxn

    ' Create two command objects for the same
    ' command - one prepared and one not prepared
    strCmd = "SELECT title, type FROM Titles ORDER BY type"

    Set cmd1 = New ADODB.Command
    Set cmd1.ActiveConnection = Cnxn
    cmd1.CommandText = strCmd

    Set cmd2 = New ADODB.Command
    Set cmd2.ActiveConnection = Cnxn
    cmd2.CommandText = strCmd
    cmd2.Prepared = True

    ' Set a timer, then execute the unprepared
    ' command 20 times
    sngStart = Timer
    For intLoop = 1 To 20
        cmd1.Execute
    Next intLoop
    sngEnd = Timer
    sngNotPrepared = sngEnd - sngStart

    ' Reset the timer, then execute the prepared
    ' command 20 times
    sngStart = Timer
    For intLoop = 1 To 20
        cmd2.Execute
    Next intLoop
    sngEnd = Timer
    sngPrepared = sngEnd - sngStart

    ' Display performance results
    MsgBox "Performance Results:" & vbCr & _
        "   Not Prepared: " & Format(sngNotPrepared, _
        "##0.000") & " seconds" & vbCr & _
        "   Prepared: " & Format(sngPrepared, _
        "##0.000") & " seconds"

    ' clean up
    Cnxn.Close
    Set Cnxn = Nothing
    Set cmd1 = Nothing
    Set cmd2 = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    Set cmd1 = Nothing
    Set cmd2 = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndPreparedVB

请参阅

Command 对象 | Prepared 属性


Provider 和 DefaultDatabase 属性范例 (VB)

本范例通过打开三个使用不同提供者的 Connection 对象来演示 Provider 属性。范例中还使用 DefaultDatabase 属性设置 Microsoft ODBC Provider 的默认数据库。

'BeginProviderVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection strings

Public Sub Main()
    On Error GoTo ErrorHandler

    Dim Cnxn1 As ADODB.Connection
    Dim Cnxn2 As ADODB.Connection
    Dim Cnxn3 As ADODB.Connection
    Dim strCnxn As String

    ' Open a connection using the Microsoft ODBC provider
    Set Cnxn1 = New ADODB.Connection
    Cnxn1.ConnectionString = "driver={SQL Server};server='MySqlServer';" & _
        "user id='MyUserID';password='MyPassword';"
    Cnxn1.Open strCnxn
    Cnxn1.DefaultDatabase = "Pubs"

    ' Display the provider
    MsgBox "Cnxn1 provider: " & Cnxn1.Provider

    ' Open a connection using the Microsoft Jet provider
    Set Cnxn2 = New ADODB.Connection
    Cnxn2.Provider = "Microsoft.Jet.OLEDB.4.0"
    Cnxn2.Open "C:\Program Files\Microsoft Office\Office\Samples\northwind.mdb", _
        "MyUserID", "MyPassword"

    ' Display the provider.
    MsgBox "Cnxn2 provider: " & Cnxn2.Provider

    ' Open a connection using the Microsoft SQL Server provider
    Set Cnxn3 = New ADODB.Connection
    Cnxn3.Provider = "sqloledb"
    Cnxn3.Open "Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"

    ' Display the provider
    MsgBox "Cnxn3 provider: " & Cnxn3.Provider

    ' clean up
    Cnxn1.Close
    Cnxn2.Close
    Cnxn3.Close
    Set Cnxn1 = Nothing
    Set Cnxn2 = Nothing
    Set Cnxn3 = Nothing
    Exit Sub

ErrorHandler:
    If Not Cnxn1 Is Nothing Then
        If Cnxn1.State = adStateOpen Then Cnxn1.Close
    End If
    Set Cnxn1 = Nothing

    If Not Cnxn2 Is Nothing Then
        If Cnxn2.State = adStateOpen Then Cnxn2.Close
    End If
    Set Cnxn2 = Nothing

    If Not Cnxn3 Is Nothing Then
        If Cnxn3.State = adStateOpen Then Cnxn3.Close
    End If
    Set Cnxn3 = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

End Sub
'EndProviderVB

请参阅

Connection 对象 | DefaultDatabase 属性 | Provider 属性


Read、ReadText、Write 和 WriteText 方法范例 (VB)

本范例演示将文本框的内容读入文本 Stream 和二进制 Stream 的方式。显示的其他属性和方法包括 Position、Size、Charset 和 SetEOS。

'BeginReadVB
Private Sub cmdRead_Click()
    On Error GoTo ErrorHandler

    'Declare variables
    Dim objStream As Stream
    Dim varA As Variant
    Dim bytA() As Byte
    Dim i As Integer
    Dim strBytes As String

    'Instantiate and Open Stream
    Set objStream = New Stream
    objStream.Open

    'Write the text content of a textbox to the stream
    If Text1.Text = "" Then
        Err.Raise 1, , "The text field is blank."
    End If
    objStream.WriteText Text1.Text

    'Display the text contents and size of the stream
    objStream.Position = 0
    Debug.Print "Default text:"
    Debug.Print objStream.ReadText
    Debug.Print objStream.Size

    'Switch character set and display
    objStream.Position = 0
    objStream.Charset = "Windows-1252"
    Debug.Print "New Charset text:"
    Debug.Print objStream.ReadText
    Debug.Print objStream.Size

    'Switch to a binary stream and display
    objStream.Position = 0
    objStream.Type = adTypeBinary
    Debug.Print "Binary:"
    Debug.Print objStream.Read
    Debug.Print objStream.Size

    'Load an array of bytes with the text box text
    ReDim bytA(Len(Text1.Text))
    For i = 1 To Len(Text1.Text)
        bytA(i - 1) = CByte(Asc(Mid(Text1.Text, i, 1)))
    Next

    'Write the buffer to the binary stream and display
    objStream.Position = 0
    objStream.Write bytA()
    objStream.SetEOS
    objStream.Position = 0
    Debug.Print "Binary after Write:"
    Debug.Print objStream.Read
    Debug.Print objStream.Size

    'Switch back to a text stream and display
    Debug.Print "Translated back:"
    objStream.Position = 0
    objStream.Type = adTypeText
    Debug.Print objStream.ReadText
    Debug.Print objStream.Size

    ' clean up
    objStream.Close
    Set objStream = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not objStream Is Nothing Then
        If objStream.State = adStateOpen Then objStream.Close
    End If
    Set objStream = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndReadVB

请参阅

Charset 属性 | Position 属性 | Read 方法 | ReadText 方法 | SetEOS 方法 | Size 属性 (ADO Stream) | Stream 对象 | Write 方法 | WriteText 方法


Refresh 方法范例 (VB)

本范例演示使用 Refresh 方法来刷新存储过程 Command 对象的 Parameters 集合。

Option Explicit

'BeginRefreshVB
Public Sub Main()
    On Error GoTo ErrorHandler

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection strings

    ' connection and recordset variables
    Dim Cnxn As ADODB.Connection
    Dim cmdByRoyalty As ADODB.Command
    Dim rstByRoyalty As ADODB.Recordset
    Dim rstAuthors As ADODB.Recordset
    Dim strCnxn As String
    Dim strSQLAuthors As String
     ' record variables
    Dim intRoyalty As Integer
    Dim strAuthorID As String
    Dim strRoyalty As String

    ' Open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open a command object for a stored procedure
    ' with one parameter
    Set cmdByRoyalty = New ADODB.Command
    Set cmdByRoyalty.ActiveConnection = Cnxn
    cmdByRoyalty.CommandText = "byroyalty"
    cmdByRoyalty.CommandType = adCmdStoredProc
    cmdByRoyalty.Parameters.Refresh

    ' Get paramater value, execute the command
    ' and store the results in a recordset
    strRoyalty = InputBox("Enter royalty:")
    If strRoyalty = "" Then
        Err.Raise 1, , "You either didn't enter royalty or canceled the input box. Exit the application"
    End If

    intRoyalty = Trim(strRoyalty)
    cmdByRoyalty.Parameters(1) = intRoyalty
    Set rstByRoyalty = cmdByRoyalty.Execute()

    ' Open the Authors table to get author names for display
    Set rstAuthors = New ADODB.Recordset
    strSQLAuthors = "Authors"
    rstAuthors.Open strSQLAuthors, Cnxn, adOpenForwardOnly, adLockPessimistic, adCmdTable

    ' Print current data in the recordset
    ' and add author names
    Debug.Print "Authors with " & intRoyalty & " percent royalty"

    Do Until rstByRoyalty.EOF
        strAuthorID = rstByRoyalty!au_id
        Debug.Print "   " & rstByRoyalty!au_id & ", ";
        rstAuthors.Filter = "au_id = '" & strAuthorID & "'"
        Debug.Print rstAuthors!au_fname & " "; rstAuthors!au_lname
        rstByRoyalty.MoveNext
    Loop

    ' clean up
    rstByRoyalty.Close
    rstAuthors.Close
    Cnxn.Close
    Set rstByRoyalty = Nothing
    Set rstAuthors = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstByRoyalty Is Nothing Then
        If rstByRoyalty.State = adStateOpen Then rstByRoyalty.Close
    End If
    Set rstByRoyalty = Nothing

    If Not rstAuthors Is Nothing Then
        If rstAuthors.State = adStateOpen Then rstAuthors.Close
    End If
    Set rstAuthors = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndRefreshVB

请参阅

Command 对象 | Parameters 集合 | Refresh 方法


Resync 方法范例 (VB)

本范例演示使用 Resync 方法来刷新静态记录集中的数据。

'BeginResyncVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection strings

Public Sub Main()
    On Error GoTo ErrorHandler

    'connection and recordset variables
    Dim Cnxn As ADODB.Connection
    Dim rstTitles As ADODB.Recordset
    Dim strCnxn As String
    Dim strSQLTitles As String

    ' Open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open recordset using object refs to set properties
    ' that allow for updates to the database
    Set rstTitles = New ADODB.Recordset
    Set rstTitles.ActiveConnection = Cnxn
    rstTitles.CursorType = adOpenKeyset
    rstTitles.LockType = adLockOptimistic

    strSQLTitles = "titles"
    rstTitles.Open strSQLTitles

    'rstTitles.Open strSQLTitles, Cnxn, adOpenKeyset, adLockPessimistic, adCmdTable
    'the above line of code passes the same refs as the object refs listed above

    ' Change the type of the first title in the recordset
    rstTitles!Type = "database"

    ' Display the results of the change
    MsgBox "Before resync: " & vbCr & vbCr & _
        "Title - " & rstTitles!Title & vbCr & _
        "Type - " & rstTitles!Type

    ' Resync with database and redisplay results
    rstTitles.Resync
    MsgBox "After resync: " & vbCr & vbCr & _
        "Title - " & rstTitles!Title & vbCr & _
        "Type - " & rstTitles!Type

    ' clean up
    rstTitles.CancelBatch
    rstTitles.Close
    Cnxn.Close
    Set rstTitles = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstTitles Is Nothing Then
        If rstTitles.State = adStateOpen Then
            rstTitles.CancelBatch
            rstTitles.Close
        End If
    End If
    Set rstTitles = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndResyncVB

请参阅

Recordset 对象 | Resync 方法


Save 和 Open 方法范例 (VB)

这三个范例演示如何配合使用 Save 和 Open 方法。

假设用户在出差时要携带数据库中的一个表。在出发前，用户以 Recordset 访问数据，并将其保存为便携格式。在到达目的地后，用户以本地、断开连接的 Recordset 访问 Recordset，在修改 Recordset 后将其保存。最后，当用户回家后，再次连接数据库并用旅途中所做的更改对其进行更新。

首先，访问并保存 Authors 表。

'BeginSaveVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    'recordset and connection variables
    Dim rstAuthors As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim strSQLAuthors As String

    ' Open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    Set rstAuthors = New ADODB.Recordset
    strSQLAuthors = "SELECT au_id, au_lname, au_fname, city, phone FROM Authors"
    rstAuthors.Open strSQLAuthors, Cnxn, adOpenDynamic, adLockOptimistic, adCmdText

    'For sake of illustration, save the Recordset to a diskette in XML format
    rstAuthors.Save "c:\Pubs.xml", adPersistXML

    ' clean up
    rstAuthors.Close
    Cnxn.Close
    Set rstAuthors = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    'clean up
    If Not rstAuthors Is Nothing Then
        If rstAuthors.State = adStateOpen Then rstAuthors.Close
    End If
    Set rstAuthors = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndSaveVB

现在用户已到达目的地。以本地、断开连接的 Recordset 访问 Authors 表。请注意，要访问保存的文件 a:\Pubs.xml，必须在用户使用的机器上装有 MSPersist 提供者。

'BeginSave2VB
Public Sub Main()
    On Error GoTo ErrorHandler

    Dim rst As ADODB.Recordset
    Set rst = New ADODB.Recordset

    'For sake of illustration, we specify all parameters
    rst.Open "c:\Pubs.xml", "Provider=MSPersist;", adOpenForwardOnly, adLockBatchOptimistic, adCmdFile

    'Now you have a local, disconnected Recordset - Edit as you desired
    '(In this example the change makes no difference)
    rst.Find "au_lname = 'Carson'"
    If rst.EOF Then
       Debug.Print "Name not found."
       Exit Sub
    End If

    rst!city = "Chicago"
    rst.Update

    'Save changes in ADTG format this time, purely for sake of illustration.
    'Note that the previous version is still on the diskette, as a:\Pubs.xml.
    rst.Save "c:\Pubs.adtg", adPersistADTG

    ' clean up
    rst.Close
    Set rst = Nothing
    Exit Sub

ErrorHandler:
    'clean up
    If Not rst Is Nothing Then
        If rst.State = adStateOpen Then rst.Close
    End If
    Set rst = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndSave2VB

最后用户回到家里。现在用所做的更改更新数据库。

'BeginSave3VB
Public Sub Main()
    On Error GoTo ErrorHandler

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

    Dim Cnxn As New ADODB.Connection
    Dim rst As ADODB.Recordset
    Dim strCnxn As String

    Set rst = New ADODB.Recordset
    ' The lock mode is batch optimistic because we are going to
    ' use the UpdateBatch method.
    rst.Open "c:\Pubs.adtg", "Provider=MSPersist;", adOpenForwardOnly, adLockBatchOptimistic, adCmdFile

     ' Connect to the database, associate the Recordset with the connection
     ' then update the database table with the changed Recordset
    strCnxn = "Provider=SQLOLEDB;Data Source=MySqlServer;Integrated Security=SSPI;Initial Catalog=pubs;"
    Cnxn.Open strCnxn

    rst.ActiveConnection = Cnxn
    rst.UpdateBatch

    ' clean up
    rst.Close
    Cnxn.Close
    Set rst = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    'clean up
    If Not rst Is Nothing Then
        If rst.State = adStateOpen Then rst.Close
    End If
    Set rst = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndSave3VB

请参阅

Open 方法 (ADO Recordset) | Recordset 对象 | Recordset 持久性 | Save 方法


Seek 方法和 Index 属性范例 (VB)

本范例使用 Recordset 对象的 Seek 方法和 Index 属性，以及给定的 Employee ID，共同定位 Nwind.mdb 数据库 Employees 表中的雇员名。

'BeginSeekVB
Public Sub Main()
    On Error GoTo ErrorHandler

    ' To integrate this code replace the data source
    ' in the connection string

     'recordset and connection variables
    Dim rstEmployees As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim strSQLEmployees As String

    Dim strID As String
    Dim strPrompt As String
    strPrompt = "Enter an EmployeeID (e.g., 1 to 9)"

    ' Open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='Microsoft.Jet.OLEDB.4.0';" & _
                "Data Source='c:\Program Files\Microsoft Office\Office\Samples\northwind.mdb';"
    Cnxn.Open strCnxn

     ' open recordset server-side for indexing
    Set rstEmployees = New ADODB.Recordset
    rstEmployees.CursorLocation = adUseServer
    strSQLEmployees = "employees"
    rstEmployees.Open strSQLEmployees, strCnxn, adOpenKeyset, adLockReadOnly, adCmdTableDirect

    ' Does this provider support Seek and Index?
    If rstEmployees.Supports(adIndex) And rstEmployees.Supports(adSeek) Then
        rstEmployees.Index = "PrimaryKey"
        ' Display all the employees
            rstEmployees.MoveFirst
            Do While rstEmployees.EOF = False
                Debug.Print rstEmployees!EmployeeId; ": "; rstEmployees!firstname; " "; _
                    rstEmployees!LastName
                rstEmployees.MoveNext
            Loop

    ' Prompt the user for an EmployeeID between 1 and 9
          rstEmployees.MoveFirst
          Do
             strID = LCase(Trim(InputBox(strPrompt, "Seek Example")))
             ' Quit if strID is a zero-length string (CANCEL, null, etc.)
             If Len(strID) = 0 Then Exit Do
             If Len(strID) = 1 And strID >= "1" And strID <= "9" Then
                rstEmployees.Seek Array(strID), adSeekFirstEQ
                If rstEmployees.EOF Then
                   Debug.Print "Employee not found."
                Else
                   Debug.Print strID; ": Employee='"; rstEmployees!firstname; " "; _
                   rstEmployees!LastName; "'"
                End If
             End If
          Loop
    End If

    ' clean up
    rstEmployees.Close
    Cnxn.Close
    Set rstEmployees = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstEmployees Is Nothing Then
        If rstEmployees.State = adStateOpen Then rstEmployees.Close
    End If
    Set rstEmployees = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndSeekVB

请参阅

Index 属性 | Recordset 对象 | Seek 方法


Sort 属性范例 (VB)

本范例使用 Recordset 对象的 Sort 属性来调整 Recordset 中行的顺序，该 Recordset 来自 Pubs 数据库的 Authors 表。辅助实用程序例程将打印每一行。

'BeginSortVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

     ' connection and recordset variables
    Dim Cnxn As New ADODB.Connection
    Dim rstAuthors As New ADODB.Recordset
    Dim strCnxn As String
    Dim strSQLAuthors As String

    Dim strTitle As String

    ' Open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' open client-side recordset to enable sort method
    Set rstAuthors = New ADODB.Recordset
    rstAuthors.CursorLocation = adUseClient
    strSQLAuthors = "SELECT * FROM Authors"
    rstAuthors.Open strSQLAuthors, Cnxn, adOpenStatic, adLockReadOnly, adCmdText

     ' sort the recordset last name ascending
    rstAuthors.Sort = "au_lname ASC, au_fname ASC"
     ' show output
    Debug.Print "Last Name Ascending:"
    Debug.Print "First Name  Last Name" & vbCr

    rstAuthors.MoveFirst
    Do Until rstAuthors.EOF
        Debug.Print rstAuthors!au_fname & " " & rstAuthors!au_lname
        rstAuthors.MoveNext
    Loop

     ' sort the recordset last name descending
    rstAuthors.Sort = "au_lname DESC, au_fname ASC"
     ' show output
    Debug.Print "Last Name Descending"
    Debug.Print "First Name  Last Name" & vbCr

    Do Until rstAuthors.EOF
        Debug.Print rstAuthors!au_fname & " " & rstAuthors!au_lname
        rstAuthors.MoveNext
    Loop

    ' clean up
    rstAuthors.Close
    Cnxn.Close
    Set rstAuthors = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstAuthors Is Nothing Then
        If rstAuthors.State = adStateOpen Then rstAuthors.Close
    End If
    Set rstAuthors = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndSortVB

下面是打印指定 Recordset 中给定标题和内容的辅助实用程序例程。

Attribute VB_Name = "Sort"

请参阅

Recordset 对象 | Sort 属性


Source 属性范例 (VB)

本范例通过打开三个基于不同数据源的 Recordset 对象来演示 Source 属性。

'BeginSourceVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    Dim Cnxn As ADODB.Connection
    Dim rstTitles As ADODB.Recordset
    Dim rstPublishers As ADODB.Recordset
    Dim rstPublishersDirect As ADODB.Recordset
    Dim rstTitlesPublishers As ADODB.Recordset
    Dim cmdSQL As ADODB.Command
    Dim strCnxn As String
    Dim strSQL As String

    ' Open a connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open a recordset based on a command object
    Set cmdSQL = New ADODB.Command
    Set cmdSQL.ActiveConnection = Cnxn
    strSQL = "Select title, type, pubdate FROM Titles ORDER BY title"
    cmdSQL.CommandText = strSQL
    Set rstTitles = cmdSQL.Execute()

    ' Open a recordset based on a table
    Set rstPublishers = New ADODB.Recordset
    strSQL = "Publishers"
    rstPublishers.Open strSQL, Cnxn, adOpenStatic, adLockReadOnly, adCmdTable
    'rstPublishers.Open strSQL, Cnxn, , , adCmdTable
     ' the above two lines of code are identical

    ' Open a recordset based on a table
    Set rstPublishersDirect = New ADODB.Recordset
    rstPublishersDirect.Open strSQL, strCnxn, , , adCmdTableDirect

    ' Open a recordset based on an SQL string.
    Set rstTitlesPublishers = New ADODB.Recordset
    strSQL = "SELECT title_ID AS TitleID, title AS Title, " & _
        "publishers.pub_id AS PubID, pub_name AS PubName " & _
        "FROM publishers INNER JOIN Titles " & _
        "ON publishers.pub_id = Titles.pub_id " & _
        "ORDER BY Title"
    rstTitlesPublishers.Open strSQL, strCnxn, , , adCmdText

    ' Use the Source property to display the source of each recordset.
    MsgBox "rstTitles source: " & vbCr & _
        rstTitles.Source & vbCr & vbCr & _
        "rstPublishers source: " & vbCr & _
        rstPublishers.Source & vbCr & vbCr & _
        "rstPublishersDirect source: " & vbCr & _
        rstPublishersDirect.Source & vbCr & vbCr & _
        "rstTitlesPublishers source: " & vbCr & _
        rstTitlesPublishers.Source

    ' clean up
    rstTitles.Close
    rstPublishers.Close
    rstTitlesPublishers.Close
    Cnxn.Close
    Set rstTitles = Nothing
    Set rstPublishers = Nothing
    Set rstTitlesPublishers = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstTitles Is Nothing Then
        If rstTitles.State = adStateOpen Then rstTitles.Close
    End If
    Set rstTitles = Nothing

    If Not rstPublishers Is Nothing Then
        If rstPublishers.State = adStateOpen Then rstPublishers.Close
    End If
    Set rstPublishers = Nothing

    If Not rstTitlesPublishers Is Nothing Then
        If rstTitlesPublishers.State = adStateOpen Then rstTitlesPublishers.Close
    End If
    Set rstTitlesPublishers = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndSourceVB

请参阅

Recordset 对象 | Source 属性 (ADO Recordset)


State 属性范例 (VB)

本范例使用 State 属性，在异步连接为开且异步命令正在执行时显示消息。

'BeginStateVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    Dim Cnxn1 As ADODB.Connection
    Dim Cnxn2 As ADODB.Connection
    Dim cmdChange As ADODB.Command
    Dim cmdRestore As ADODB.Command
    Dim strCnxn As String
    Dim strSQL As String

    ' Open two asynchronous connections, displaying
    ' a message while connecting
    Set Cnxn1 = New ADODB.Connection
    Set Cnxn2 = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"

    Cnxn1.Open strCnxn, , , adAsyncConnect
    Do Until Cnxn1.State <> adStateConnecting
       Debug.Print "Opening first connection...."
    Loop

    Cnxn2.Open strCnxn, , , adAsyncConnect
    Do Until Cnxn2.State <> adStateConnecting
       Debug.Print "Opening second connection...."
    Loop

    ' Create two command objects
    Set cmdChange = New ADODB.Command
    cmdChange.ActiveConnection = Cnxn1
    strSQL = "UPDATE Titles SET type = 'self_help' WHERE type = 'psychology'"
    cmdChange.CommandText = strSQL

    Set cmdRestore = New ADODB.Command
    cmdRestore.ActiveConnection = Cnxn2
    strSQL = "UPDATE Titles SET type = 'psychology' WHERE type = 'self_help'"
    cmdRestore.CommandText = strSQL

    ' Executing the commands, displaying a message
    ' while they are executing
    cmdChange.Execute , , adAsyncExecute
    Do Until cmdChange.State <> adStateExecuting
       Debug.Print "Change command executing...."
    Loop

    cmdRestore.Execute , , adAsyncExecute
    Do Until cmdRestore.State <> adStateExecuting
       Debug.Print "Restore command executing...."
    Loop

    ' clean up
    Cnxn1.Close
    Cnxn2.Close
    Set Cnxn1 = Nothing
    Set Cnxn2 = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not Cnxn1 Is Nothing Then
        If Cnxn1.State = adStateOpen Then Cnxn1.Close
    End If
    Set Cnxn1 = Nothing

    If Not Cnxn2 Is Nothing Then
        If Cnxn2.State = adStateOpen Then Cnxn2.Close
    End If
    Set Cnxn2 = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndStateVB

请参阅

Recordset 对象 | State 属性


Status 属性范例 (Field) (VB)

下列范例用 Internet Publishing Provider 从读/写文件夹中打开文档。Record 的 Field 对象的 Status 属性将先设置为 adFieldPendingInsert，然后更新为 adFieldOk。

'BeginStatusFieldVB

 ' to integrate this code replace the values in the source string

Sub Main()

   Dim File As ADODB.Record
   Dim strFile As String
   Dim Cnxn As ADODB.Connection
   Dim strCnxn As String

   Set Cnxn = New ADODB.Connection
   strCnxn = "url=http://MyServer/"
   Cnxn.Open strCnxn

   Set File = New ADODB.Record
   strFile = "Folder/FileName"
   ' Open a read/write document
   File.Source = strFile
   File.ActiveConnection = Cnxn
   File.Mode = adModeReadWrite
   File.Open

   Debug.Print "Append a couple of fields"

   File.Fields.Append "chektest:fld1", adWChar, 42, adFldUpdatable, "fld1"
   File.Fields.Append "chektest:fld2", adWChar, 42, adFldUpdatable, "fld2"

   Debug.Print "status for the fields"
   Debug.Print File.Fields("chektest:fld1").Status 'adfldpendinginsert
   Debug.Print File.Fields("chektest:fld2").Status 'adfldpendinginsert

    'turn off error-handling to verify field status
   On Error Resume Next

   File.Fields.Update

   Debug.Print "Update succeeds"
   Debug.Print File.Fields("chektest:fld1").Status 'adfldpendinginsert + adFieldUnavailable
   Debug.Print File.Fields("chektest:fld2").Status 'adfldpendinginsert + adFieldUnavailable

    ' resume default error-handling
   On Error GoTo 0

     ' clean up
    File.Close
    Cnxn.Close
    Set File = Nothing
    Set Cnxn = Nothing

End Sub
'EndStatusFieldVB

以下范例将从文档打开的 Record 中删除已知 Field。Status 属性将先设置为 adFieldOK，然后设置为 adFieldPendingUnknown。

'BeginStatusField2VB

' to integrate this code replace the values in the source string

Sub Main()

   Dim File As ADODB.Record
   Dim fld As ADODB.Field
   Dim strFile As String

   Dim Cnxn As ADODB.Connection
   Dim strCnxn As String

    ' create connection as a URL
   Set Cnxn = New ADODB.Connection
   strCnxn = "url=http://MyServer/"
   Cnxn.Open strCnxn
   Set File = New ADODB.Record
   strFile = "Folder/FileName"
   ' Open a read/write document
   File.Open strFile, Cnxn, adModeReadWrite
   Debug.Print File.Fields("chektest:fld1").Status ' should be adFldOK

   ' Delete a field which already exists in the collection
   File.Fields.Delete "chektest:fld1"
   Set fld = File.Fields("chektest:fld1")
   Debug.Print File.Fields("chektest:fld1").Status   ' Pending delete

    'turn off error-handling to verify field status
   On Error Resume Next

   File.Fields.Update

   Debug.Print "Deleted"
   Debug.Print fld.Status   ' Pending unknown

    ' resume default error-handling
   On Error GoTo 0

     ' clean up
    File.Close
    Cnxn.Close
    Set File = Nothing
    Set Cnxn = Nothing

End Sub
'EndStatusField2VB

下列代码将从只读文档上打开的 Record 中删除 Field。Status 将设置为 adFieldPendingDelete。在 Update 时，删除失败并且 Status 为 adFieldPendingDelete 和 adFieldPermissionDenied 之和。CancelUpdate 清除挂起的 Status 设置。

Sub Main()
   Dim File As ADODB.Record
   Dim fld As ADODB.Field
   Dim Cnxn As ADODB.Connection
   Dim strCnxn As String
   Dim strFile As String

    ' create connection as a URL
   Set Cnxn = New ADODB.Connection
   strCnxn = "url=http://MyServer/"
   Cnxn.Open strCnxn

   ' Open a read/write document
   Set File = New ADODB.Record
   strFile = "Folder/FileName"
   File.Open strFile, Cnxn, adModeReadWrite, adCreateCollection Or adOpenIfExists

   Debug.Print "Try to delete something without permission"
   File.Fields.Delete ("RESOURCE_PARSENAME")
   Set fld = File.Fields("RESOURCE_PARSENAME")

   Debug.Print "Pending delete"
   Debug.Print fld.Status   ' Pending delete
   Debug.Print "Delete should fail on Update"

    'turn off error-handling to verify field status
   On Error Resume Next

   File.Fields.Update   ' Should fail

   Debug.Print fld.Status   ' Pending delete plus error
   File.Fields.CancelUpdate
   Debug.Print fld.Status   ' Okay

    ' resume default error-handling
   On Error GoTo 0

     ' clean up
    File.Close
    Cnxn.Close
    Set File = Nothing
    Set Cnxn = Nothing

End Sub
'EndStatusField3VB

请参阅

Field 对象 | Record 对象 | Status 属性 (ADO Field)


Status 属性范例（记录集）(VB)

ADO 2.5 范例

Status 属性范例 (Recordset) (VB)

本范例使用 Status 属性来显示在批更新发生前被批操作修改的记录。

'BeginStatusRecordsetVB
Public Sub Main()
    On Error GoTo ErrorHandler

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

    ' connection and recordset variables
    Dim rstTitles As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim strSQLTitles As String

     ' open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

     ' open recordset for batch update
    Set rstTitles = New ADODB.Recordset
    strSQLTitles = "Titles"
    rstTitles.Open strSQLTitles, Cnxn, adOpenKeyset, adLockBatchOptimistic, adCmdTable

    ' change the type of psychology titles
    Do Until rstTitles.EOF
        If Trim(rstTitles!Type) = "psychology" Then rstTitles!Type = "self_help"
        rstTitles.MoveNext
    Loop

    ' display Title ID and status
    rstTitles.MoveFirst
    Do Until rstTitles.EOF
        If rstTitles.Status = adRecModified Then
            Debug.Print rstTitles!title_id & " - Modified"
        Else
            Debug.Print rstTitles!title_id
        End If
    rstTitles.MoveNext
    Loop

    ' clean up
    rstTitles.Close
    Cnxn.Close
    Set rstTitles = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstTitles Is Nothing Then
        If rstTitles.State = adStateOpen Then
            ' Cancel the update because this is a demonstration
            rstTitles.CancelBatch
            rstTitles.Close
        End If
    End If
    Set rstTitles = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndStatusRecordsetVB

请参阅

Status 属性 (ADO Recordset)


StayInSync 属性范例 (VB)

本范例演示 StayInSync 属性如何方便地访问分级 Recordset 的行。

外循环显示每个作者的姓名、州/省别和标识。每行追加的 Recordset 都从 Fields 集合进行检索，一旦父 Recordset 移至新行，StayInSync 属性即自动将其分配给 rstTitleAuthor。内循环显示追加的记录集中每行的四个字段。

'BeginStayInSyncVB
Public Sub Main()
    On Error GoTo ErrorHandler

    'To integrate this code create a DSN called Pubs
    'with a user_id = sa and no password

    Dim Cnxn As ADODB.Connection
    Dim rst As ADODB.Recordset
    Dim rstTitleAuthor As New ADODB.Recordset
    Dim strCnxn As String

        ' open connection with Data Shape attributes
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider=MSDataShape;Data Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

        ' create recordset
    Set rst = New ADODB.Recordset
    rst.StayInSync = True
    rst.Open "SHAPE {select * from Authors} " & _
                   "APPEND ( { select * from titleauthor} AS chapTitleAuthor " & _
                   "RELATE au_id TO au_id) ", Cnxn, , , adCmdText

    Set rstTitleAuthor = rst("chapTitleAuthor").Value
    Do Until rst.EOF
        Debug.Print rst!au_fname & " " & rst!au_lname & " " & _
                   rst!State & " " & rst!au_id

        Do Until rstTitleAuthor.EOF
            Debug.Print rstTitleAuthor(0) & " " & rstTitleAuthor(1) & " " & _
                   rstTitleAuthor(2) & " " & rstTitleAuthor(3)
            rstTitleAuthor.MoveNext
        Loop

        rst.MoveNext
    Loop

    ' clean up
    rst.Close
    Cnxn.Close
    Set rst = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rst Is Nothing Then
        If rst.State = adStateOpen Then rst.Close
    End If
    Set rst = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndStayInSyncVB

请参阅

Fields 集合 | Recordset 对象 | StayInSync 属性


Supports 方法范例 (VB)

本范例使用 Supports 方法来显示用不同游标类型打开的记录集所支持的选项。运行此过程需要 DisplaySupport 过程。

'BeginSupportsVB

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

Public Sub Main()
    On Error GoTo ErrorHandler

    ' recordset and connection variables
    Dim rstTitles As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim strSQLTitles As String
     ' array variables
    Dim arrCursorType(4) As Integer
    Dim intIndex As Integer

    ' open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Fill array with CursorType constants
    arrCursorType(0) = adOpenForwardOnly
    arrCursorType(1) = adOpenKeyset
    arrCursorType(2) = adOpenDynamic
    arrCursorType(3) = adOpenStatic

    ' open recordset using each CursorType and optimistic locking
    For intIndex = 0 To 3
        Set rstTitles = New ADODB.Recordset
        rstTitles.CursorType = arrCursorType(intIndex)
        rstTitles.LockType = adLockOptimistic

        strSQLTitles = "Titles"
        rstTitles.Open strSQLTitles, Cnxn, , , adCmdTable

        Select Case arrCursorType(intIndex)
           Case adOpenForwardOnly
              Debug.Print "ForwardOnly cursor supports:"
           Case adOpenKeyset
              Debug.Print "Keyset cursor supports:"
           Case adOpenDynamic
              Debug.Print "Dynamic cursor supports:"
           Case adOpenStatic
              Debug.Print "Static cursor supports:"
        End Select

        ' call the DisplaySupport procedure from below
        ' to display the supported options
        DisplaySupport rstTitles

    Next intIndex

    ' clean up
    rstTitles.Close
    Cnxn.Close
    Set rstTitles = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstTitles Is Nothing Then
        If rstTitles.State = adStateOpen Then rstTitles.Close
    End If
    Set rstTitles = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndSupportsVB

'BeginSupports2VB
Public Sub DisplaySupport(rstTemp As ADODB.Recordset)

   Dim arrConstants(11) As Long
   Dim blnSupports As Boolean
   Dim intIndex As Integer

   ' Fill array with cursor option constants
   arrConstants(0) = adAddNew
   arrConstants(1) = adApproxPosition
   arrConstants(2) = adBookmark
   arrConstants(3) = adDelete
   arrConstants(4) = adFind
   arrConstants(5) = adHoldRecords
   arrConstants(6) = adMovePrevious
   arrConstants(7) = adNotify
   arrConstants(8) = adResync
   arrConstants(9) = adUpdate
   arrConstants(10) = adUpdateBatch

   For intIndex = 0 To 10
      blnSupports = _
         rstTemp.Supports(arrConstants(intIndex))
      If blnSupports Then
         Select Case arrConstants(intIndex)
            Case adAddNew
               Debug.Print "   AddNew"
            Case adApproxPosition
               Debug.Print "   AbsolutePosition and AbsolutePage"
            Case adBookmark
               Debug.Print "   blnkmark"
            Case adDelete
               Debug.Print "   Delete"
            Case adFind
               Debug.Print "   Find"
            Case adHoldRecords
               Debug.Print "   Holding Records"
            Case adMovePrevious
               Debug.Print "   MovePrevious and Move"
            Case adNotify
               Debug.Print "   Notifications"
            Case adResync
               Debug.Print "   Resyncing data"
            Case adUpdate
               Debug.Print "   Update"
            Case adUpdateBatch
               Debug.Print "   batch updating"
         End Select
      End If
   Next intIndex

End Sub
'EndSupports2VB

请参阅

Recordset 对象 | Supports 方法


Type 属性范例 (Field) (VB)

本范例通过显示与 Employees 表中所有 Field 对象的 Type 属性值对应的常量名，来演示 Type 属性。运行此过程需要 FieldType 函数。

'BeginTypeFieldVB
Public Sub Main()
    On Error GoTo ErrorHandler

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

    Dim Cnxn As ADODB.Connection
    Dim rstEmployees As ADODB.Recordset
    Dim fld As ADODB.Field
    Dim strCnxn As String
    Dim strSQLEmployee As String
    Dim FieldType As String

    ' Open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open recordset with data from Employees table
    Set rstEmployees = New ADODB.Recordset
    strSQLEmployee = "employee"
    rstEmployees.Open strSQLEmployee, Cnxn, , , adCmdTable
    'rstEmployees.Open strSQLEmployee, Cnxn, adOpenStatic, adLockReadOnly, adCmdTable
     ' the above two lines of code are identical

    Debug.Print "Fields in Employees Table:" & vbCr

    ' Enumerate Fields collection of Employees table
    For Each fld In rstEmployees.Fields
        ' translate field-type code to text
        Select Case fld.Type
            Case adChar
               FieldType = "adChar"
            Case adVarChar
               FieldType = "adVarChar"
            Case adSmallInt
               FieldType = "adSmallInt"
            Case adUnsignedTinyInt
               FieldType = "adUnsignedTinyInt"
            Case adDBTimeStamp
               FieldType = "adDBTimeStamp"
        End Select
        ' show results
        Debug.Print "  Name: " & fld.Name & vbCr & _
          "  Type: " & FieldType & vbCr
    Next fld

    ' clean up
    rstEmployees.Close
    Cnxn.Close
    Set rstEmployees = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstEmployees Is Nothing Then
        If rstEmployees.State = adStateOpen Then rstEmployees.Close
    End If
    Set rstEmployees = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    Set fld = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndTypeFieldVB

请参阅

Field 对象 | Type 属性


Type 属性范例 (Property) (VB)

本范例演示 Type 属性。这是列出集合（如 Properties、Fields 等等）的名称和类型的实用程序模型。

不需要打开 Recordset 即可访问其 Properties 集合；在 Recordset 对象实例化时它们即已存在。但是，将 CursorLocation 属性设置为 adUseClient 会向 Recordset 对象的 Properties 集合添加若干个动态属性，这将给范例增添一些趣味。为了达到说明的效果，在此使用 Item 属性来访问每个 Property 对象。

'BeginTypePropertyVB
Public Sub Main()
    On Error GoTo ErrorHandler

     ' recordset variables
    Dim rst As ADODB.Recordset
    Dim prop As ADODB.Property
     ' property variables
    Dim ix As Integer
    Dim strMsg As String

     ' create client-side recordset
    Set rst = New ADODB.Recordset
    rst.CursorLocation = adUseClient
     ' enumerate property types
    For ix = 0 To rst.Properties.Count - 1
        Set prop = rst.Properties.Item(ix)
        Select Case prop.Type
           Case adBigInt
              strMsg = "adBigInt"
           Case adBinary
              strMsg = "adBinary"
           Case adBoolean
              strMsg = "adBoolean"
           Case adBSTR
              strMsg = "adBSTR"
           Case adChapter
              strMsg = "adChapter"
           Case adChar
              strMsg = "adChar"
           Case adCurrency
              strMsg = "adCurrency"
           Case adDate
              strMsg = "adDate"
           Case adDBDate
              strMsg = "adDBDate"
           Case adDBTime
              strMsg = "adDBTime"
           Case adDBTimeStamp
              strMsg = "adDBTimeStamp"
           Case adDecimal
              strMsg = "adDecimal"
           Case adDouble
              strMsg = "adDouble"
           Case adEmpty
              strMsg = "adEmpty"
           Case adError
              strMsg = "adError"
           Case adFileTime
              strMsg = "adFileTime"
           Case adGUID
              strMsg = "adGUID"
           Case adIDispatch
              strMsg = "adIDispatch"
           Case adInteger
              strMsg = "adInteger"
           Case adIUnknown
              strMsg = "adIUnknown"
           Case adLongVarBinary
              strMsg = "adLongVarBinary"
           Case adLongVarChar
              strMsg = "adLongVarChar"
           Case adLongVarWChar
              strMsg = "adLongVarWChar"
           Case adNumeric
              strMsg = "adNumeric"
           Case adPropVariant
              strMsg = "adPropVariant"
           Case adSingle
              strMsg = "adSingle"
           Case adSmallInt
              strMsg = "adSmallInt"
           Case adTinyInt
              strMsg = "adTinyInt"
           Case adUnsignedBigInt
              strMsg = "adUnsignedBigInt"
           Case adUnsignedInt
              strMsg = "adUnsignedInt"
           Case adUnsignedSmallInt
              strMsg = "adUnsignedSmallInt"
           Case adUnsignedTinyInt
              strMsg = "adUnsignedTinyInt"
           Case adUserDefined
              strMsg = "adUserDefined"
           Case adVarBinary
              strMsg = "adVarBinary"
           Case adVarChar
              strMsg = "adVarChar"
           Case adVariant
              strMsg = "adVariant"
           Case adVarNumeric
              strMsg = "adVarNumeric"
           Case adVarWChar
              strMsg = "adVarWChar"
           Case adWChar
              strMsg = "adWChar"
           Case Else
              strMsg = "*UNKNOWN*"
        End Select
            'show results
        Debug.Print "Property " & ix & ": " & prop.Name & _
                    ", Type = " & strMsg
    Next ix

    ' clean up
    Set rst = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    Set rst = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

End Sub
'EndTypePropertyVB

请参阅

Property 对象 | Type 属性


Update 和 CancelUpdate 方法范例 (VB)

本范例演示 Update 和 CancelUpdate 方法。

'BeginUpdateVB
Public Sub Main()
    On Error GoTo ErrorHandler

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

    ' recordset and connection variables
    Dim rstEmployees As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim strSQLEmployees As String
     ' buffer variables
    Dim strOldFirst As String
    Dim strOldLast As String
    Dim strMessage As String

    ' Open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open recordset to enable changes
    Set rstEmployees = New ADODB.Recordset
    strSQLEmployees = "SELECT fname, lname FROM Employee ORDER BY lname"
    rstEmployees.Open strSQLEmployees, Cnxn, adOpenKeyset, adLockOptimistic, adCmdText

    ' Store original data
    strOldFirst = rstEmployees!fname
    strOldLast = rstEmployees!lname
    ' Change data in edit buffer
    rstEmployees!fname = "Linda"
    rstEmployees!lname = "Kobara"

    ' Show contents of buffer and get user input
    strMessage = "Edit in progress:" & vbCr & _
        "  Original data = " & strOldFirst & " " & _
        strOldLast & vbCr & "  Data in buffer = " & _
        rstEmployees!fname & " " & rstEmployees!lname & vbCr & vbCr & _
        "Use Update to replace the original data with " & _
        "the buffered data in the Recordset?"

    If MsgBox(strMessage, vbYesNo) = vbYes Then
        rstEmployees.Update
    Else
        rstEmployees.CancelUpdate
    End If

    ' show the resulting data
    MsgBox "Data in recordset = " & rstEmployees!fname & " " & _
       rstEmployees!lname

    ' restore original data because this is a demonstration
    If Not (strOldFirst = rstEmployees!fname And _
           strOldLast = rstEmployees!lname) Then
        rstEmployees!fname = strOldFirst
        rstEmployees!lname = strOldLast
        rstEmployees.Update
    End If

    ' clean up
    rstEmployees.Close
    Cnxn.Close
    Set rstEmployees = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstEmployees Is Nothing Then
        If rstEmployees.State = adStateOpen Then rstEmployees.Close
    End If
    Set rstEmployees = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndUpdateVB

本范例演示 Update 和 AddNew 方法。

' BeginUpdate2VB
Public Sub Main()
    On Error GoTo ErrorHandler

    Dim cnn1 As ADODB.Connection
    Dim rstEmployees As ADODB.Recordset
    Dim strEmpID As String
    Dim strOldFirst As String
    Dim strOldLast As String
    Dim strMessage As String
    Dim strCnn As String

    ' Open a connection.
    Set cnn1 = New ADODB.Connection
       strCnn = "Provider=sqloledb;" & _
       "Data Source=MySqlServer;Initial Catalog=Pubs;Integrated Security=SSPI; "
    cnn1.Open strCnn

    ' Open recordset with data from Employees table.
    Set rstEmployees = New ADODB.Recordset
    rstEmployees.CursorType = adOpenKeyset
    rstEmployees.LockType = adLockOptimistic
    rstEmployees.Open "employee", cnn1, , , adCmdTable

    rstEmployees.AddNew
    strEmpID = "B-S55555M"
    rstEmployees!emp_id = strEmpID
    rstEmployees!fname = "Bill"
    rstEmployees!lname = "Sornsin"

    ' Show contents of buffer and get user input.
    strMessage = "AddNew in progress:" & vbCr & _
        "Data in buffer = " & rstEmployees!emp_id & ", " & _
        rstEmployees!fname & " " & rstEmployees!lname & vbCr & vbCr & _
        "Use Update to save buffer to recordset?"

    If MsgBox(strMessage, vbYesNoCancel) = vbYes Then
        rstEmployees.Update
        ' Go to the new record and show the resulting data.
        MsgBox "Data in recordset = " & rstEmployees!emp_id & ", " & _
            rstEmployees!fname & " " & rstEmployees!lname
    Else
        rstEmployees.CancelUpdate
        MsgBox "No new record added."
    End If

    ' Delete new data because this is a demonstration.
    cnn1.Execute "DELETE FROM employee WHERE emp_id = '" & strEmpID & "'"

    ' clean up
    rstEmployees.Close
    cnn1.Close
    Set rstEmployees = Nothing
    Set cnn1 = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstEmployees Is Nothing Then
        If rstEmployees.State = adStateOpen Then rstEmployees.Close
    End If
    Set rstEmployees = Nothing

    If Not cnn1 Is Nothing Then
        If cnn1.State = adStateOpen Then cnn1.Close
    End If
    Set cnn1 = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndUpdate2VB

请参阅

CancelUpdate 方法 | Recordset 对象 | Update 方法


UpdateBatch 和 CancelBatch 方法范例 (VB)

本范例演示 UpdateBatch 和 CancelBatch 方法。

'BeginUpdateBatchVB
Public Sub Main()
    On Error GoTo ErrorHandler

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

    'connection and recordset variables
    Dim rstTitles As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim strSQLTitles As String
     'record variables
    Dim strTitle As String
    Dim strMessage As String

    ' Open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

     ' open recordset for batch uodate
    Set rstTitles = New ADODB.Recordset
    strSQLTitles = "titles"
    rstTitles.Open strSQLTitles, Cnxn, adOpenKeyset, adLockBatchOptimistic, adCmdTable

    rstTitles.MoveFirst
    ' Loop through recordset and ask user if she wants
    ' to change the type for a specified title.
    Do Until rstTitles.EOF
        If Trim(rstTitles!Type) = "psychology" Then
            strTitle = rstTitles!Title
            strMessage = "Title: " & strTitle & vbCr & _
               "Change type to self help?"

            If MsgBox(strMessage, vbYesNo) = vbYes Then
                rstTitles!Type = "self_help"
            End If
        End If

        rstTitles.MoveNext
    Loop

    ' Ask the user if she wants to commit to all the
    ' changes made above.
    If MsgBox("Save all changes?", vbYesNo) = vbYes Then
        rstTitles.UpdateBatch
    Else
        rstTitles.CancelBatch
    End If

    ' Print current data in recordset.
    rstTitles.Requery
    rstTitles.MoveFirst
    Do While Not rstTitles.EOF
        Debug.Print rstTitles!Title & " - " & rstTitles!Type
        rstTitles.MoveNext
    Loop

    ' Restore original values because this is a demonstration.
    rstTitles.MoveFirst
    Do Until rstTitles.EOF
        If Trim(rstTitles!Type) = "self_help" Then
            rstTitles!Type = "psychology"
        End If
        rstTitles.MoveNext
    Loop
    rstTitles.UpdateBatch

    ' clean up
    rstTitles.Close
    Cnxn.Close
    Set rstTitles = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstTitles Is Nothing Then
        If rstTitles.State = adStateOpen Then rstTitles.Close
    End If
    Set rstTitles = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndUpdateBatchVB

请参阅

CancelBatch 方法 | UpdateBatch 方法


Value 属性范例 (VB)

本范例通过显示 Employees 表的字段和属性值来演示 Field 和 Property 对象的 Value 属性。

'BeginValueVB
Public Sub Main()
    On Error GoTo ErrorHandler

    'To integrate this code
    'replace the data source and initial catalog values
    'in the connection string

    ' connection and recordset variables
    Dim rstEmployees As ADODB.Recordset
    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim strSQLEmployees As String
     ' field property variables
    Dim fld As ADODB.Field
    Dim prp As ADODB.Property

     ' Open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    ' Open recordset with data from Employees table
    Set rstEmployees = New ADODB.Recordset
    strSQLEmployees = "employee"
    rstEmployees.Open strSQLEmployees, Cnxn, , , adCmdTable
    'rstEmployees.Open strSQLEmployees, Cnxn, adOpenStatic, adLockReadOnly, adCmdTable
    ' the above two lines of code are identical

    Debug.Print "Field values in rstEmployees"

    ' Enumerate the Fields collection of the Employees table
    For Each fld In rstEmployees.Fields
        ' Because Value is the default property of a
        ' Field object, the use of the actual keyword
        ' here is optional.
        Debug.Print "   " & fld.Name & " = " & fld.Value
    Next fld

    Debug.Print "Property values in rstEmployees"

    ' Enumerate the Properties collection of the Recordset object
    For Each prp In rstEmployees.Properties
        Debug.Print "   " & prp.Name & " = " & prp.Value
        ' because Value is the default property of a Property object
        ' use of the actual Value keyword is optional
    Next prp

    ' clean up
    rstEmployees.Close
    Cnxn.Close
    Set rstEmployees = Nothing
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not rstEmployees Is Nothing Then
        If rstEmployees.State = adStateOpen Then rstEmployees.Close
    End If
    Set rstEmployees = Nothing

    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndValueVB

请参阅

Field 对象 | Property 对象 | Value 属性


Version 属性范例 (VB)

本范例使用 Connection 对象的 Version 属性来显示当前 ADO 版本。范例中还使用若干动态属性来显示：

  • 当前 DBMS 名称和版本。
  • OLE DB 版本。
  • 提供者名称和版本。
  • ODBC 版本。
  • ODBC 驱动程序名称和版本。
'BeginVersionVB
Public Sub Main()
    On Error GoTo ErrorHandler

    Dim Cnxn As ADODB.Connection
    Dim strCnxn As String
    Dim strVersionInfo As String

    ' Open connection
    Set Cnxn = New ADODB.Connection
    strCnxn = "Provider='sqloledb';Data Source='MySqlServer';" & _
        "Initial Catalog='Pubs';Integrated Security='SSPI';"
    Cnxn.Open strCnxn

    strVersionInfo = "ADO Version: " & Cnxn.Version & vbCr
    strVersionInfo = strVersionInfo & "DBMS Name: " & Cnxn.Properties("DBMS Name") & vbCr
    strVersionInfo = strVersionInfo & "DBMS Version: " & Cnxn.Properties("DBMS Version") & vbCr
    strVersionInfo = strVersionInfo & "OLE DB Version: " & Cnxn.Properties("OLE DB Version") & vbCr
    strVersionInfo = strVersionInfo & "Provider Name: " & Cnxn.Properties("Provider Name") & vbCr
    strVersionInfo = strVersionInfo & "Provider Version: " & Cnxn.Properties("Provider Version") & vbCr

    MsgBox strVersionInfo

    ' clean up
    Cnxn.Close
    Set Cnxn = Nothing
    Exit Sub

ErrorHandler:
    ' clean up
    If Not Cnxn Is Nothing Then
        If Cnxn.State = adStateOpen Then Cnxn.Close
    End If
    Set Cnxn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
'EndVersionVB

请参阅

Connection 对象 | Version 属性


Microsoft Visual Basic Scripting Edition 中的 ADO 代码范例

通过下列代码范例来学习用 Visual Basic Scripting Edition (VBScript) 编程时如何使用 ADO 方法。

注意 请将整个代码范例（从开始到结束）粘贴到代码编辑器中。如果只使用部分范例或者丢失了段落格式，范例可能无法正确运行。

方法

  • AddNew 方法范例
  • Clone 方法范例
  • Delete 方法范例
  • Execute、Requery 和 Clear 方法范例
  • Move 方法范例
  • MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法范例
  • Open 和 Close 方法范例

请参阅

Microsoft Visual Basic 中的 ADO 代码范例 | Microsoft Visual C++ 中的 ADO 代码范例 | Microsoft Visual J++ 中的 ADO 代码范例


AddNew 方法范例 (VBScript)

本范例使用 AddNew 方法来创建具有指定名称的新记录。

在 Active Server Page (ASP) 中使用下列范例。使用 Find 定位文件 Adovbs.inc，并将其放到计划使用的目录中。请将以下代码剪切并粘贴到记事本或其他文本编辑器中，并将其另存为 AddNewVBS.asp。您可以在任何客户端浏览器中查看结果。

要执行本范例，请在 HTML 表中添加新记录。单击“Add New”。要删除不需要的记录，请参阅 Delete 方法范例。

<!-- BeginAddNewVBS -->
<%@Language = VBScript %>
<%' use this meta tag instead of adovbs.inc%>
<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->
<HTML>
<HEAD>
    <TITLE>ADO AddNew Method (VBScript)</TITLE>
    <STYLE>
    <!--
    body {
       font-family: 'Verdana','Arial','Helvetica',sans-serif;
       BACKGROUND-COLOR:white;
       COLOR:black;
        }
    TH {
       background-color: #008080;
       font-family: 'Arial Narrow','Arial',sans-serif;
       font-size: xx-small;
       color: white;
       }
    TD {
       text-align: center;
       background-color: #f7efde;
       font-family: 'Arial Narrow','Arial',sans-serif;
       font-size: xx-small;
        }
    -->
    </STYLE>
</HEAD>
<BODY>

<H1>ADO AddNew Method (VBScript)</H1>

<% ' to integrate/test this code replace the
   ' Data Source value in the Connection string%>
<%
    ' connection and recordset variables
    Dim Cnxn, strCnxn
    Dim rsCustomers, strSQLCustomers
    Dim fld, Err

    ' open connection
    Set Cnxn = Server.CreateObject("ADODB.Connection")
    strCnxn = "Provider='sqloledb';Data Source=" & _
            Request.ServerVariables("SERVER_NAME") & ";" & _
            "Integrated Security='SSPI';Initial Catalog='Northwind';"
    Cnxn.Open strCnxn

     ' create and open Recordset using object refs
    Set rsCustomers = Server.CreateObject("ADODB.Recordset")
    strSQLCustomers = "Customers"

    rsCustomers.ActiveConnection = Cnxn
    rsCustomers.CursorLocation = adUseClient
    rsCustomers.CursorType = adOpenKeyset
    rsCustomers.LockType = adLockOptimistic
    rsCustomers.Source = strSQLCustomers
    rsCustomers.Open

    'If this is first time page is open, Form collection
    'will be empty when data is entered. run AddNew method
    If Not IsEmpty(Request.Form) Then
        If Not Request.Form("CompanyName") = "" Then
            rsCustomers.AddNew
                rsCustomers("CustomerID") = Request.Form("CompanyID")
                rsCustomers("CompanyName") = Request.Form("CompanyName")
                rsCustomers("ContactName") = Request.Form("FirstName") & _
                    " " & Request.Form("LastName")
                rsCustomers("Phone") = Request.Form("PhoneNumber")
                rsCustomers("City") = Request.Form("City")
                rsCustomers("Region") = Request.Form("State")
            rsCustomers.Update
             ' check for errors
            If Cnxn.Errors.Count > 0 Then
                For Each Err In Cnxn.Errors
                    Response.Write("Error " & Err.SQLState & ": " & _
                        Err.Description & " | " & Err.NativeError)
                Next
            Cnxn.Errors.Clear
            rsCustomers.CancelUpdate
            End If
            'On Error GoTo 0
        rsCustomers.MoveFirst
        End If
    End If
%>

<TABLE COLSPAN="8" CELLPADDING=5 BORDER=1 ALIGN="center">
<!-- BEGIN column header row for Customer Table-->
    <TR>
        <TH>Customer ID</TH>
        <TH>Company Name</TH>
        <TH>Contact Name</TH>
        <TH>Phone Number</TH>
        <TH>City</TH>
        <TH>State/Province</TH>
        </TR>

    <% ' show the data
        Do Until rsCustomers.EOF
            Response.Write("<TR>")
            Response.Write("<TD>" & rsCustomers("CustomerID") & "</TD>")
            Response.Write("<TD>" & rsCustomers("CompanyName")& "</TD>")
            Response.Write("<TD>" & rsCustomers("ContactName") & "</TD>")
            Response.Write("<TD>" & rsCustomers("Phone") & "</TD>")
            Response.Write("<TD>" & rsCustomers("City") & "</TD>")
            Response.Write("<TD>" & rsCustomers("Region") & "</TD>")
            Response.Write("</TR>")
        rsCustomers.MoveNext
        Loop
    %>
</TABLE>

<HR>

<!--
    Form to enter new record posts variables
    back to this page
-->
<FORM Method=post Action="AddNewVbs.asp" Name=Form>
    <TABLE>
        <TR>
            <TD>Company ID:</TD>
            <TD><INPUT Size="5" Name="CompanyID" maxLength=5  ></TD>
        </TR>
        <TR>
            <TD>Company Name:</TD>
            <TD><INPUT Size="50" Name="CompanyName" ></TD>
        </TR>
        <TR>
            <TD>Contact First Name:</TD>
            <TD><INPUT Size="50" Name="FirstName" ></TD>
        </TR>
        <TR>
            <TD>Contact Last Name:</TD>
            <TD><INPUT Size="50" Name="LastName" ></TD>
        </TR>
        <TR>
            <TD>Contact Phone:</TD>
            <TD><INPUT Size="50" Name="PhoneNumber" ></TD>
        </TR>
        <TR>
            <TD>City:</TD>
            <TD><INPUT Size="50" Name="City" ></TD>
        </TR>
        <TR>
            <TD>State / Province:</TD>
            <TD><INPUT Size="5" Name="State" ></TD>
        </TR>
        <TR>
            <TD Align="right"><INPUT Type="submit" Value="Add New"></TD>
            <TD Align="left"><INPUT Type="reset" Value="Reset Form"></TD>
        </TR>
    </TABLE>
</FORM>

<%
    ' show connection
    Response.Write("Following is the connection string: <br><br>")
    Response.Write(Cnxn)

    ' Clean up.
    If rsCustomers.State = adStateOpen then
       rsCustomers.Close
    End If
    If Cnxn.State = adStateOpen then
       Cnxn.Close
    End If
    Set rsCustomers=Nothing
    Set Cnxn=Nothing
    Set fld=Nothing
%>

<SCRIPT Language = "VBScript">
Sub Form_OnSubmit
   MsgBox "Sending New Record to Server",,"ADO-ASP _Example"
End Sub
</SCRIPT>
</BODY>
</HTML>
<!-- EndAddNewVBS -->

请参阅

AddNew 方法 | Recordset 对象


Clone 方法范例 (VBScript)

本范例使用 Clone 方法来创建 Recordset 的副本，然后让用户单独定位每个副本的记录指针。

在 Active Server Page (ASP) 中使用下列范例。本范例使用与 Microsoft Access 一起发布的 Northwind 数据库。请将下列代码剪切并粘贴到记事本或其他文本编辑器中，并将其另存为 CloneVBS.asp。可以在任何客户端浏览器中查看结果。

要执行本范例，请将行 RsCustomerList.Source = "Customers" 更改为 RsCustomerList.Source = "Products"，以便计算更大的表。

<!-- BeginCloneVBS -->
<% Language = VBScript %>
<%' use this meta tag instead of adovbs.inc%>
<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->
<HTML>
<HEAD>
<TITLE>ADO Clone Method</TITLE>
</HEAD>

<BODY>

<H1 align="center">ADO Clone Method</H1>
<HR>
<% ' to integrate/test this code replace the
   ' Data Source value in the Connection string%>
<%
    ' connection and recordset variables
    Dim Cnxn, strCnxn
    Dim rsCustomers, strSQLCustomers
    Dim rsFirst, rsLast, rsCount
    Dim rsClone
    Dim CloneFirst, CloneLast, CloneCount

    ' open connection
    Set Cnxn = Server.CreateObject("ADODB.Connection")
    strCnxn = "Provider='sqloledb';Data Source=" & _
            Request.ServerVariables("SERVER_NAME") & ";" & _
            "Integrated Security='SSPI';Initial Catalog='Northwind';"
    Cnxn.Open strCnxn

    ' create and open Recordset using object refs
    Set rsCustomers = Server.CreateObject("ADODB.Recordset")
    strSQLCustomers = "Customers"

    rsCustomers.ActiveConnection = Cnxn
    rsCustomers.CursorLocation = adUseClient
    rsCustomers.CursorType = adOpenKeyset
    rsCustomers.LockType = adLockOptimistic
    rsCustomers.Source = strSQLCustomers
    rsCustomers.Open

    rsCustomers.MoveFirst
    rsCount = rsCustomers.RecordCount
    rsFirst = rsCustomers("CompanyName")
    rsCustomers.MoveLast
    rsLast = rsCustomers("CompanyName")

    ' create clone
    Set rsClone = rsCustomers.Clone
    rsClone.MoveFirst
    CloneCount = rsClone.RecordCount
    CloneFirst = rsClone("CompanyName")
    rsClone.MoveLast
    CloneLast = rsClone("CompanyName")
%>

<!-- Display Results -->
<H3>There Are <%=rsCount%> Records in the original recordset</H3>
<H3>The first record is <%=rsFirst%> and the last record is <%=rsLast%></H3>
<BR><HR>
<H3>There Are <%=CloneCount%> Records in the original recordset</H3>
<H3>The first record is <%=CloneFirst%> and the last record is <%=CloneLast%></H3>
<BR><HR>
<H4>Location of OLEDB Database</H4>

<%
    ' Show location of DSN data source
    Response.Write(Cnxn)

    ' Clean up
    If rsCustomers.State = adStateOpen then
       rsCustomers.Close
    End If
    If rsClone.State = adStateOpen then
       rsClone.Close
    End If
    If Cnxn.State = adStateOpen then
       Cnxn.Close
    End If
    Set rsCustomers = Nothing
    Set rsClone = Nothing
    Set Cnxn = Nothing
%>
</BODY>
</HTML>
<!-- EndCloneVBS -->

请参阅

Clone 方法 | Recordset 对象


Delete 方法范例 (VBScript)

本范例使用 Delete 方法从 Recordset 中删除指定的记录。

在 Active Server Page (ASP) 中使用下列范例。

使用 Find 定位文件 Adovbs.inc，并将其放到计划使用的目录中。请将下列代码剪切并粘贴到记事本或其他文本编辑器中，并将其另存为 DeleteVBS.asp。可以在任何客户端浏览器中查看结果。

要执行本范例，请先用 AddNew 范例来添加一些记录。然后可以尝试将其删除。可以在任何客户浏览器中查看结果。

<!-- BeginDeleteVBS -->
<%@ Language=VBScript %>
<% ' use this meta tag instead of ADOVBS.inc%>
<!-- METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4"  -->
<HTML>
<HEAD>
<TITLE>ADO Delete Method</TITLE>
</HEAD>
<STYLE>
<!--
TH {
   background-color: #008080;
   font-family: 'Arial Narrow','Arial',sans-serif;
   font-size: xx-small;
   color: white;
   }
TD {
   text-align: center;
   background-color: #f7efde;
   font-family: 'Arial Narrow','Arial',sans-serif;
   font-size: xx-small;
    }
-->
</STYLE>

<BODY>
<H3>ADO Delete Method</H3>

<%
    ' to integrate this code replace the DataSource value in the connection string

    ' connection and recordset variables
   Dim Cnxn, strCnxn
   Dim rsCustomers, strSQLCustomers

    ' create and open connection
   Set Cnxn = Server.CreateObject("ADODB.Connection")
   strCnxn="Provider='sqloledb';Data Source=" & _
            Request.ServerVariables("SERVER_NAME") & ";" & _
            "Integrated Security='SSPI';Initial Catalog='Northwind';"
   Cnxn.Open  strCnxn
    ' create and open recordset
   Set rsCustomers = Server.CreateObject("ADODB.Recordset")
   strSQLCustomers = "Customers"
   rsCustomers.Open strSQLCustomers, Cnxn, adOpenKeyset, adLockOptimistic, adCmdTable

   ' Move to designated record and delete it
   If Not IsEmpty(Request.Form("WhichRecord")) Then
      'Get value to move from Form Post method
      Moves = Request.Form("WhichRecord")

      rsCustomers.Move CInt(Moves)
      If Not rsCustomers.EOF or rsCustomers.BOF Then
          ' handle any db errors
         On Error Resume Next
         rsCustomers.Delete 1
         If Cnxn.Errors.Count <> 0 Then
            Response.Write "Cannot delete since there are related records in other tables."
            Response.End
         End If
         rsCustomers.MoveFirst
         On Error GoTo 0
      Else
         Response.Write "Not a Valid Record Number"
         rsCustomers.MoveFirst
      End If
   End If
%>

<!-- BEGIN column header row for Customer Table-->
<TABLE COLSPAN=8 CELLPADDING=5 BORDER=0>
<TR>
   <TH>Rec. #</TH>
   <TH>Company Name</TH>
   <TH>Contact Name</TH>
   <TH>City</TH>
</TR>

   <%
   ' Display ADO Data from Customer Table
   ' Loop through Recordset adding one row to HTML Table each pass
   Dim iCount
   iCount = 0
   Do Until rsCustomers.EOF %>
   <TR>
     <TD> <%= CStr(iCount) %>
     <TD> <%= rsCustomers("CompanyName")%> </TD>
     <TD> <%= rsCustomers("ContactName")%> </TD>
     <TD> <%= rsCustomers("City")%> </TD>
   </TR>
   <%
     iCount = iCount + 1
     rsCustomers.MoveNext
   Loop
   %>
</TABLE>

<!-- Do Client side Input Data Validation Move to named record and Delete it -->
<Center>
<H4>Clicking Button Will Remove Designated Record</H4>
<H5>There are <%=rsCustomers.RecordCount%> Records in this Set</H5>

<Form Method=Post Action="Deletevbs.asp" Name=Form>
   <Input Type=Text Name="WhichRecord" Size=3>
   <Input Type=Button Name=cmdDelete Value="Delete Record">
</Form>

</BODY>

<Script Language = "VBScript">
Sub cmdDelete_OnClick
   If IsNumeric(Document.Form.WhichRecord.Value) Then
      Document.Form.WhichRecord.Value = CInt(Document.Form.WhichRecord.Value)
      Dim Response
      Response = MsgBox("Are You Sure About Deleting This Record?", vbYesNo,  "ADO-ASP Example")

      If Response = vbYes Then
         Document.Form.Submit
      End If
   Else
      MsgBox "You Must Enter a Valid Record Number",,"ADO-ASP Example"
   End If
End Sub
</Script>

<%
    ' clean up
    If rsCustomers.State = adStateOpen then
        rsCustomers.Close
    End If
    If Cnxn.State = adStateOpen then
        Cnxn.Close
    End If
%>
</HTML>
<!-- EndDeleteVBS -->

请参阅

Delete 方法 (ADO Recordset) | Recordset 对象

© 1998-2002 Microsoft Corporation。保留所有权利。


Execute、Requery 和 Clear 方法范例 (VBScript)

本范例演示从 Command 和 Connection 对象运行 Execute 方法。范例中还使用 Requery 方法检索 Recordset 中的当前数据，并使用 Clear 方法清除 Errors 集合的内容。运行此过程需要 ExecuteCommand 和 PrintOutput 过程。

在 Active Server Page (ASP) 中使用下列范例。使用 Find 定位文件 Adovbs.inc，并将其放到计划使用的目录中。请将下列代码剪切并粘贴到记事本或其他文本编辑器中，并将其另存为 ExecuteVBS.asp。可以在任何客户端浏览器中查看结果。

<!-- BeginExecuteVBS -->
<%@ Language=VBScript %>
<% ' use this meta tag instead of ADOVBS.inc%>
<!-- METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4"  -->
<HTML>
<HEAD>
<META name="VI60_DefaultClientScript"  content=VBScript>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<title>ADO Execute Method</title>
<STYLE>
<!--
BODY {
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   BACKGROUND-COLOR:white;
   COLOR:black;
    }
.thead {
   background-color: #008080;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
   color: white;
   }
.thead2 {
   background-color: #800000;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
   color: white;
   }
.tbody {
   text-align: center;
   background-color: #f7efde;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
    }
-->
</STYLE>
</HEAD>

<BODY>
<H3>ADO Execute Method</H3>
<HR>
<H4>Recordset Retrieved Using Connection Object</H4>
<!--- Recordsets retrieved using Execute method of Connection and Command Objects-->
<%
     ' connection, command and recordset variables
    Dim Cnxn, strCnxn
    Dim rsCustomers, strSQLCustomers
    Dim Cmd
    Dim rsProducts, strSQLProducts

    ' create and open connection
    Set Cnxn = Server.CreateObject("ADODB.Connection")
    strCnxn="Provider='sqloledb';Data Source=" & _
            Request.ServerVariables("SERVER_NAME") & ";" & _
            "Integrated Security='SSPI';Initial Catalog='Northwind';"
    Cnxn.Open  strCnxn
    ' create and open recordset
    Set rsCustomers = Server.CreateObject("ADODB.Recordset")
    strSQLCustomers = "Customers"
    rsCustomers.Open strSQLCustomers, Cnxn, adOpenKeyset, adLockOptimistic, adCmdTable

    '1st Recordset using Connection - Execute
    Set rsCustomers = Cnxn.Execute(strSQLCustomers)

    Set Cmd = Server.CreateObject("ADODB.Command")
    Cmd.ActiveConnection = Cnxn
    strSQLProducts = "SELECT * From Products"
    Cmd.CommandText = strSQLProducts

    '2nd Recordset Cmd - execute
    Set rsProducts = Cmd.Execute
    %>
    <TABLE COLSPAN=8 CELLPADDING=5 BORDER=0 ALIGN=CENTER>
    <!-- BEGIN column header row for Customer Table-->
    <TR CLASS=thead>
      <TH>Company Name</TH>
      <TH>Contact Name</TH>
      <TH>City</TH>
    </TR>

    <!--Display ADO Data from Customer Table-->
    <%
    Do While Not rsCustomers.EOF %>
      <TR CLASS=tbody>
        <TD>
        <%= rsCustomers("CompanyName")%>
        </TD>
        <TD>
        <%= rsCustomers("ContactName") %>
        </TD>
        <TD>
        <%= rsCustomers("City")%>
        </TD>
      </TR>
      <%
    rsCustomers.MoveNext
    Loop
    %>
</TABLE>

<HR>
<H4>Recordset Retrieved Using Command Object</H4>

<TABLE CELLPADDING=5 BORDER=0 ALIGN=CENTER WIDTH="80%">

<!-- BEGIN column header row for Product List Table-->
<TR CLASS=thead2>
  <TH>Product Name</TH>
  <TH>Unit Price</TH>
</TR>

<!-- Display ADO Data Product List-->
<% Do Until rsProducts.EOF %>
  <TR CLASS=tbody>
    <TD>
    <%= rsProducts("ProductName")%>
    </TD>
    <TD>
    <%= rsProducts("UnitPrice")%>
    </TD>
<%
    rsProducts.MoveNext
    Loop

    ' clean up
    If rsCustomers.State = adStateOpen then
        rsCustomers.Close
    End If
    If rsProducts.State = adStateOpen then
        rsProducts.Close
    End If
    If Cnxn.State = adStateOpen then
        Cnxn.Close
    End If
    Set Cmd = Nothing
    Set rsCustomers = Nothing
    Set rsProducts = Nothing
    Set Cnxn = Nothing
%>
</TABLE>

</BODY>
</HTML>
<!-- EndExecuteVBS -->

请参阅

Clear 方法 | Command 对象 | Connection 对象 | Error 对象 | Errors 集合 | Execute 方法 (ADO Command) | Execute 方法 (ADO Connection) | Recordset 对象 | Requery 方法

© 1998-2002 Microsoft Corporation。保留所有权利。


Move 方法范例 (VBScript)

本范例使用 Move 方法按用户输入定位记录指针。

在 Active Server Page (ASP) 中使用下列范例。

使用 Find 定位 Adovbs.inc 文件，并将其放置在要使用的目录中。将下列代码剪切并粘贴到记事本或其他文本编辑器中，并将其保存为 Move.asp。您可以在任何浏览器中查看结果。

可尝试输入字母或非整数来查看错误处理的运作。

<!-- BeginMoveVBS -->
<%@ Language=VBScript %>
<%' use this meta tag instead of adovbs.inc%>
<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->
<HTML>
<HEAD>
<TITLE>ADO Move Methods</TITLE>
<STYLE>
<!--
BODY {
   font-family: "MS SANS SERIF",sans-serif;
    }
.thead1 {
   background-color: #008080;
   font-family: 'Arial Narrow','Arial',sans-serif;
   font-size: x-small;
   color: white;
   }
.tbody {
   text-align: center;
   background-color: #f7efde;
   font-family: 'Arial Narrow','Arial',sans-serif;
   font-size: x-small;
    }
-->
</STYLE>
</HEAD>
<BODY>
<H3>ADO Move Methods</H3>
<% ' to integrate/test this code replace the
   ' Data Source value in the Connection string%>
<%
    ' connection and recordset variables
    Dim Cnxn, strCnxn
    Dim rsCustomers, strSQLCustomers

    ' open connection
    Set Cnxn = Server.CreateObject("ADODB.Connection")
    strCnxn = "Provider='sqloledb';Data Source=" & _
            Request.ServerVariables("SERVER_NAME") & ";" & _
            "Integrated Security='SSPI';Initial Catalog='Northwind';"

    Cnxn.Open strCnxn

     ' create and open Recordset using object refs
    Set rsCustomers = Server.CreateObject("ADODB.Recordset")
    strSQLCustomers = "Customers"

    rsCustomers.ActiveConnection = Cnxn
    rsCustomers.CursorLocation = adUseClient
    rsCustomers.CursorType = adOpenKeyset
    rsCustomers.LockType = adLockOptimistic
    rsCustomers.Source = strSQLCustomers
    rsCustomers.Open

    'Check number of user moves this session and increment by entry
    Session("Clicks") = Session("Clicks") + Request.Form("MoveAmount")
    Clicks = Session("Clicks")
    ' Move to last known recordset position plus amount passed
    rsCustomers.Move CInt(Clicks)

    'Error Handling
    If rsCustomers.EOF Then
        Session("Clicks") = rsCustomers.RecordCount
        Response.Write "This is the Last Record"
        rsCustomers.MoveLast
    ElseIf rsCustomers.BOF Then
        Session("Clicks") = 1
        rsCustomers.MoveFirst
        Response.Write "This is the First Record"
    End If
    %>

    <H3>Current Record Number is <BR>
    <%
    If Session("Clicks") = 0 Then Session("Clicks") = 1
    Response.Write(Session("Clicks") )%> of <%=rsCustomers.RecordCount%></H3>
    <HR>

    <TABLE COLSPAN=8 CELLPADDING=5 BORDER=0>

    <!-- BEGIN column header row for Customer Table-->

    <TR CLASS=thead1>
       <TD>Company Name</TD>
       <TD>Contact Name</TD>
       <TD>City</TD>
    </TR>
        <% 'display%>
        <TR CLASS=tbody>
          <TD> <%= rsCustomers("CompanyName")%> </TD>
          <TD> <%= rsCustomers("ContactName")%></TD>
          <TD> <%= rsCustomers("City")%> </TD>
        </TR>
    </TABLE>

    <HR>
    <Input Type=Button Name=cmdDown  Value="&lt;  ">
    <Input Type=Button Name=cmdUp Value=" &gt;">
    <H5>Click Direction Arrows for Previous or Next Record
    <BR> <BR>

    <FORM Method = Post Action="MoveVbs.asp" Name=Form>
    <TABLE>
        <TR>
           <TD><Input Type="Button" Name=Move Value="Move Amount "></TD>
           <TD></TD>
           <TD><Input Type="Text" Size="4" Name="MoveAmount" Value=0></TD>
        <TR>
    </TABLE>
    Click Move Amount to use Move Method<br>
    Enter Number of Records to Move + or - </H5>    </FORM>
</BODY>

<Script Language = "VBScript">

Sub Move_OnClick
   ' Make sure move value entered is an integer
   If IsNumeric(Document.Form.MoveAmount.Value)Then
      Document.Form.MoveAmount.Value = CInt(Document.Form.MoveAmount.Value)
      Document.Form.Submit
   Else
      MsgBox "You Must Enter a Number", ,"ADO-ASP Example"
      Document.Form.MoveAmount.Value = 0
   End If
End Sub

Sub cmdDown_OnClick
   Document.Form.MoveAmount.Value = -1
   Document.Form.Submit
End Sub

Sub cmdUp_OnClick
   Document.Form.MoveAmount.Value = 1
   Document.Form.Submit
End Sub
</Script>

<%
    ' clean up
    If rsCustomers.State = adStateOpen then
        rsCustomers.Close
    End If
    If Cnxn.State = adStateOpen then
        Cnxn.Close
    End If
%>
</HTML>
<!-- EndMoveVBS -->

请参阅

Move 方法 | Recordset 对象

© 1998-2002 Microsoft Corporation。保留所有权利。


MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法范例 (VBScript)

本范例使用 MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法，按照提供的命令移动 Recordset 的记录指针。

将下列代码剪切并粘贴到记事本或其他文本编辑器中，并将其保存为 MoveFirstVBS.asp。您可以在任何浏览器中查看结果。

<!-- BeginMoveFirstVBS -->
<%@ Language=VBScript %>
<%' use this meta tag instead of adovbs.inc%>
<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->
<HTML>
<HEAD>
<TITLE>ADO MoveNext, MovePrevious, MoveLast, MoveFirst Methods</TITLE>

<SCRIPT LANGUAGE="VBScript">
<!--
   Sub cmdDown_OnClick
      'Set Values in Form Input Boxes and Submit Form
      Document.form.MoveAction.Value = "MovePrev"
      Document.Form.Submit
   End Sub

   Sub cmdUp_OnClick
      Document.form.MoveAction.Value = "MoveNext"
      Document.Form.Submit
   End Sub

   Sub cmdFirst_OnClick
      Document.form.MoveAction.Value = "MoveFirst"
      Document.Form.Submit
   End Sub

   Sub cmdLast_OnClick
      Document.form.MoveAction.Value = "MoveLast"
      Document.Form.Submit
   End Sub
//-->
</SCRIPT>
</HEAD>

<body bgcolor="white">
<h1 align="center">ADO MoveNext, MovePrevious <br> MoveLast & MoveFirst Methods</h1>
<% ' to integrate/test this code replace the
   ' Data Source value in the Connection string%>
<%
   ' connection and recordset variables
   Dim Cnxn, strCnxn
   Dim rsEmployees, strSQLEmployees

   ' open connection
    Set Cnxn = Server.CreateObject("ADODB.Connection")
    strCnxn = "Provider='sqloledb';Data Source=" & _
            Request.ServerVariables("SERVER_NAME") & ";" & _
            "Integrated Security='SSPI';Initial Catalog='Northwind';"
    Cnxn.Open strCnxn

    ' create and open Recordset using object refs
   Set rsEmployees = Server.CreateObject("ADODB.Recordset")
   strSQLEmployees = "Employees"

   rsEmployees.ActiveConnection = Cnxn
   rsEmployees.CursorLocation = adUseClient
   rsEmployees.CursorType = adOpenKeyset
   rsEmployees.LockType = adLockOptimistic
   rsEmployees.Source = strSQLEmployees
   rsEmployees.Open

   rsEmployees.MoveFirst

   If Not IsEmpty(Request.Form("MoveAction")) Then
      strAction = Request.Form("MoveAction")
      varPosition  = Request.Form("Position")

      rsEmployees.AbsolutePosition = varPosition

      Select Case strAction

        Case "MoveNext"

         rsEmployees.MoveNext
         If rsEmployees.EOF Then
            rsEmployees.MoveLast
            strMessage = "Can't move beyond the last record."
         End If

        Case "MovePrev"

         rsEmployees.MovePrevious
         If rsEmployees.BOF Then
            rsEmployees.MoveFirst
            strMessage = "Can't move beyond the first record."
         End If

        Case "MoveLast"

         rsEmployees.MoveLast

        Case "MoveFirst"

         rsEmployees.MoveFirst

      End Select
   End If

%>

<!-- Display Current Record Number and Recordset Size -->
<h2>Record Number <%=rsEmployees.AbsolutePosition%> of <%=rsEmployees.RecordCount%></H2>
<hr>
<table cellpadding=5 border=0>
<!-- BEGIN column header row for Customer Table-->
<tr>
   <th>Name</th>
   <th>Hire Date</th>
</tr>

<!--Display ADO Data from Customer Table-->
<tr>
  <td><%= rsEmployees("LastName") & ", " %>
      <%= rsEmployees("FirstName") & " " %></td>
  <td><%= rsEmployees("HireDate")%></td>
</tr>
<tr>
  <td colspan=2><%=strMessage%></td>
</tr>
</table>

<hr>

<form Name="Form" Method="Post" Action="MoveFirstVbs.asp">
<Input Type=Button Name=cmdDown Value="<">
<Input Type=Button Name=cmdUp Value=">">
<BR>
<H3>Click Direction Arrows to Use MovePrevious or MoveNext</H3>
<Input Type=Button Name=cmdFirst Value="First Record">
<Input Type=Button Name=cmdLast Value="Last Record">

<!-- Use Hidden Form Fields to record values to send to Server -->

<input Type="Hidden" Size="4" Name="MoveAction" Value="Move">
<input Type="Hidden" Size="4" Name="Position" Value="<%= rsEmployees.AbsolutePosition%>">
</form>

<HR>
</BODY>

<%
    ' clean up
    If rsEmployees.State = adStateOpen then
        rsEmployees.Close
    End If
    If Cnxn.State = adStateOpen then
        Cnxn.Close
    End If
%>
</HTML>
<!-- EndMoveFirstVBS -->

请参阅

MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法 | Recordset 对象


Open 和 Close 方法范例 (VBScript)

本范例在已打开的 Recordset 和 Connection 对象上使用 Open 和 Close 方法。

在 Active Server Page (ASP) 中使用下列范例。使用 Find 定位 Adovbs.inc 文件，并将其放置在要使用的目录中。将下列代码剪切并粘贴到记事本或其他文本编辑器中，并将其保存为 OpenVBS.asp。您可以在任何浏览器中查看结果。

<!-- BeginOpenVBS -->
<%@ Language=VBScript %>
<%' use this meta tag instead of adovbs.inc%>
<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->
<HTML>
<HEAD>
<META name="VI60_DefaultClientScript"  content=VBScript>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<title>ADO Open Method</title>
<STYLE>
<!--
BODY {
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   BACKGROUND-COLOR:white;
   COLOR:black;
    }
.thead {
   background-color: #008080;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
   color: white;
   }
.thead2 {
   background-color: #800000;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
   color: white;
   }
.tbody {
   text-align: center;
   background-color: #f7efde;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
    }
-->
</STYLE>
</HEAD>

<BODY>
<H3>ADO Open Method</H3>

<TABLE WIDTH=600 BORDER=0>
<TR>
<TD VALIGN=TOP COLSPAN=3>
<FONT SIZE=2>
<% ' to integrate/test this code replace the
   ' Data Source value in the Connection string%>
<%
    ' connection and recordset variables
    Dim Cnxn, strCnxn
    Dim rsCustomers, strSQLCustomers
    Dim rsProducts, strSQLProducts

    ' open connection
    Set Cnxn = Server.CreateObject("ADODB.Connection")
    strCnxn = "Provider='sqloledb';Data Source=" & _
            Request.ServerVariables("SERVER_NAME") & ";" & _
            "Integrated Security='SSPI';Initial Catalog='Northwind';"

    Cnxn.Open strCnxn

    ' create and open first Recordset using Connection - execute
    Set rsCustomers = Server.CreateObject("ADODB.Recordset")
    strSQLCustomers = "SELECT CompanyName, ContactName, City FROM Customers"
    Set rsCustomers = Cnxn.Execute(strSQLCustomers)

    ' create and open second Recordset using recordset - open
    Set rsProducts = Server.CreateObject("ADODB.Recordset")
    strSQLProducts = "SELECT ProductName, UnitPrice FROM Products"
    rsProducts.Open strSQLProducts, Cnxn, adOpenDynamic, adLockPessimistic, adCmdText
    %>

    <TABLE COLSPAN=8 CELLPADDING=5 BORDER=0>
    <!-- BEGIN column header row for Customer Table-->
    <TR CLASS=thead>
       <TD>Company Name</TD>
       <TD>Contact Name</TD>
       <TD>City</TD>
    </TR>

    <!--Display ADO Data from Customer Table-->
    <% Do Until rsCustomers.EOF %>
    <TR CLASS=tbody>
      <TD> <%=rsCustomers("CompanyName")%> </TD>
      <TD> <%=rsCustomers("ContactName")%></TD>
      <TD> <%=rsCustomers("City")%> </TD>
    </TR>
    <%rsCustomers.MoveNext
    Loop
    %>
    </TABLE>

    <HR>

    <TABLE COLSPAN=8 CELLPADDING=5 BORDER=0>
    <!-- BEGIN column header row for Product List Table-->

    <TR CLASS=thead2>
       <TD>Product Name</TD>
       <TD>Unit Price</TD>
    </TR>
    <!-- Display ADO Data Product List-->
    <% Do Until rsProducts.EOF %>
      <TR CLASS=tbody>
      <TD> <%=rsProducts("ProductName")%> </TD>
      <TD> <%=rsProducts("UnitPrice")%> </TD>
      </TR>
      <!--  Next Row = Record -->
    <%rsProducts.MoveNext
    Loop

    ' clean up
    If rsProducts.State = adStateOpen then
        rsProducts.Close
    End If
    If rsCustomers.State = adStateOpen then
        rsCustomers.Close
    End If
    If Cnxn.State = adStateOpen then
        Cnxn.Close
    End If
    Set rsProducts = Nothing
    Set rsCustomers = Nothing
    Set Cnxn = Nothing

    %>
    </TABLE>

</BODY>
</HTML>
<!-- EndOpenVBS -->

请参阅

Close 方法 | Connection 对象 | Open 方法 (ADO Connection) | Open 方法 (ADO Recordset) | Recordset 对象


Microsoft Visual C++ 中的 ADO 代码范例

通过下列代码范例来学习用 Microsoft Visual C++ 编程时如何使用 ADO 方法、属性和事件。

注意 请将整个代码范例（从开始到结束）粘贴到代码编辑器中。如果只使用部分范例或者丢失了段落格式，范例可能无法正确运行。

方法

  • AddNew 方法范例
  • Append 和 CreateParameter 方法范例
  • AppendChunk 和 GetChunk 方法范例
  • BeginTrans、CommitTrans 和 RollbackTrans 方法范例
  • Cancel 方法范例
  • Clone 方法范例
  • CompareBookmarks 方法范例
  • Delete 方法范例
  • Execute、Requery 和 Clear 方法范例
  • Find 方法范例
  • GetRows 方法范例
  • GetString 方法范例
  • MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法范例
  • NextRecordset 方法范例
  • Open 和 Close 方法范例
  • OpenSchema 方法范例
  • Refresh 方法范例
  • Resync 方法范例
  • Save 和 Open 方法范例
  • Seek 方法和 Index 属性范例
  • Supports 方法范例
  • Update 和 CancelUpdate 方法范例
  • UpdateBatch 和 CancelBatch 方法范例

Properties

  • AbsolutePage、PageCount 和 PageSize 属性范例
  • AbsolutePosition 和 CursorLocation 属性范例
  • ActiveCommand 属性范例
  • ActiveConnection、CommandText、CommandTimeout、CommandType、Size 和 Direction 属性范例
  • ActualSize 和 DefinedSize 属性范例
  • Attributes 和 Name 属性范例
  • BOF、EOF 和 Bookmark 属性范例
  • CacheSize 属性范例
  • ConnectionString、ConnectionTimeout 和 State 属性范例
  • Count 属性范例
  • CursorType、LockType 和 EditMode 属性范例
  • Description、HelpContext、HelpFile、NativeError、Number、Source 和 SQLState 属性范例
  • Filter 和 RecordCount 属性范例
  • Index 属性和 Seek 方法范例
  • IsolationLevel 和 Mode 属性范例
  • Item 属性范例
  • MarshalOptions 属性范例
  • MaxRecords 属性范例
  • NumericScale 和 Precision 属性范例
  • Optimize 属性范例
  • OriginalValue 和 UnderlyingValue 属性范例
  • Prepared 属性范例
  • Provider 和 DefaultDatabase 属性范例
  • Sort 属性范例
  • Source 属性范例
  • State 属性范例
  • Status 属性范例
  • StayInSync 属性范例
  • Type 属性范例 (Fields)
  • Type 属性范例 (Property)
  • Value 属性范例
  • Version 属性范例

其他

  • ADO 事件模型范例

请参阅

Microsoft Visual Basic 中的 ADO 代码范例 | Microsoft Visual Basic Scripting Edition 中的 ADO 代码范例 | Microsoft Visual J++ 中的 ADO 代码范例


ADO 事件模型范例 (VC++)

不同语言的 ADO 事件实例的 Visual C++ 一节将对实例化 ADO 事件模型的方式进行常规说明。下面是一个在由 #import 伪指令创建的环境中实例化事件模型的特定范例。

常规说明中使用 adoint.h 作为方法声明的引用。但是由于使用 #import 伪指令，因此常规说明中的一些细节需要稍微做些更改。

  • #import 伪指令将 typedef、方法声明数据类型和组合键分解为其基本格式。
  • 所有必须覆盖的纯虚拟方法都被加上前缀“raw_”。

某些代码只反映编码样式。

  • Advise 方法使用的指向 IUnknown 的指针是通过 QueryInterface 调用显式获取的。
  • 不需要在类定义中对析构函数进行显式编码。
  • 用户可能需要使 QueryInterface、AddRef 和 Release 的编码更加可靠。
  • __uuidof() 伪指令的用法可扩展用于获取接口 ID。

最后，该范例还包含某些实用代码。

  • 该范例被编写为控制台应用程序。
  • 应在注释“// Do some work”下插入用户自己的代码。
  • 默认情况下所有事件处理程序不进行任何操作，并且取消进一步的通知。用户应当针对自己的应用程序插入适当的代码，如果需要应允许通知。
// eventmodel.cpp : Defines the entry point for the console application.
//

#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
   no_namespace rename("EOF", "EndOfFile")
#include <comdef.h>
#include <stdio.h>

//----The Connection events----------------------------------------------

class CConnEvent : public ConnectionEventsVt
{
private:
      ULONG   m_cRef;
   public:
      CConnEvent() { m_cRef = 0; };
      ~CConnEvent() {};

      STDMETHODIMP QueryInterface(REFIID riid, void ** ppv);
      STDMETHODIMP_(ULONG) AddRef(void);
      STDMETHODIMP_(ULONG) Release(void);

      STDMETHODIMP raw_InfoMessage(
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Connection *pConnection);

      STDMETHODIMP raw_BeginTransComplete(
         LONG TransactionLevel,
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Connection *pConnection);

   STDMETHODIMP raw_CommitTransComplete(
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Connection *pConnection);

      STDMETHODIMP raw_RollbackTransComplete(
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Connection *pConnection);

      STDMETHODIMP raw_WillExecute(
         BSTR *Source,
         CursorTypeEnum *CursorType,
         LockTypeEnum *LockType,
         long *Options,
         EventStatusEnum *adStatus,
         struct _Command *pCommand,
         struct _Recordset *pRecordset,
         struct _Connection *pConnection);

      STDMETHODIMP raw_ExecuteComplete(
         LONG RecordsAffected,
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Command *pCommand,
         struct _Recordset *pRecordset,
         struct _Connection *pConnection);

   STDMETHODIMP raw_WillConnect(
         BSTR *ConnectionString,
         BSTR *UserID,
         BSTR *Password,
         long *Options,
         EventStatusEnum *adStatus,
         struct _Connection *pConnection);

      STDMETHODIMP raw_ConnectComplete(
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Connection *pConnection);

      STDMETHODIMP raw_Disconnect(
         EventStatusEnum *adStatus,
         struct _Connection *pConnection);
};

//-----The Recordset events----------------------------------------------

class CRstEvent : public RecordsetEventsVt
    {
   private:
      ULONG m_cRef;
    public:
      CRstEvent() { m_cRef = 0; };
      ~CRstEvent() {};

         STDMETHODIMP QueryInterface(REFIID riid, void ** ppv);
         STDMETHODIMP_(ULONG) AddRef(void);
         STDMETHODIMP_(ULONG) Release(void);

         STDMETHODIMP raw_WillChangeField(
         LONG cFields,
         VARIANT Fields,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset);

      STDMETHODIMP raw_FieldChangeComplete(
         LONG cFields,
         VARIANT Fields,
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset);

      STDMETHODIMP raw_WillChangeRecord(
         EventReasonEnum adReason,
         LONG cRecords,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset);

      STDMETHODIMP raw_RecordChangeComplete(
         EventReasonEnum adReason,
         LONG cRecords,
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset);

      STDMETHODIMP raw_WillChangeRecordset(
         EventReasonEnum adReason,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset);

      STDMETHODIMP raw_RecordsetChangeComplete(
         EventReasonEnum adReason,
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset);

      STDMETHODIMP raw_WillMove(
         EventReasonEnum adReason,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset);

      STDMETHODIMP raw_MoveComplete(
         EventReasonEnum adReason,
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset);

      STDMETHODIMP raw_EndOfRecordset(
         VARIANT_BOOL *fMoreData,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset);

      STDMETHODIMP raw_FetchProgress(
         long Progress,
         long MaxProgress,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset);

      STDMETHODIMP raw_FetchComplete(
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset);
};

//-----Implement each connection method----------------------------------

      STDMETHODIMP CConnEvent::raw_InfoMessage(
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Connection *pConnection)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

      STDMETHODIMP CConnEvent::raw_BeginTransComplete(
         LONG TransactionLevel,
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Connection *pConnection)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

      STDMETHODIMP CConnEvent::raw_CommitTransComplete(
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Connection *pConnection)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

      STDMETHODIMP CConnEvent::raw_RollbackTransComplete(
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Connection *pConnection)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

   STDMETHODIMP CConnEvent::raw_WillExecute(
         BSTR *Source,
         CursorTypeEnum *CursorType,
         LockTypeEnum *LockType,
         long *Options,
         EventStatusEnum *adStatus,
         struct _Command *pCommand,
         struct _Recordset *pRecordset,
         struct _Connection *pConnection)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

      STDMETHODIMP CConnEvent::raw_ExecuteComplete(
         LONG RecordsAffected,
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Command *pCommand,
         struct _Recordset *pRecordset,
         struct _Connection *pConnection)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

      STDMETHODIMP CConnEvent::raw_WillConnect(
         BSTR *ConnectionString,
         BSTR *UserID,
         BSTR *Password,
         long *Options,
         EventStatusEnum *adStatus,
         struct _Connection *pConnection)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

      STDMETHODIMP CConnEvent::raw_ConnectComplete(
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Connection *pConnection)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

      STDMETHODIMP CConnEvent::raw_Disconnect(
         EventStatusEnum *adStatus,
         struct _Connection *pConnection)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

//-----Implement each recordset method-----------------------------------

      STDMETHODIMP CRstEvent::raw_WillChangeField(
         LONG cFields,
         VARIANT Fields,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

      STDMETHODIMP CRstEvent::raw_FieldChangeComplete(
         LONG cFields,
         VARIANT Fields,
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

      STDMETHODIMP CRstEvent::raw_WillChangeRecord(
         EventReasonEnum adReason,
         LONG cRecords,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

      STDMETHODIMP CRstEvent::raw_RecordChangeComplete(
         EventReasonEnum adReason,
         LONG cRecords,
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

      STDMETHODIMP CRstEvent::raw_WillChangeRecordset(
         EventReasonEnum adReason,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

      STDMETHODIMP CRstEvent::raw_RecordsetChangeComplete(
         EventReasonEnum adReason,
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

      STDMETHODIMP CRstEvent::raw_WillMove(
         EventReasonEnum adReason,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

      STDMETHODIMP CRstEvent::raw_MoveComplete(
         EventReasonEnum adReason,
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

      STDMETHODIMP CRstEvent::raw_EndOfRecordset(
         VARIANT_BOOL *fMoreData,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

      STDMETHODIMP CRstEvent::raw_FetchProgress(
         long Progress,
         long MaxProgress,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

      STDMETHODIMP CRstEvent::raw_FetchComplete(
         struct Error *pError,
         EventStatusEnum *adStatus,
         struct _Recordset *pRecordset)
         {
         *adStatus = adStatusUnwantedEvent;
         return S_OK;
         };

//-----Implement QueryInterface, AddRef, and Release---------------------

   STDMETHODIMP CRstEvent::QueryInterface(REFIID riid, void ** ppv)
   {
      *ppv = NULL;
      if (riid == __uuidof(IUnknown) ||
              riid == __uuidof(RecordsetEventsVt)) *ppv = this;
      if (*ppv == NULL)
         return ResultFromScode(E_NOINTERFACE);
      AddRef();
      return NOERROR;
   }
   STDMETHODIMP_(ULONG) CRstEvent::AddRef(void) { return ++m_cRef; };
   STDMETHODIMP_(ULONG) CRstEvent::Release()
                              {
                              if (0 != --m_cRef) return m_cRef;
                              delete this;
                              return 0;
                              }

   STDMETHODIMP CConnEvent::QueryInterface(REFIID riid, void ** ppv)

   {
      *ppv = NULL;
      if (riid == __uuidof(IUnknown) ||
          riid == __uuidof(ConnectionEventsVt)) *ppv = this;
      if (*ppv == NULL)
         return ResultFromScode(E_NOINTERFACE);
      AddRef();
      return NOERROR;
   }
   STDMETHODIMP_(ULONG) CConnEvent::AddRef() { return ++m_cRef; };
   STDMETHODIMP_(ULONG) CConnEvent::Release()
                              {
                              if (0 != --m_cRef) return m_cRef;
                              delete this;
                              return 0;
                              }

//-----Write your main block of code-------------------------------------

int main(int argc, char* argv[])
{
   HRESULT hr;
   DWORD   dwConnEvt;
   DWORD   dwRstEvt;
   IConnectionPointContainer   *pCPC = NULL;
   IConnectionPoint         *pCP = NULL;
   IUnknown               *pUnk = NULL;
   CRstEvent               *pRstEvent = NULL;
   CConnEvent               *pConnEvent= NULL;
   int                     rc = 0;
   _RecordsetPtr            pRst;
   _ConnectionPtr            pConn;

   ::CoInitialize(NULL);

   hr = pConn.CreateInstance(__uuidof(Connection));
   if (FAILED(hr)) return rc;

   hr = pRst.CreateInstance(__uuidof(Recordset));
   if (FAILED(hr)) return rc;

   // Start using the Connection events

   hr = pConn->QueryInterface(__uuidof(IConnectionPointContainer),
      (void **)&pCPC);
   if (FAILED(hr)) return rc;
   hr = pCPC->FindConnectionPoint(__uuidof(ConnectionEvents), &pCP);
   pCPC->Release();
   if (FAILED(hr)) return rc;

   pConnEvent = new CConnEvent();
   hr = pConnEvent->QueryInterface(__uuidof(IUnknown), (void **) &pUnk);
   if (FAILED(hr)) return rc;
   hr = pCP->Advise(pUnk, &dwConnEvt);
   pCP->Release();
   if (FAILED(hr)) return rc;

   // Start using the Recordset events

   hr = pRst->QueryInterface(__uuidof(IConnectionPointContainer),
      (void **)&pCPC);
   if (FAILED(hr)) return rc;
   hr = pCPC->FindConnectionPoint(__uuidof(RecordsetEvents), &pCP);
   pCPC->Release();
   if (FAILED(hr)) return rc;

   pRstEvent = new CRstEvent();
   hr = pRstEvent->QueryInterface(__uuidof(IUnknown), (void **) &pUnk);
   if (FAILED(hr)) return rc;
   hr = pCP->Advise(pUnk, &dwRstEvt);
   pCP->Release();
   if (FAILED(hr)) return rc;

   // Do some work

   pConn->Open("dsn=Pubs;", "MyUserName", "MyPassword", adConnectUnspecified);
   pRst->Open("SELECT * FROM authors", (IDispatch *) pConn,
         adOpenStatic, adLockReadOnly, adCmdText);
   pRst->MoveFirst();
   while (pRst->EndOfFile == FALSE)
   {
      wprintf(L"Name = '%s'\n", (wchar_t*)
         ((_bstr_t) pRst->Fields->GetItem("au_lname")->Value));
      pRst->MoveNext();
   }

   pRst->Close();
   pConn->Close();

   // Stop using the Connection events

   hr = pConn->QueryInterface(__uuidof(IConnectionPointContainer),
      (void **) &pCPC);
   if (FAILED(hr)) return rc;
   hr = pCPC->FindConnectionPoint(__uuidof(ConnectionEvents), &pCP);
   pCPC->Release();
   if (FAILED(hr)) return rc;
   hr = pCP->Unadvise( dwConnEvt );
   pCP->Release();
   if (FAILED(hr)) return rc;

   // Stop using the Recordset events
   hr = pRst->QueryInterface(__uuidof(IConnectionPointContainer),
      (void **) &pCPC);
   if (FAILED(hr)) return rc;
   hr = pCPC->FindConnectionPoint(__uuidof(RecordsetEvents), &pCP);
   pCPC->Release();
   if (FAILED(hr)) return rc;
   hr = pCP->Unadvise( dwRstEvt );
   pCP->Release();
   if (FAILED(hr)) return rc;

   CoUninitialize();
   return 1;
}


AbsolutePage、PageCount 和 PageSize 属性范例 (VC++)

本范例使用 AbsolutePage、PageCount 和 PageSize 属性显示 Employee 表中的姓名和受雇日期，每次显示五个记录。

// BeginAbsolutePageCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <stdio.h>
#include <ole2.h>
#include "conio.h"
#include "AbsolutepageX.h"

//Function Declarations.
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void AbsolutePageX(void);
void PrintProviderError(_ConnectionPtr pConnection);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    AbsolutePageX();

    ::CoUninitialize();
}

/////////////////////////////////////////////////////////////
//                                                         //
//      AbsolutePageX Function                             //
//                                                         //
/////////////////////////////////////////////////////////////

void AbsolutePageX(void)
{

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr   pRstEmployees   = NULL;

    //Define Other Variables
    //Interface Pointer declared.(VC++ Extensions)
    IADORecordBinding   *picRs = NULL;
    CEmployeeRs emprs;          //C++ class object
    HRESULT hr = S_OK;
    _bstr_t strMessage;

    //Open a recordset using a Client Cursor
    //For the Employee Table

    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
        "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        // Open a recordset.
        TESTHR(hr = pRstEmployees.CreateInstance(__uuidof(Recordset)));

        // Use client cursor to enable Absoluteposition property.
        pRstEmployees->CursorLocation = adUseClient;

        // You have to explicitly pass the default Cursor type
        // and LockType to the Recordset here
        TESTHR(hr = pRstEmployees->Open("employee",
            strCnn,adOpenForwardOnly,adLockReadOnly,adCmdTable));

        //Open an IADORecordBinding interface pointer which we'll use for
        //Binding Recordset to a class
        TESTHR(hr = pRstEmployees->QueryInterface
            (__uuidof(IADORecordBinding), (LPVOID*)&picRs));

        //Bind the Recordset to a C++ Class here
        TESTHR(hr = picRs->BindToRecordset(&emprs));

        //Display Names and hire dates, five records at a time
        pRstEmployees->PageSize = 5;

        int intPageCount = pRstEmployees->PageCount;

        for(int intPage=1;intPage<=intPageCount;intPage++)
        {
            pRstEmployees->put_AbsolutePage((enum PositionEnum)intPage);
            strMessage = "";

            for(int intRecord=1;
                intRecord<=pRstEmployees->PageSize;intRecord++)
            {
                printf("\t%s %s %.10s\n",
                    emprs.lau_fnameStatus == adFldOK ?
                    emprs.m_szau_fname : "<NULL>",
                    emprs.lau_lnameStatus == adFldOK ?
                    emprs.m_szau_lname : "<NULL>",
                    emprs.lau_hiredateStatus == adFldOK ?
                    emprs.m_szau_hiredate : "<NULL>");

                pRstEmployees->MoveNext();

                if(pRstEmployees->EndOfFile)
                    break;
            }

            printf("\n Press any key to continue...");getch();

            //Clear the Screen for the next Display
            system("cls");
        }
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _variant_t vtConnect = pRstEmployees->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                printf("Error:\n");
                printf("Code = %08lx\n", e.Error());
                printf("Message = %s\n", e.ErrorMessage());
                printf("Source = %s\n", (LPCSTR) e.Source());
                printf("Description = %s\n", (LPCSTR) e.Description());
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }
    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (pRstEmployees)
        if (pRstEmployees->State == adStateOpen)
            pRstEmployees->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr  pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        printf("Error:\n");
        for(long iError = 0; iError < nCount; iError++)
        {
            pErr = pConnection->Errors->GetItem(iError);
            printf("\t Error number: %x\t%s\n", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}
//EndAbsolutePageCpp

AbsolutePageX.h

// BeginAbsolutePageH
#include "icrsint.h"

//This Class extracts only fname,lastname and hire_date

class CEmployeeRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CEmployeeRs)

    //Column fname is the 2nd field in the table
   ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_szau_fname,
         sizeof(m_szau_fname), lau_fnameStatus, FALSE)

   ADO_VARIABLE_LENGTH_ENTRY2(4, adVarChar, m_szau_lname,
         sizeof(m_szau_lname), lau_lnameStatus, TRUE)

   ADO_VARIABLE_LENGTH_ENTRY2(8, adVarChar, m_szau_hiredate,
         sizeof(m_szau_hiredate), lau_hiredateStatus, TRUE)

END_ADO_BINDING()

public:
   CHAR   m_szau_lname[41];
   ULONG  lau_lnameStatus;
   CHAR   m_szau_fname[41];
   ULONG  lau_fnameStatus;
   CHAR   m_szau_hiredate[40];
   ULONG  lau_hiredateStatus;

};
// EndAbsolutePageH

请参阅

AbsolutePage 属性 | PageCount 属性 | PageSize 属性 | Recordset 对象


AbsolutePosition 和 CursorLocation 属性范例 (VC++)

本范例演示 AbsolutePosition 属性如何跟踪循环的进度。该循环用于枚举 Recordset 中的所有记录。范例中使用了 CursorLocation 属性，通过将游标设置为客户端游标来启用 AbsolutePosition 属性。

// BeginAbsolutePositionCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include "conio.h"
#include "AbsolutePositionX.h"

//Function Declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void AbsolutePositionX(void);
void AbsolutePosition2X(void);
void PrintProviderError(_ConnectionPtr pConnection);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    AbsolutePositionX();

    //Clear the screen for the next display
    printf("Press any key to continue...");
    getch();
    system("cls");

    AbsolutePosition2X();

    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      AbsolutePositionX Function                       //
//                                                       //
///////////////////////////////////////////////////////////

void AbsolutePositionX(void)
{
    HRESULT hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr  pRstEmployees  = NULL;

    //Define Other Variables
    //Interface Pointer declared.(VC++ Extensions)
    IADORecordBinding *picRs = NULL;
    CEmployeeRs emprs;                  //C++ class object
    _bstr_t strMessage;
    char chKey;

    //Open a recordset using a Client Cursor
    //For the Employee Table

    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
        "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        //Open a recordset.
        TESTHR(pRstEmployees.CreateInstance(__uuidof(Recordset)));

        //Use client cursor to enable Absoluteposition property.
        pRstEmployees->CursorLocation = adUseClient;

        //You have to explicitly pass the default Cursor type
        //and LockType to the Recordset.
        TESTHR(  pRstEmployees->Open("employee",
        strCnn,adOpenForwardOnly,adLockReadOnly,adCmdTable));

        // Open an IADORecordBinding interface pointer which we'll use
        // for Binding Recordset to a class.
        TESTHR(pRstEmployees->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        //Bind the Recordset to a C++ Class here
        TESTHR(picRs->BindToRecordset(&emprs));

        strMessage= "";

        //Enumerate recordset
        do
        {
            //Display Current Record Information
            printf("Employee : %s \n record %ld of %d",
                emprs.lau_lnameStatus == adFldOK ?
                emprs.m_szau_lname : "<NULL>",
                pRstEmployees->AbsolutePosition,
                    pRstEmployees->RecordCount);

            printf("\nContinue?(y/n)  :");

            do
            {
                chKey = getch();
            }while(chKey != 'y' && chKey !='n');

            //Clear the Screen for the next output
            system("cls");

            if(chKey == 'n')
                break;

            strMessage = "";
            pRstEmployees->MoveNext();
        }while(!(pRstEmployees->EndOfFile));
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _variant_t vtConnect = pRstEmployees->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                printf("Error:\n");
                printf("Code = %08lx\n", e.Error());
                printf("Message = %s\n", e.ErrorMessage());
                printf("Source = %s\n", (LPCSTR) e.Source());
                printf("Description = %s\n", (LPCSTR) e.Description());
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (pRstEmployees)
        if (pRstEmployees->State == adStateOpen)
            pRstEmployees->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      AbsolutePosition2X Function                       //
//                                                       //
///////////////////////////////////////////////////////////

void AbsolutePosition2X(void)
{
    HRESULT hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr  pRstEmployees  = NULL;

    //Define Other Variables
    //Interface Pointer declared.(VC++ Extensions)
    IADORecordBinding *picRs = NULL;
    CEmployeeRs emprs;                  //C++ class object
    _bstr_t strMessage;

    //Open a recordset using a Client Cursor
    //For the Employee Table

    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
        "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        //Open a recordset.
        TESTHR(pRstEmployees.CreateInstance(__uuidof(Recordset)));

        //Use client cursor to enable Absoluteposition property.
        pRstEmployees->CursorLocation = adUseClient;

        //You have to explicitly pass the default Cursor type
        //and LockType to the Recordset.
        TESTHR(pRstEmployees->Open("employee",
          strCnn,adOpenStatic,adLockReadOnly,adCmdTable));

        // Open an IADORecordBinding interface pointer which we'll use
        // for Binding Recordset to a class.
        TESTHR(pRstEmployees->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        //Bind the Recordset to a C++ Class here
        TESTHR(picRs->BindToRecordset(&emprs));

        long lGoToPos = 21;

        pRstEmployees->AbsolutePosition = (PositionEnum)lGoToPos;

        //Display Current Record Information
        printf("Employee : %s \n record %ld of %d",
            emprs.lau_lnameStatus == adFldOK ? emprs.m_szau_lname : "<NULL>", pRstEmployees->AbsolutePosition,
            pRstEmployees->RecordCount);

        printf("\nPress any key to continue:");
        getch();
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _variant_t vtConnect = pRstEmployees->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                printf("Error:\n");
                printf("Code = %08lx\n", e.Error());
                printf("Message = %s\n", e.ErrorMessage());
                printf("Source = %s\n", (LPCSTR) e.Source());
                printf("Description = %s\n", (LPCSTR) e.Description());
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (pRstEmployees)
        if (pRstEmployees->State == adStateOpen)
            pRstEmployees->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;
    long      nCount  = 0;
    long      i     = 0;

    if( (pConnection->Errors->Count) > 0)
    {
        nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s",
                pErr->Number,(LPCSTR) pErr->Description);
        }
    }
}

// EndAbsolutePositionCpp

AbsolutePositionX.h

// BeginAbsolutePositionH
#include <ole2.h>
#include <stdio.h>
#include "icrsint.h"

//This Class extracts lastname.

class CEmployeeRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CEmployeeRs)

    //Column lname is the 4th field in the recordset

   ADO_VARIABLE_LENGTH_ENTRY2(4, adVarChar, m_szau_lname,
         sizeof(m_szau_lname), lau_lnameStatus, TRUE)

END_ADO_BINDING()

public:
   CHAR   m_szau_lname[41];
   ULONG  lau_lnameStatus;

};
// EndAbsolutePositionH

请参阅

AbsolutePosition 属性 | CursorLocation 属性 | Recordset 对象


ActiveCommand 属性范例 (VC++)

本范例演示 ActiveCommand 属性。

向子例程提供一个 Recordset 对象，该对象的 ActiveCommand 属性用于显示创建 Recordset 的命令文本和参数。

// BeginActiveCommandCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>
#include "ActiveCommandX.h"

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void ActiveCommandX(void);
void ActiveCommandXprint(_RecordsetPtr pRst);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);
inline char* mygets(char* strDest, int n)
{
    char strExBuff[10];
    char* pstrRet = fgets(strDest, n, stdin);

    if (pstrRet == NULL)
        return NULL;

    if (!strrchr(strDest, '\n'))
        // Exhaust the input buffer.
        do
        {
            fgets(strExBuff, sizeof(strExBuff), stdin);
        }while (!strrchr(strExBuff, '\n'));
    else
        // Replace '\n' with '\0'
        strDest[strrchr(strDest, '\n') - strDest] = '\0';

    return pstrRet;
}

//////////////////////////////////////////////////////////
//                                                      //
//        Main Function                                 //
//                                                      //
//////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    ActiveCommandX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//            ActiveCommandX Function                   //
//                                                      //
//////////////////////////////////////////////////////////

void ActiveCommandX(void)
{

    HRESULT    hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _ConnectionPtr  pConnection      = NULL;
    _CommandPtr    pCmd      = NULL;
    _RecordsetPtr  pRstAuthors    = NULL;

    //Definitions of other variables
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
        "Initial Catalog='pubs';Integrated Security='SSPI';");
    _bstr_t      strPrompt;
    _bstr_t      strName;
    CHAR strcharName[50];

    try
    {
        // Open connection.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));

        TESTHR(pRstAuthors.CreateInstance(__uuidof(Recordset)));

        TESTHR(pCmd.CreateInstance(__uuidof(Command)));

        printf ("ActiveCommandX Example\n\n");
        strPrompt = "Enter an author's name (e.g., Ringer): ";
        printf(strPrompt);
        mygets(strcharName, 50);
        char *tempStr = strtok(strcharName, " \t");
        strName = tempStr;

        pCmd->CommandText = "SELECT * FROM authors WHERE au_lname = ?";
        pCmd->Parameters->Append(pCmd->CreateParameter("LastName", adChar, adParamInput, 20, strName));

        pConnection->Open (strCnn, "", "", adConnectUnspecified);

        pCmd->PutActiveConnection(_variant_t((IDispatch*)pConnection));

        pRstAuthors = pCmd->Execute(NULL,NULL,adCmdText);

        ActiveCommandXprint(pRstAuthors);

    }    // End Try statement.
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        // Pass a connection pointer accessed from the Recordset.
        PrintProviderError(pConnection);
        PrintComError(e);
    }

    // Clean up objects before exit.
    if (pRstAuthors)
        if (pRstAuthors->State == adStateOpen)
            pRstAuthors->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

//////////////////////////////////////////////////////////
//                                                      //
//              ActiveCommandXprint Function            //
//                                                      //
//////////////////////////////////////////////////////////

void ActiveCommandXprint(_RecordsetPtr    pRst = NULL)
{
    // Varible Declaraion & initialization
    IADORecordBinding   *picRs  = NULL;  //Interface Pointer declared.
    CAuthorsRs autrs;           //C++ class object
    _bstr_t strName;

    //Open an IADORecordBinding interface pointer which
    //we'll use for Binding Recordset to a class
    TESTHR(pRst->QueryInterface(__uuidof(IADORecordBinding),(LPVOID*)&picRs));

    //Bind the Recordset to a C++ Class here
    TESTHR(picRs->BindToRecordset(&autrs));

    strName = ((_CommandPtr)pRst->GetActiveCommand())->GetParameters()->GetItem("LastName")->Value;
    printf("Command text = '%s'\n", (LPCSTR)((_CommandPtr)pRst->GetActiveCommand())->CommandText);
    printf("Parameter = '%s'\n", (LPCSTR)strName);

    if (pRst->BOF)
        printf("Name = '%s'not found.", (LPCSTR)strName);
    else
    {
        printf ("Name = '%s  %s' author ID = '%s'",
            autrs.lau_fnameStatus == adFldOK ? autrs.m_au_fname : "<NULL>",
            autrs.lau_lnameStatus == adFldOK ? autrs.m_au_lname : "<NULL>",
            autrs.lau_idStatus == adFldOK ? autrs.m_au_id : "<NULL>");
    }

    //Release IADORecordset Interface
    if (picRs)
        picRs->Release();

}

//////////////////////////////////////////////////////////
//                                                      //
//        PrintProviderError Function                   //
//                                                      //
//////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;
    long      nCount  = 0;
    long      i     = 0;

    if( (pConnection->Errors->Count) > 0)
    {
        nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s\n", pErr->Number, (LPCSTR)pErr->Description);
        }
    }
}

//////////////////////////////////////////////////////////
//                                                      //
//       PrintComError Function                         //
//                                                      //
//////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);

}
// EndActiveCommandCpp

ActiveCommandX.h
// BeginActiveCommandH
#include "icrsint.h"

// This Class extracts id, fname, lname from authors table.

class CAuthorsRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CAuthorsRs)

    // Column au_id is the 1st field in the recordset
    ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_au_id,
         sizeof(m_au_id), lau_idStatus, TRUE)

    // Column au_fname is the 2nd field in the recordset
    ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_au_fname,
         sizeof(m_au_fname), lau_fnameStatus, TRUE)

    // Column au_lname is the 3rd field in the recordset
    ADO_VARIABLE_LENGTH_ENTRY2(3, adVarChar, m_au_lname,
         sizeof(m_au_lname), lau_lnameStatus, TRUE)

END_ADO_BINDING()

public:

   char     m_au_id[21];
   ULONG    lau_idStatus;
   char     m_au_fname[41];
   ULONG    lau_fnameStatus;
   char     m_au_lname[41];
   ULONG    lau_lnameStatus;

};
// EndActiveCommandH

请参阅

ActiveCommand 属性 | Recordset 对象


ActiveConnection、CommandText、CommandTimeout、CommandType、Size 和 Direction 属性范例 (VC++)

本范例使用 ActiveConnection、CommandText、CommandTimeout、CommandType、Size 和 Direction 属性来执行存储过程。

// BeginActiveConnectionCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#define TESTHR(x) if FAILED(x) _com_issue_error(x)

#include <stdio.h>
#include <ole2.h>
#include "conio.h"
#include "ActiveConnectionX.h"

//Function declaration
void ActiveConnectionX(VOID);
void PrintProviderError(_ConnectionPtr pConnection);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    ActiveConnectionX();

    //Wait here for user to see the output..
    printf("\n\nPress any key to continue..");
    getch();

    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      ActiveConnectionX Function                       //
//                                                       //
///////////////////////////////////////////////////////////
VOID ActiveConnectionX(VOID)
{
    HRESULT hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _ConnectionPtr  pConnection      = NULL;
    _CommandPtr     pCmdByRoyalty  = NULL;
    _RecordsetPtr  pRstByRoyalty  = NULL;
    _RecordsetPtr  pRstAuthors   = NULL;
    _ParameterPtr    pPrmByRoyalty  = NULL;

    //Define Other variables
    IADORecordBinding   *picRs = NULL;  //Interface Pointer declared.(VC++ Extensions)  TCS(SPA)
    CEmployeeRs emprs;          //C++ class object  TCS(SPA)
    _bstr_t strAuthorId;
    int intRoyalty;
    VARIANT vtroyal ;

    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        //Define a command object for a stored procedure.

        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        hr = pConnection->Open(strCnn,"","",adConnectUnspecified);

        TESTHR(pCmdByRoyalty.CreateInstance(__uuidof(Command)));

        pCmdByRoyalty->ActiveConnection = pConnection;
        pCmdByRoyalty->CommandText = "byRoyalty";
        pCmdByRoyalty->CommandType = adCmdStoredProc;
        pCmdByRoyalty->CommandTimeout = 15;

        //Define stored procedure's input parameter.
        printf("Enter Royalty :  ");
        scanf("%d",&intRoyalty);

        //Assign Integer value
        vtroyal.vt = VT_I2;
        vtroyal.iVal  = intRoyalty;

        TESTHR(pPrmByRoyalty.CreateInstance(__uuidof(Parameter)));
        pPrmByRoyalty->Type = adInteger;
        pPrmByRoyalty->Size = 3;
        pPrmByRoyalty->Direction = adParamInput;
        pPrmByRoyalty->Value = vtroyal;
        pCmdByRoyalty->Parameters->Append(pPrmByRoyalty);

        //Create a recordset by executing a command.
        pRstByRoyalty = pCmdByRoyalty->Execute(NULL,NULL,adCmdStoredProc);

        //Open the authors table to get author names for display.

        TESTHR(pRstAuthors.CreateInstance(__uuidof(Recordset)));
        hr = pRstAuthors->Open("authors",strCnn,adOpenForwardOnly,adLockReadOnly,adCmdTable);

        //Open an IADORecordBinding interface pointer which we'll use for Binding Recordset to a class
        TESTHR(pRstAuthors->QueryInterface(__uuidof(IADORecordBinding),(LPVOID*)&picRs));

        //Bind the Recordset to a C++ Class here
        TESTHR(picRs->BindToRecordset(&emprs));

        //Print current data in the recordset ,adding author names from author table.
        printf("Authors With  %d  Percent Royalty",intRoyalty);

        while(!(pRstByRoyalty->EndOfFile))
        {
            strAuthorId = pRstByRoyalty->Fields->Item["au_id"]->Value;
            pRstAuthors->Filter = "au_id = '"+strAuthorId+"'";

            printf("\n\t%s, %s %s",emprs.lau_idStatus == adFldOK ? emprs.m_szau_id : "<NULL>",\
            emprs.lau_fnameStatus == adFldOK ? emprs.m_szau_fname : "<NULL>",\
                    emprs.lau_lnameStatus == adFldOK ? emprs.m_szau_lname : "<NULL>");

            pRstByRoyalty->MoveNext();
        }
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

         PrintProviderError(pConnection);
         printf("Source : %s \n Description : %s \n",(LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }

    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (pRstByRoyalty)
        if (pRstByRoyalty->State == adStateOpen)
            pRstByRoyalty->Close();
    if (pRstAuthors)
        if (pRstAuthors->State == adStateOpen)
            pRstAuthors->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

VOID PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;
    long      nCount  = 0;
    long      i     = 0;

    if( (pConnection->Errors->Count) > 0)
    {
        nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s", pErr->Number,(LPCSTR)pErr->Description);
        }
    }
}

// EndActiveConnectionCpp

ActiveConnectionX.h

// BeginActiveConnectionH
#include "icrsint.h"

//This Class extracts  fname,lastname

class CEmployeeRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CEmployeeRs)

    //Column au_id is the 1st field in the recordset
    ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_szau_id,
         sizeof(m_szau_id), lau_idStatus, TRUE)

    ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_szau_lname,
         sizeof(m_szau_lname), lau_lnameStatus, TRUE)

    ADO_VARIABLE_LENGTH_ENTRY2(3, adVarChar, m_szau_fname,
         sizeof(m_szau_fname), lau_fnameStatus, TRUE)

END_ADO_BINDING()

public:

    CHAR m_szau_id[20];
    ULONG lau_idStatus;

    CHAR m_szau_fname[40];
    ULONG lau_fnameStatus;

    CHAR   m_szau_lname[40];
    ULONG  lau_lnameStatus;

};
// EndActiveConnectionH

请参阅

ActiveConnection 属性 | CommandText 属性 | CommandTimeout 属性 | CommandType 属性 | Direction 属性 | Size 属性


ActualSize 和 DefinedSize 属性范例 (VC++)

本范例使用 ActualSize 和 DefinedSize 属性显示字段的定义大小和实际大小。

// BeginActualSizeCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include "conio.h"

//Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void ActualSizeX(VOID);
void PrintProviderError(_ConnectionPtr pConnection);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;
    ActualSizeX();
    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      ActualSizeX Function                             //
//                                                       //
///////////////////////////////////////////////////////////
VOID ActualSizeX(VOID)
{
    HRESULT hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr pRstStores = NULL;

    //Define Other variables
    _bstr_t strMessage;
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
        "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        //Open a recordset for the stores table.
        TESTHR(pRstStores.CreateInstance(__uuidof(Recordset)));

        //You have to explicitly pass the Cursor type and LockType
        //to the Recordset here.
        hr = pRstStores->Open("stores",
                strCnn,adOpenForwardOnly,adLockReadOnly,adCmdTable);

        //Loop through the recordset displaying the contents
        //of the stor_name field, the field's defined size,
        //and its actual size.

        pRstStores->MoveFirst();

        while(!(pRstStores->EndOfFile))
        {
            strMessage = "Store Name: ";
            strMessage += (_bstr_t)pRstStores->Fields->
                             Item["stor_name"]->Value + "\n";
            strMessage += "Defined Size: ";
            strMessage += (_bstr_t)pRstStores->Fields->
                             Item["stor_name"]->DefinedSize + "\n";
            strMessage += "Actual Size: ";
            strMessage += (_bstr_t) pRstStores->Fields->
                             Item["stor_name"]->ActualSize + "\n";

            printf("%s\n",(LPCSTR)strMessage);
            printf("Press any key to continue...");
            getch();
            //Clear the screen for the next display
            system("cls");
            pRstStores->MoveNext();
        }
    }
    catch(_com_error &e)
    {
        _variant_t vtConnect = pRstStores->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                printf("Error:\n");
                printf("Code = %08lx\n", e.Error());
                printf("Message = %s\n", e.ErrorMessage());
                printf("Source = %s\n", (LPCSTR) e.Source());
                printf("Description = %s\n", (LPCSTR) e.Description());
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    if (pRstStores)
        if (pRstStores->State == adStateOpen)
            pRstStores->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

VOID PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;
    long        nCount    = 0;
    long        i     = 0;

    if( (pConnection->Errors->Count) > 0)
    {
        nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,(LPCSTR ) pErr->Description);
        }
    }
}
// EndActualSizeCpp

请参阅

ActualSize 属性 | DefinedSize 属性


AddNew 方法范例 (VC++)

本范例使用 AddNew 方法来创建具有指定名称的新记录。

// Note: When adding the record. You need to get the data from the user
// The employee id must be formatted as first,middle and last initial,
// five numbers,then M or F to signify the gender.For example,the
// employee id for Bill A. Sorensen would be "BAS55555M".

// BeginAddNewCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include "conio.h"
#include "AddNewX.h"

//Function declaration
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void AddNewX(VOID);
void PrintProviderError(_ConnectionPtr pConnection);
inline int myscanf(char* strDest, int n)
{
    char strExBuff[10];
    char* pstrRet = fgets(strDest, n, stdin);

    if (pstrRet == NULL)
        return 0;

    if (!strrchr(strDest, '\n'))
        // Exhaust the input buffer.
        do
        {
            fgets(strExBuff, sizeof(strExBuff), stdin);
        }while (!strrchr(strExBuff, '\n'));
    else
        // Replace '\n' with '\0'
        strDest[strrchr(strDest, '\n') - strDest] = '\0';

    return strlen(strDest);
}

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////
void main()
{
    HRESULT  hr = S_OK;

    if(FAILED(::CoInitialize(NULL)))
        return;

    if (SUCCEEDED(hr))
    {
         AddNewX();

        //Wait here for the user to see the output
        printf("Press any key to continue...");
        getch();

        ::CoUninitialize();
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      AddNewX Function                                 //
//                                                       //
///////////////////////////////////////////////////////////
VOID AddNewX(VOID)
{

    // Define ADO object pointers.
    // Initialize pointers on define.
    _RecordsetPtr pRstEmployees = NULL;
    _ConnectionPtr pConnection  = NULL;

    //Define Other variables
    IADORecordBinding *picRs = NULL;  //Interface Pointer declared.(VC++ Extensions)
    CEmployeeRs emprs;    //C++ class object

    HRESULT hr = S_OK;

                            //Replace Data Source value with your server name.
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
        "Initial Catalog='pubs';Integrated Security='SSPI';");
    _bstr_t strId;
    _bstr_t strMessage;

    try
    {
        //Open a connection
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        pConnection->Open(strCnn,"","",adConnectUnspecified);

        //Open employee table
        TESTHR(pRstEmployees.CreateInstance(__uuidof(Recordset)));

        //You have to explicitly pass the Cursor type and LockType to the Recordset here
        pRstEmployees->Open("employee",_variant_t((IDispatch *) pConnection, true),
            adOpenKeyset,adLockOptimistic,adCmdTable);

        //Open an IADORecordBinding interface pointer which we'll use for Binding
        //Recordset to a class
        TESTHR(pRstEmployees->QueryInterface(__uuidof(IADORecordBinding),(LPVOID*)&picRs));

        //Bind the Recordset to a C++ Class here
        TESTHR(picRs->BindToRecordset(&emprs));

        // Get data from the user.The employee id must be formatted as
        // first,middle and last initial,five numbers,then M or F to
        // signify the gender.For example,the employee id for
        // Bill A. Sorensen would be "BAS55555M".

        printf("Enter Employee Id: ");
        myscanf(emprs.m_sz_empid, sizeof(emprs.m_sz_empid));
        strId = emprs.m_sz_empid;
        printf("Enter First Name: ");
        myscanf(emprs.m_sz_fname, sizeof(emprs.m_sz_fname));
        printf("Enter Last Name:");
        myscanf(emprs.m_sz_lname, sizeof(emprs.m_sz_lname));

        //Proceed if the user actually entered some thing
        //for the id, the first and the last name.

        if(strcmp(emprs.m_sz_empid,"")  && strcmp(emprs.m_sz_fname,"") &&
            strcmp(emprs.m_sz_lname,""))
        {
            //This adds a new record to the table
            //if (FAILED(hr = picRs->AddNew(&emprs)))
            //_com_issue_error(hr);
            TESTHR(picRs->AddNew(&emprs));

            //Show the newly added data
            printf("New Record: %s  %s  %s \n",\
            emprs.lemp_empidStatus == adFldOK ? emprs.m_sz_empid : "<NULL>",\
            emprs.lemp_fnameStatus == adFldOK ? emprs.m_sz_fname : "<NULL>",\
            emprs.lemp_lnameStatus == adFldOK ? emprs.m_sz_lname : "<NULL>");
        }
        else
            printf("Please enter an employee id, first name and last name.\n");

        //Delete the new record because this is a demonstration.
        pConnection->Execute("DELETE FROM EMPLOYEE WHERE emp_id = '"+strId+"'",
            NULL,adCmdText);
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _variant_t vtConnect = pRstEmployees->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                printf("Error:\n");
                printf("Code = %08lx\n", e.Error());
                printf("Message = %s\n", e.ErrorMessage());
                printf("Source = %s\n", (LPCSTR) e.Source());
                printf("Description = %s\n", (LPCSTR) e.Description());
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }

    }

    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (pRstEmployees)
        if (pRstEmployees->State == adStateOpen)
            pRstEmployees->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

VOID PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr  pErr = NULL;
    long      nCount = 0;
    long      i = 0;

    if( (pConnection->Errors->Count) > 0)
    {
        nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\n\t Error number: %x\t%s", pErr->Number, (LPCSTR)pErr->Description);
        }
    }
}
// EndAddNewCpp

AddNewX.h

// BeginAddNewH
#include "icrsint.h"

//This Class extracts empid, fname and lastname

class CEmployeeRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CEmployeeRs)

    //Column empid is the 1st field in the recordset

    ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_sz_empid,
         sizeof(m_sz_empid), lemp_empidStatus, TRUE)

    ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_sz_fname,
         sizeof(m_sz_fname), lemp_fnameStatus, TRUE)

    ADO_VARIABLE_LENGTH_ENTRY2(4, adVarChar, m_sz_lname,
         sizeof(m_sz_lname), lemp_lnameStatus, TRUE)

END_ADO_BINDING()

public:

   CHAR  m_sz_empid[10];
   ULONG lemp_empidStatus;
   CHAR   m_sz_fname[40];
   ULONG  lemp_fnameStatus;
   CHAR   m_sz_lname[41];
   ULONG  lemp_lnameStatus;

};
// EndAddNewH

请参阅

AddNew 方法 | Recordset 对象


Append 和 CreateParameter 方法范例 (VC++)

本范例使用 Append 和 CreateParameter 方法执行具有输入参数的存储过程。

// BeginAppendCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include "conio.h"
#include "AppendX.h"

//Function declaration
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void AppendX(VOID);
void PrintProviderError(_ConnectionPtr pConnection);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////
void main()
{
    HRESULT  hr = S_OK;

    if(FAILED(::CoInitialize(NULL)))
        return;

    AppendX();

    //Wait here for the user to see the output.
    printf("\n\nPress any key to continue...");
    getch();
    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      AppendX Function                                 //
//                                                       //
///////////////////////////////////////////////////////////
VOID  AppendX(VOID)
{

    HRESULT hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr pRstByRoyalty = NULL;
    _RecordsetPtr pRstAuthors = NULL;
    _CommandPtr pcmdByRoyalty = NULL;
    _ParameterPtr pprmByRoyalty = NULL;
    _ConnectionPtr pConnection = NULL;

    //Define Other variables
    IADORecordBinding *picRs = NULL;    //Interface Pointer declared.(VC++ Extensions)
    CEmployeeRs emprs;                  //C++ class object

    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
        "Initial Catalog='pubs';Integrated Security='SSPI';");

    _bstr_t strMessage, strAuthorID;

    int intRoyalty;
    VARIANT vtRoyalty;

    try
    {
        //Open a Connection.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        hr = pConnection->Open(strCnn,"","",adConnectUnspecified);
        pConnection->CursorLocation = adUseClient;

        //Open Command Object with one Parameter
        TESTHR(pcmdByRoyalty.CreateInstance(__uuidof(Command)));
        pcmdByRoyalty->CommandText = "byroyalty";
        pcmdByRoyalty->CommandType = adCmdStoredProc;

        //Get parameter value and append parameter
        printf("Enter Royalty: ");
        scanf("%d",&intRoyalty);

        //Define Integer/variant.
        vtRoyalty.vt = VT_I2;
        vtRoyalty.iVal = intRoyalty;
        pprmByRoyalty = pcmdByRoyalty->CreateParameter("percentage",adInteger,adParamInput,sizeof(int),vtRoyalty);
        pcmdByRoyalty->Parameters->Append(pprmByRoyalty);

        pprmByRoyalty->Value  = vtRoyalty;

        //Create Recordset by executing the command
        pcmdByRoyalty->ActiveConnection = pConnection;
        pRstByRoyalty = pcmdByRoyalty->Execute(NULL,NULL,adCmdStoredProc);

        //Open the authors table to get author names for display
        TESTHR(pRstAuthors.CreateInstance(__uuidof(Recordset)));

        //You have to explicitly pass the default Cursor type and LockType to the Recordset here
        hr = pRstAuthors->Open("authors",_variant_t((IDispatch*)pConnection,true),adOpenForwardOnly,adLockReadOnly,adCmdTable);

        //Open an IADORecordBinding interface pointer which we'll use for Binding Recordset to a class
        TESTHR(pRstAuthors->QueryInterface(__uuidof(IADORecordBinding),(LPVOID*)&picRs));

        //Bind the Recordset to a C++ Class here
        TESTHR(picRs->BindToRecordset(&emprs));

        //Print current data in the recordset, adding
        //author names from author table.
        printf("Authors with %d percent royalty ",intRoyalty);

        while(!(pRstByRoyalty->EndOfFile))
        {
            strAuthorID = pRstByRoyalty->Fields->Item["au_id"]->Value;
            pRstAuthors->Filter = "au_id = '"+strAuthorID+"'";

            printf("\n"  "%s, %s  %s",emprs.lau_idStatus == adFldOK ? emprs.m_szau_id : "<NULL>",\
                    emprs.lau_fnameStatus == adFldOK ? emprs.m_szau_fname : "<NULL>",\
                    emprs.lau_lnameStatus == adFldOK ? emprs.m_szau_lname : "<NULL>");

            pRstByRoyalty->MoveNext();
        }
    }
    catch(_com_error &e)
    {
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        PrintProviderError(pConnection);

        printf("\n Source : %s \n Description : %s \n",(LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }

    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (pRstByRoyalty)
        if (pRstByRoyalty->State == adStateOpen)
            pRstByRoyalty->Close();
    if (pRstAuthors)
        if (pRstAuthors->State == adStateOpen)
            pRstAuthors->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

VOID PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr = NULL;
    long        nCount = 0;
    long        i = 0;

    if( (pConnection->Errors->Count) > 0)
    {
        nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\n Error Description: %s\n", pErr->Number,(LPCSTR) pErr->Description);
        }
    }
}
// EndAppendCpp

AppendX.h

// BeginAppendH
#include "icrsint.h"

//This Class extracts only author id,fname,lastname

class CEmployeeRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CEmployeeRs)

    //Column au_id is the 1st field in the recordset

    ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_szau_id,
         sizeof(m_szau_id), lau_idStatus, TRUE)

    ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_szau_lname,
         sizeof(m_szau_lname), lau_lnameStatus, TRUE)

    ADO_VARIABLE_LENGTH_ENTRY2(3, adVarChar, m_szau_fname,
         sizeof(m_szau_fname), lau_fnameStatus, TRUE)

END_ADO_BINDING()

public:

   CHAR m_szau_id[20];
   ULONG lau_idStatus;

   CHAR m_szau_fname[40];
   ULONG lau_fnameStatus;

   CHAR   m_szau_lname[40];
   ULONG  lau_lnameStatus;

};
// EndAppendH

请参阅

Append 方法 | CreateParameter 方法


AppendChunk 和 GetChunk 方法范例 (VC++)

本范例使用 AppendChunk 和 GetChunk 方法用其他记录中的数据填充图像字段。

// BeginAppendChunkCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#define ChunkSize    100

#include <ole2.h>
#include <stdio.h>
#include "conio.h"
#include "malloc.h"
#include "AppendChunkX.h"

//Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void AppendChunkX(VOID);
void PrintProviderError(_ConnectionPtr pConnection);
inline int myscanf(char* strDest, int n)
{
    char strExBuff[10];
    char* pstrRet = fgets(strDest, n, stdin);

    if (pstrRet == NULL)
        return 0;

    if (!strrchr(strDest, '\n'))
        // Exhaust the input buffer.
        do
        {
            fgets(strExBuff, sizeof(strExBuff), stdin);
        }while (!strrchr(strExBuff, '\n'));
    else
        // Replace '\n' with '\0'
        strDest[strrchr(strDest, '\n') - strDest] = '\0';

    return strlen(strDest);
}
inline char* mygets(char* strDest, int n)
{
    char strExBuff[10];
    char* pstrRet = fgets(strDest, n, stdin);

    if (pstrRet == NULL)
        return NULL;

    if (!strrchr(strDest, '\n'))
        // Exhaust the input buffer.
        do
        {
            fgets(strExBuff, sizeof(strExBuff), stdin);
        }while (!strrchr(strExBuff, '\n'));
    else
        // Replace '\n' with '\0'
        strDest[strrchr(strDest, '\n') - strDest] = '\0';

    return pstrRet;
}

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////
void main()
{
    HRESULT  hr = S_OK;

    if(FAILED(::CoInitialize(NULL)))
        return;

    AppendChunkX();

    //Wait here for the user to see the output
    printf("\n\nPress any key to continue..");
    getch();
    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      AppendChunkX Function                            //
//                                                       //
///////////////////////////////////////////////////////////
VOID  AppendChunkX(VOID)
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr pRstPubInfo = NULL;
    _ConnectionPtr pConnection = NULL;

    //Define other variables
    IADORecordBinding   *picRs = NULL;  //Interface Pointer declared.(VC++ Extensions)
    CPubInfoRs pubrs;          //C++ class object

    HRESULT hr = S_OK;
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
        "Initial Catalog='pubs';Integrated Security='SSPI';");

    _bstr_t strMessage,strPubID,strPRInfo;
    _variant_t varChunk;
    long lngOffSet,lngLogoSize;
    char pubId[50];
    lngOffSet = 0;

    UCHAR chData;
    SAFEARRAY FAR *psa;
    SAFEARRAYBOUND rgsabound[1];
    rgsabound[0].lLbound = 0;
    rgsabound[0].cElements = ChunkSize;

    try
    {
        //Open a Connection.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        hr = pConnection->Open(strCnn,"","",adConnectUnspecified);

        TESTHR(hr= pRstPubInfo.CreateInstance(__uuidof(Recordset)));

        pRstPubInfo->CursorType = adOpenKeyset;
        pRstPubInfo->LockType = adLockOptimistic;

        hr = pRstPubInfo->Open("pub_info",
            _variant_t((IDispatch*)pConnection,true),
            adOpenKeyset,adLockOptimistic,adCmdTable);

        //Open an IADORecordBinding interface pointer which we'll use
        //for Binding Recordset to a class
        TESTHR(pRstPubInfo->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        //Bind the Recordset to a C++ Class here
        TESTHR(picRs->BindToRecordset(&pubrs));

        //Display the available logos here
        strMessage = "Available logos are: " + (_bstr_t)"\n\n";
        printf(strMessage);
        int Counter = 0;
        while(!(pRstPubInfo->EndOfFile))
        {
            printf("\n%s",pubrs.m_sz_pubid);
            printf("\n%s",strtok(pubrs.m_sz_prinfo,","));

            //Display 5 records at a time and wait for user to continue..
            if (++Counter >= 5)
            {
                Counter = 0;
                printf("\nPress any key to continue...");
                getch();
            }
            pRstPubInfo->MoveNext();
        }

        //Prompt For a Logo to Copy
        printf("\nEnter the ID of a logo to copy: ");
        myscanf(pubId, sizeof(pubId));
        strPubID = pubId;

        //Copy the logo to a variable in chunks

        pRstPubInfo->Filter = "pub_id = '"  + strPubID + "'";
        lngLogoSize = pRstPubInfo->Fields->Item["logo"]->ActualSize;

        //Create a safe array to store the array of BYTES
        rgsabound[0].cElements = lngLogoSize;
        psa = SafeArrayCreate(VT_UI1,1,rgsabound);

        long index1 = 0;
        while(lngOffSet < lngLogoSize)
        {
            varChunk = pRstPubInfo->Fields->
                        Item["logo"]->GetChunk(ChunkSize);

            //Copy the data only upto the Actual Size of Field.
            for(long index=0;index<=(ChunkSize-1);index++)
            {
                hr= SafeArrayGetElement(varChunk.parray,&index,&chData);
                if(SUCCEEDED(hr))
                {
                    //Take BYTE by BYTE and advance Memory Location
                    hr = SafeArrayPutElement(psa,&index1,&chData);
                    index1++;
                }
                else
                    break;
            }
            lngOffSet = lngOffSet + ChunkSize;
        }
        lngOffSet = 0;

        printf("Enter a new Pub Id: ");
        myscanf(pubrs.m_sz_pubid, sizeof(pubrs.m_sz_pubid));
        strPubID = pubrs.m_sz_pubid;
        printf("Enter descriptive text: " );
        mygets(pubrs.m_sz_prinfo, sizeof(pubrs.m_sz_prinfo));

        pRstPubInfo->AddNew();
        pRstPubInfo->Fields->GetItem("pub_id")->PutValue(strPubID);
        pRstPubInfo->Fields->GetItem("pr_info")->
            PutValue(pubrs.m_sz_prinfo);

        //Assign the Safe array  to a variant.
        varChunk.vt = VT_ARRAY|VT_UI1;
        varChunk.parray = psa;
        hr = pRstPubInfo->Fields->GetItem("logo")->
                AppendChunk(varChunk);

        //Update the table
        pRstPubInfo->Update();

        lngLogoSize = pRstPubInfo->Fields->Item["logo"]->ActualSize;

        //Show the newly added record.
        printf("New Record : %s\n Description : %s\n Logo Size : %s",
            pubrs.m_sz_pubid,
            pubrs.m_sz_prinfo,(LPCSTR)(_bstr_t)pRstPubInfo->Fields->
            Item["logo"]->ActualSize);

        //Delete new record because this is demonstration.
        pConnection->Execute("DELETE FROM PUB_INFO WHERE pub_id = '"
                        + strPubID +"'",NULL,adCmdText);
    }
    catch(_com_error &e)
    {
         // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        PrintProviderError(pConnection);
        printf("Source : %s \n Description : %s\n",(LPCSTR)bstrSource,
            (LPCSTR)bstrDescription);
    }

    // Clean up objects before exit.
    if (pRstPubInfo)
        if (pRstPubInfo->State == adStateOpen)
            pRstPubInfo->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

VOID PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr = NULL;
    long        nCount = 0;
    long        i = 0;

    if( (pConnection->Errors->Count) > 0)
    {
        nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,(LPCSTR) pErr->Description);
        }
    }
}

// EndAppendChunkCpp

AppendChunkX.h

// BeginAppendChunkH
#include "icrsint.h"

//This Class extracts pubid,prinfo.

class CPubInfoRs : public CADORecordBinding
{
    BEGIN_ADO_BINDING(CPubInfoRs)

        ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_sz_pubid,
         sizeof(m_sz_pubid), l_pubid, TRUE)

        ADO_VARIABLE_LENGTH_ENTRY2(3, adVarChar, m_sz_prinfo,
         sizeof(m_sz_prinfo), l_prinfo, TRUE)

    END_ADO_BINDING()

public:
   CHAR   m_sz_pubid[10];
   ULONG  l_pubid;
   CHAR   m_sz_prinfo[200];
   ULONG l_prinfo;
};
// EndAppendChunkH

请参阅

AppendChunk 方法 | Field 对象 | GetChunk 方法


Attributes 和 Name 属性范例 (VC++)

本范例显示 Connection、Field 和 Property 对象的 Attributes 属性的值。该范例使用 Name 属性显示每个 Field 和 Property 对象的名称。

// BeginAttributesCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void AttributesX();
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    AttributesX();

    //Wait here for user to see the output..
    printf("\nPress any key to continue...");
    getch();

    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      AttributesX Function                             //
//                                                       //
///////////////////////////////////////////////////////////

void AttributesX()
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace
    _RecordsetPtr pRstEmployee  = NULL;
    _ConnectionPtr pConnection = NULL;
    FieldsPtr fldLoop = NULL;
    PropertiesPtr proLoop = NULL;

    //Define Other Variables
    HRESULT  hr = S_OK;
    _variant_t Index;
    Index.vt = VT_I2;
    int j=0;
    //Open a recordset using a Client Cursor
    //For the Employee Table
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
    "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        // open connection and record set
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        pConnection->Open(strCnn,"","",adConnectUnspecified);

        TESTHR(pRstEmployee.CreateInstance(__uuidof(Recordset)));
        pRstEmployee->Open("Employee", _variant_t((IDispatch *)pConnection,true), adOpenForwardOnly,
            adLockReadOnly, adCmdTable);

        // Display the attributes of Connection.
        printf("Connection attributes: %d \n", pConnection->Attributes);

        // Display the attribute of the employee table's
        //fields
        printf("\nFields attributes:\n");
        fldLoop = pRstEmployee->GetFields();

        for (int i = 0; i < (int)fldLoop->GetCount(); i++)
        {
            Index.iVal=i;
            printf ("   %s = %d \n",(LPSTR)fldLoop->GetItem(Index)->GetName(),
                (int)fldLoop->GetItem(Index)->GetAttributes());
        }

        // Display Fields of the Employee table which are NULLBALE
        printf("\nNULLABLE Fields :");

        for (int i1 = 0; i1 < (int)fldLoop->GetCount(); i1++)
        {
            Index.iVal = i1;

            if (fldLoop->GetItem(Index)->GetAttributes()  & adFldIsNullable)
                {
                    printf ("%s  \n", (LPSTR)fldLoop->GetItem(Index)->GetName());
                }
        }

        // Display the attributes of the Employee tables's
        // properties
        printf("\nProperty attributes:\n");
        proLoop = pRstEmployee->GetProperties();

        for (int i2 = 0; i2 < (int)proLoop->GetCount(); i2++)
        {
            j= j+1;
            Index.iVal=i2;
            printf (" %s = %d \n", (LPSTR)(_bstr_t)proLoop->GetItem(Index)->GetName()
            ,(int)proLoop->GetItem(Index)->GetAttributes());

            if (((j % 23) == 0) || ( i2==6))
            {
                printf("\nPress any key to continue...");
                getch();

                //Clear the screen for the next display
                system("cls");
                j=0;
            }

        }
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.

        PrintProviderError(pConnection);
        PrintComError(e);
    }

    // Clean up objects before exit.
    if (pRstEmployee)
        if (pRstEmployee->State == adStateOpen)
            pRstEmployee->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.

    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;
    long      nCount  = 0;
    long       i    = 0;

    if( (pConnection->Errors->Count) > 0)
    {
        nCount = pConnection->Errors->Count;

        // Collection ranges from 0 to nCount -1.
        for(i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", (LPCSTR) pErr->Number, (LPCSTR) pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

VOID PrintComError(_com_error &e)
{
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

    // Print Com errors.
    printf("\nError\n");
    printf("Code = %08lx\n", e.Error());
    printf("Code meaning = %s\n", e.ErrorMessage());
    printf("Source = %s\n", (LPCSTR) bstrSource);
    printf("Description = %s\n", (LPCSTR) bstrDescription);
}
// EndAttributesCpp

AttributesX.h

// BeginAttributesH
#include "icrsint.h"

//This class extracts LastName, FirstName, FaxPhone from Employees table

class CEmployeeRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CEmployeeRs)

        // Column LastName is the 2nd field in the table
        ADO_VARIABLE_LENGTH_ENTRY2(2,adVarChar,m_szemp_LastName,
            sizeof(m_szemp_LastName),lemp_LastNameStatus,TRUE)

        // Column FirstName is the 17th field in the table
        ADO_VARIABLE_LENGTH_ENTRY2(17,adVarChar,m_szemp_FirstName,
            sizeof(m_szemp_FirstName),lemp_FirstNameStatus,TRUE)

        // Column FaxPhone is the 18th field in the table
        ADO_VARIABLE_LENGTH_ENTRY2(18,adVarChar,m_szemp_Faxphone,
            sizeof(m_szemp_Faxphone),lemp_FaxphoneStatus,TRUE)

END_ADO_BINDING()

public:
    CHAR  m_szemp_LastName[21];
    ULONG lemp_LastNameStatus;
    CHAR  m_szemp_FirstName[11];
    ULONG lemp_FirstNameStatus;
    CHAR  m_szemp_Faxphone[25];
    ULONG lemp_FaxphoneStatus;
};

// EndAttributesH

请参阅

Attributes 属性 | Connection 对象 | Field 对象 | Name 属性 | Property 对象


BeginTrans、CommitTrans 和 RollbackTrans 方法范例 (VC++)

本范例更改数据库的 Titles 表中所有心理学书籍的类型。在 BeginTrans 方法启动事务来隔离 Titles 表的所有更改后，使用 CommitTrans 方法保存更改。可以使用 RollbackTrans 方法撤消用 Update 方法保存的更改。

// BeginBeginTransCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <stdio.h>
#include <ole2.h>
#include <conio.h>
#include <assert.h>
#include <malloc.h>
#include "BeginTransX.h"

inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void BeginTransX(void);
void PrintProviderError(_ConnectionPtr pConnection);

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    BeginTransX();

    //Wait here for user to see the output.
    printf("\nPress any key to continue...");
    getch();

    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      BeginTransX Function                             //
//                                                       //
///////////////////////////////////////////////////////////

void BeginTransX()
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr rstTitles = NULL;
    _ConnectionPtr pConnection = NULL;

    //Define Other Variables
    HRESULT hr = S_OK;
    IADORecordBinding   *picRs = NULL;  //Interface Pointer declared...
    CTitlesRs titlrs;
    _bstr_t strTitle;
    _bstr_t strMessage;
    LPSTR p_TempStr = NULL;
    char chKey;
    int i = 0;

    try
    {
        // open connection.
        _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));

        TESTHR(pConnection->Open(strCnn,"","",adConnectUnspecified));

        rstTitles.CreateInstance(__uuidof(Recordset));

        rstTitles->CursorType = adOpenDynamic;
        rstTitles->LockType = adLockPessimistic;

        // open Titles table
        TESTHR(rstTitles->Open("titles",
            _variant_t((IDispatch*)pConnection,true),
            adOpenDynamic, adLockPessimistic,adCmdTable));

        rstTitles->MoveFirst();
        pConnection->BeginTrans();

        //Open an IADORecordBinding interface pointer which
        //we'll use for Binding Recordset to a class
        TESTHR(rstTitles->QueryInterface(
            __uuidof(IADORecordBinding), (LPVOID*)&picRs));

        //Bind the Recordset to a C++ Class here
        TESTHR(picRs->BindToRecordset(&titlrs));

        // Loop through recordset and ask user if he wants
        // to change the type for a specified title.
        // Allocate memory to p_TempStr string pointer.
        p_TempStr = (LPSTR) malloc(sizeof(titlrs.m_szT_type));

        // Check for null string.
        assert(p_TempStr != NULL);
        while (VARIANT_FALSE == rstTitles->EndOfFile)
        {
            // Set the final character of the destination string to NULL.
            p_TempStr[sizeof(titlrs.m_szT_type)-1] = '\0';
            // The source string will get truncated if its length is
            // longer than the length of the destination string minus one.
            strncpy(p_TempStr,strtok(titlrs.m_szT_type," "),sizeof(titlrs.m_szT_type)-1);

            // Compare type with psychology
            if (!strcmp(p_TempStr,"psychology"))
            {
                strTitle = titlrs.m_szT_title;
                strMessage = "Title: " + strTitle +
                        "\n Change type to Self help?(y/n)";

                // Change the title for specified employee
                printf("%s\n",(LPCSTR)strMessage);
                do
                {
                    chKey = getch();
                }while(chKey != 'y' && chKey !='n');
                if(chKey == 'y')
                {
                    // Set the final character of the destination string to NULL.
                    titlrs.m_szT_type[sizeof(titlrs.m_szT_type)-1] = '\0';
                    // Copy "self_help" title field.
                    // The source string will get truncated if its length is
                    // longer than the length of the destination string minus one.
                    strncpy(titlrs.m_szT_type,"self_help", sizeof(titlrs.m_szT_type)-1);
                    picRs->Update(&titlrs);
                }
            }
            rstTitles->MoveNext();
        }
        // Ask if the User wants to commit to all the
        // changes made above
        printf("\n\n Save all changes(y/n)?");
        do
        {
            chKey = getch();
        }while(chKey != 'y' && chKey !='n');

        if(chKey == 'y')

            // Save the changes to the title table
            pConnection->CommitTrans();
        else
            // Unsave the changes to the title table
            pConnection->RollbackTrans();

        // Print current data in recordset.
        rstTitles->Requery(0);

        // Move to the first record of the title table
        rstTitles->MoveFirst();
        printf("\n\nPress any key to continue...");
        getch();

        // Clear the screen for the next display
        //system("cls");

        // Open IADORecordBinding interface pointer again
        // for binding Recordset to a class.
        TESTHR(rstTitles->QueryInterface(
            __uuidof(IADORecordBinding),
            (LPVOID*)&picRs));

        // Rebind the Recordset to a C++ Class.
        TESTHR(picRs->BindToRecordset(&titlrs));

        while (!rstTitles->EndOfFile)
        {
            i= i+1;
            if (i % 23 == 0)
            {
                printf("\nPress any key to continue...");
                getch();

                //Clear the screen for the next display
                //system("cls");
            }
            printf("%s -  %s\n",titlrs.m_szT_title,titlrs.m_szT_type);
            rstTitles->MoveNext();
        }
        // Restore original data becasue this is a demonstration.
        rstTitles->MoveFirst();

        while (VARIANT_FALSE == rstTitles->EndOfFile)
        {
            // Set the final character of the destination string to NULL.
            p_TempStr[sizeof(titlrs.m_szT_type)-1] = '\0';
            // The source string will get truncated if its length is
            // longer than the length of the destination string minus one.
            strncpy(p_TempStr,titlrs.m_szT_type,sizeof(titlrs.m_szT_type)-1);
            p_TempStr = strtok(p_TempStr," ");

            if (!strcmp(p_TempStr,"self_help"))
            {
                // Set the final character of the destination string to NULL.
                titlrs.m_szT_type[sizeof(titlrs.m_szT_type)-1] = '\0';
                // The source string will get truncated if its length is
                // longer than the length of the destination string minus one.
                strncpy(titlrs.m_szT_type,"psychology",sizeof(titlrs.m_szT_type)-1);
                picRs->Update(&titlrs);
            }
            rstTitles->MoveNext();
        }
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        PrintProviderError(pConnection);

        printf("Source : %s\n",(LPCSTR)bstrSource);
        printf("Description : %s\n",(LPCSTR)bstrDescription);
    }

    // Deallocate the memory
    if (p_TempStr)
        free(p_TempStr);
    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (rstTitles)
        if (rstTitles->State == adStateOpen)
            rstTitles->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
};

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr  pErr    = NULL;
    long      nCount  = 0;
    long      i       = 0;

    if( (pConnection->Errors->Count) > 0)
    {
        nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,(LPCSTR) pErr->Description);
        }
    }
}
// EndBeginTransCpp

BeginTransX.h

// BeginBeginTransH
#include "icrsint.h"

//This Class extracts only title and type
class CTitlesRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CTitlesRs)
    //Column title is the 2nd field in the recordset
    ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_szT_title,
         sizeof(m_szT_title), lT_titleStatus, FALSE)

    //Column type is the 3rd field in the recordset
    ADO_VARIABLE_LENGTH_ENTRY2(3, adVarChar, m_szT_type,
         sizeof(m_szT_type), lT_typeStatus, TRUE)
END_ADO_BINDING()

public:
   CHAR   m_szT_title[150];
   ULONG  lT_titleStatus;
   CHAR   m_szT_type[40];
   ULONG  lT_typeStatus;
};
// EndBeginTransH

请参阅

BeginTrans、CommitTrans 和 RollbackTrans 方法 | Update 方法


BOF、EOF 和 Bookmark 属性范例 (VC++)

本范例的第一个函数使用 BOF 和 EOF 属性，在用户试图移过 Recordset 的第一个或最后一个记录时显示一条消息。用户可以使用 Bookmark 属性对 Recordset 中的记录进行标记，稍后再返回该记录。

第二个函数使用 Bookmark 属性将 Recordset 中每隔一个记录的 Bookmark 放置在数组中，然后使用该数组过滤该 Recordset。

// BeginBOFCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>
#include "BofEofBookmark.h"

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void BOFX(void);
void BookmarkX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////////////////
//                                                       //
//      BOFX Function                                    //
//                                                       //
///////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    BOFX();

    //Clear the screen for the next display
    system("cls");

    BookmarkX();

    printf("Press any key to continue...");
    getch();

    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      BOFX Function                                    //
//                                                       //
///////////////////////////////////////////////////////////

void BOFX(void)
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace
    _RecordsetPtr rstPublishers = NULL;

    //Define Other Variables
    HRESULT hr = S_OK;
    IADORecordBinding  *picRs = NULL;    //Interface Pointer declared.
    CPublishers Publs;

    bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
        "Initial Catalog='pubs';Integrated Security='SSPI';");
    _bstr_t strMessage;
    _variant_t VarBookmark;
    int intCommand = 0;
    _variant_t TempPublisher;

    try
    {
        // Open recordset with data from Publishers table.
        TESTHR(rstPublishers.CreateInstance(__uuidof(Recordset)));
        rstPublishers->CursorType = adOpenStatic;

        // Use client cursor to enable absolutePosition property.
        rstPublishers->CursorLocation = adUseClient;
        rstPublishers->Open("select pub_id, pub_name from publishers"
            " order by pub_name", strCnn, adOpenStatic,
            adLockBatchOptimistic, adCmdText);

        //Open an IADORecordBinding interface pointer
        //which will be used for Binding Recordset to a class
        TESTHR(rstPublishers->QueryInterface(
            __uuidof(IADORecordBinding), (LPVOID*)&picRs));

        //Bind the Recordset to a C++ Class here
        TESTHR(picRs->BindToRecordset(&Publs));

        rstPublishers->MoveFirst();

         while (true)    // Continuous loop.
        {
            // Display information about the current record
            // and get user input
            printf("Publisher:%s \n Record %d of %d\n\n",
                Publs.lP_pubnameStatus  == adFldOK ?
                Publs.m_szP_pubname : "<NULL>",
                rstPublishers->AbsolutePosition,
                rstPublishers->RecordCount);
            printf("Enter command:\n ");
            printf("[1 - next          /  2 - previous       /\n");
            printf(" 3 - set bookmark  /  4 - go to bookmark /\n");
            printf(" 5 - quit                                ]\n");

            scanf("%d", &intCommand);
            if ((intCommand < 1) || (intCommand > 4))
                break;    // Out of range entry exits program loop.

            switch(intCommand)
            {
                // Move forward or backward, trapping for BOF or EOF
                case 1:
                    rstPublishers->MoveNext();
                    if (rstPublishers->EndOfFile)
                    {
                        printf("\nCannot move past the last record."
                               " Try again...\n");
                        rstPublishers->MoveLast();
                    }
                    break;

                case 2:
                    rstPublishers->MovePrevious();
                    if (rstPublishers->BOF)
                    {
                        printf("\nCannot move before the first record."
                               " Try again...\n");
                        rstPublishers->MoveFirst();
                    }
                    break;

                // store the bookmark of the current record.
                case 3:
                    VarBookmark = rstPublishers->Bookmark;
                    // Go to the record indicated by the
                    // stored bookmark
                    break;

                case 4:
                    // Check for whether bookmark set for a record
                    if (VarBookmark.vt == VT_EMPTY)
                        printf("No Bookmark set!\n");
                    else
                        rstPublishers->Bookmark = VarBookmark;
                    break;

                default:
                    break;
            }
        }
    }
    catch (_com_error &e)
    {
        printf("Error in BOFx...\n");
        // Notify the user of errors if any.
        _variant_t vtConnect = rstPublishers->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                printf("Error:\n");
                printf("Code = %08lx\n", e.Error());
                printf("Message = %s\n", e.ErrorMessage());
                printf("Source = %s\n", (LPCSTR) e.Source());
                printf("Description = %s\n", (LPCSTR) e.Description());
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
        printf("Press any key to continue...");
        getch();
    }

    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (rstPublishers)
        if (rstPublishers->State == adStateOpen)
            rstPublishers->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      BookmarkX Function                               //
//                                                       //
///////////////////////////////////////////////////////////

void BookmarkX(void)
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr rstAuthors = NULL;

    //Define Other Variables
    IADORecordBinding *picRs = NULL; //Interface Pointer declared.
    CAuthors Authrs;
    HRESULT  hr = S_OK;
    _bstr_t  strCnn("Provider='sqloledb';Data Source='MySqlServer';"
              "Initial Catalog='pubs';Integrated Security='SSPI';");
    _variant_t vBookmark;

    // Variable declaration for safe arrays.
    SAFEARRAY FAR* psa;

    // define ARRAY/ VARIANT variant.
    vBookmark.vt = VT_ARRAY|VT_VARIANT;
    SAFEARRAYBOUND rgsabound[1];
    rgsabound[0].lLbound = 0;
    rgsabound[0].cElements = 11;
    long ii = 0;

    try
    {
        rstAuthors.CreateInstance(__uuidof(Recordset));
        // Set The Cursor Location
        rstAuthors->CursorLocation  = adUseClient;
        rstAuthors->PutActiveConnection((_variant_t)strCnn);

        // Open Authors table
        TESTHR(rstAuthors->Open("select * from authors",strCnn,
            adOpenStatic,adLockBatchOptimistic,adCmdText));

        //Open an IADORecordBinding interface pointer
        //which we'll use for binding Recordset to a class
        TESTHR(rstAuthors->QueryInterface(__uuidof(IADORecordBinding),
                (LPVOID*)&picRs));

        //Bind the Recordset to a C++ Class here
        TESTHR(picRs->BindToRecordset(&Authrs));

        printf("Number of Records before filtering:  %d\n",
                rstAuthors->RecordCount);

        // Create safearrays to store array of variant
        psa = SafeArrayCreate(VT_VARIANT,1,rgsabound);

        // Store bookmark of every other record into an array.
        while ((!rstAuthors->EndOfFile) && (ii < 11))
        {
            SafeArrayPutElement(psa,&ii,&rstAuthors->Bookmark);
            //ii = ii +1;
            ii++;
            rstAuthors->Move(2);
        }

        vBookmark.parray = psa;

        // Filter the Record with the array of bookmarks.
        rstAuthors->put_Filter(vBookmark);
        printf("Number of Records after filtering:  %d\n",
            rstAuthors->RecordCount);
        rstAuthors->MoveFirst();

        while (!rstAuthors->EndOfFile)
        {
            printf("%d    %s\n",rstAuthors->AbsolutePosition,
                Authrs.lau_lnameStatus == adFldOK ?
                Authrs.m_szau_lname : "<NULL>");
            rstAuthors->MoveNext();
        }
    }
    catch (_com_error &e)
    {
        // Notify the user of errors if any.
        _variant_t vtConnect = rstAuthors->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                printf("Error:\n");
                printf("Code    = %08lx\n", e.Error());
                printf("Message = %s\n", e.ErrorMessage());
                printf("Source  = %s\n", (LPCSTR) e.Source());
                printf("Description = %s\n", (LPCSTR) e.Description());
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (rstAuthors)
        if (rstAuthors->State == adStateOpen)
            rstAuthors->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr  pErr    = NULL;
    long      nCount  = 0;
    long      i       = 0;

    if( (pConnection->Errors->Count) > 0)
    {
        nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}
// EndBOFCpp

BofEofBookmark.h

// BeginBOFEOFH
#include "icrsint.h"

//This Class extracts only pubid,lastname and hire_date
class CPublishers : public CADORecordBinding
{
BEGIN_ADO_BINDING(CPublishers)

    //Column title is the 2nd field in the recordset
    ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_szP_pubid,
        sizeof(m_szP_pubid), lP_pubidStatus, FALSE)

    //Column type is the 3rd field in the recordset
    ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_szP_pubname,
        sizeof(m_szP_pubname), lP_pubnameStatus, TRUE)

END_ADO_BINDING()

public:
    CHAR    m_szP_pubid;
    ULONG   lP_pubidStatus;
    CHAR    m_szP_pubname[40];
    ULONG   lP_pubnameStatus;
};

//This Class extracts only authorlastname

class CAuthors : public CADORecordBinding
{
BEGIN_ADO_BINDING(CAuthors)

    //Column authorlname is the 2nd field in the recordset
    ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar,  m_szau_lname,
         sizeof(m_szau_lname), lau_lnameStatus, FALSE)

END_ADO_BINDING()

public:
    CHAR    m_szau_lname[40];
    ULONG   lau_lnameStatus;
};
// EndBOFEOFH

请参阅

BOF 和 EOF 属性 | Bookmark 属性 | Recordset 对象


CacheSize 属性范例 (VC++)

本范例使用 CacheSize 属性显示使用和不使用缓存（大小为 30 条记录）时执行的操作在性能上的差别。

// BeginCacheSizeCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>
#include <winbase.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void CacheSizeX();
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    CacheSizeX();

    //Wait here for user to see the output..
    printf("\nPress any key to continue...");
    getch();

    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      CacheSizeX Function                              //
//                                                       //
///////////////////////////////////////////////////////////

void CacheSizeX()
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace
     _RecordsetPtr    pRstRoySched  = NULL;

     //Define Other Variables
    HRESULT  hr = S_OK;
    DWORD sngStart;
    DWORD sngEnd;
    float sngNoCache;
    float sngCache;
    int intLoop = 0;
    _bstr_t strTemp;

    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
        "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        //Open the RoySched table.
        TESTHR(pRstRoySched.CreateInstance(__uuidof(Recordset)));
        pRstRoySched->Open("roysched", strCnn, adOpenForwardOnly,
            adLockReadOnly, adCmdTable);

        // Enumerate the Recordset object twice and record
        // the elapsed time.
        sngStart = GetTickCount();

        for (intLoop = 1; intLoop < 2; intLoop++)
        {
            pRstRoySched->MoveFirst();

            while(!(pRstRoySched->EndOfFile))
            {
                    // Execute a simple operation for the
                    // performance test.
                    strTemp = pRstRoySched->Fields->
                        Item["title_id"]->Value;
                    pRstRoySched->MoveNext();
            }
        }
        sngEnd = GetTickCount();
        sngNoCache = (float)(sngEnd - sngStart)/(float)1000;

        // Cache records in groups of 30 records.
        pRstRoySched->MoveFirst();
        pRstRoySched->CacheSize = 30;

        sngStart =  GetTickCount();

        // Enumerate the Recordset object twice and record
        // the elapsed time.
        for (intLoop = 1;intLoop < 2; intLoop++)
        {
            pRstRoySched->MoveFirst();
            while(!(pRstRoySched->EndOfFile))
            {
                    // Execute a simple operation for the
                    // performance test.
                    strTemp = pRstRoySched->Fields->
                        Item["title_id"]->Value;
                    pRstRoySched->MoveNext();
            }
        }
        sngEnd =  GetTickCount();
        sngCache = (float)(sngEnd - sngStart)/(float)1000;

        // Display performance results.
        printf("Caching Performance Results:\n");
        printf("No cache: %6.3f  seconds \n", sngNoCache);
        printf("30-record cache: %6.3f  seconds \n", sngCache);
    }
    catch(_com_error &e)
    {
         // Notify the user of errors if any.
        _variant_t vtConnect = pRstRoySched->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
               // Pass a connection pointer accessed from the Recordset.
               PrintProviderError(vtConnect);
               break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    if (pRstRoySched)
        if (pRstRoySched->State == adStateOpen)
            pRstRoySched->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.

    // pErr is a record object in the Connection's Error collection.
    ErrorPtr pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s", pErr->Number,
                pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

    // Print Com errors.
    printf("Error\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    printf("\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCSTR) bstrDescription);

}
// EndCacheSizeCpp

请参阅

CacheSize 属性 | Recordset 对象


Cancel 方法范例 (VC++)

本范例使用 Cancel 方法，在连接繁忙时取消在 Connection 对象上执行的命令。

// BeginCancelCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include<conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void CancelX();
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    CancelX();

    //Wait here for user to see the output..
    printf("\nPress any key to continue...");
    getch();

    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      CancelX Function                                 //
//                                                       //
///////////////////////////////////////////////////////////

void CancelX()
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace
     _ConnectionPtr pConnection = NULL;

     //Define Other Variables
    HRESULT  hr = S_OK;
    _bstr_t strCmdChange;
    _bstr_t strCmdRestore;
    BOOL booChanged = FALSE;

    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
        "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        // open a connection.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        pConnection->Open(strCnn,"","",adConnectUnspecified);

        // Define command strings.
        strCmdChange = "UPDATE titles SET type = 'self_help' "
            "WHERE type = 'psychology'";

        strCmdRestore = "UPDATE titles SET type = 'psychology' "
            "WHERE type = 'self_help'";

        // Begin a transaction, then execute a command asynchronously.
        pConnection->BeginTrans();
        pConnection->Execute(strCmdChange,NULL,adAsyncExecute);

        // do something else for a little while - this could be changed
        for (int i = 1; i<=100000 ;i++)
        {
           // i = i + i;
            printf("%d\n", i);
        }

        // If the command has NOT completed, cancel the execute
        // and roll back the transaction. Otherwise, commit the
        // transaction.
        if ((pConnection->GetState()))
        {
            pConnection->Cancel();
            pConnection->RollbackTrans();
            booChanged = FALSE;
            printf("Update canceled.\n");
            printf("GetState = %d\n", pConnection->GetState());
        }
        else
        {
            pConnection->CommitTrans();
            booChanged = TRUE;
            printf("Update complete.\n");

        }

        // If the change was made, restore the data
        // because this is a demonstration.
        if (booChanged)
        {
            pConnection->Execute(strCmdRestore,NULL,0);
            printf("Data restored.\n");
        }
    }
    catch(_com_error &e)
    {
        // Notify user of any errors that result from
        // executing the query.
        // Pass a connection pointer accessed from the Connection.
        PrintProviderError(pConnection);
        PrintComError(e);
    }

    // Cleanup object before exit
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;

        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s", pErr->Number,
                pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

    // Print Com errors.
    printf("Error\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    printf("\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndCancelCpp

请参阅

Cancel 方法 | Connection 对象


Clone 方法范例 (VC++)

本范例使用 Clone 方法来创建 Recordset 的副本，然后让用户单独定位每个副本的记录指针。

// BeginCloneCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <stdio.h>
#include <ole2.h>
#include <conio.h>
#include "CloneX.h"

// Function Declarations.
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void CloneX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);
inline char* mygets(char* strDest, int n)
{
    char strExBuff[10];
    char* pstrRet = fgets(strDest, n, stdin);

    if (pstrRet == NULL)
        return NULL;

    if (!strrchr(strDest, '\n'))
        // Exhaust the input buffer.
        do
        {
            fgets(strExBuff, sizeof(strExBuff), stdin);
        }while (!strrchr(strExBuff, '\n'));
    else
        // Replace '\n' with '\0'
        strDest[strrchr(strDest, '\n') - strDest] = '\0';

    return pstrRet;
}

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    CloneX();

    //Wait here for user to see the output..
    printf("\nPress any key to continue...");
    getch();
    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      CloneX Function                                  //
//                                                       //
///////////////////////////////////////////////////////////

void  CloneX()
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr  arstStores[3];

    //Define Other Variables
    HRESULT hr = S_OK;
    int intLoop = 0;
    _bstr_t strSQL;
    _bstr_t strMessage;
    _bstr_t strFind;
    int intLoop1 = 0;
    char *tempStr;
    bool boolFlag = TRUE;
    char m_szS_stor_name[150];

    // Assign SQL statement and connection string to variables.
    strSQL = "SELECT stor_name FROM Stores ORDER BY stor_name";

    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        // Open recordset as a static cursor type recordset.
        arstStores[0].CreateInstance(__uuidof(Recordset));
        arstStores[0]->CursorType = adOpenStatic;
        arstStores[0]->LockType = adLockBatchOptimistic;

        TESTHR(arstStores[0]->Open(strSQL,strCnn, adOpenStatic,
            adLockBatchOptimistic,adCmdText));

        // Create two clones of the original Recordset.
        arstStores[1] = arstStores[0]->Clone(adLockUnspecified);
        arstStores[2] = arstStores[0]->Clone(adLockUnspecified);

        while (boolFlag)
        {
            // Loop through the array so that on each pass,
            // the user is searching a different copy of the
            // same Recordset.
            for (intLoop = 1; intLoop <= 3 ; intLoop++)
            {
                // Ask for search string while showing where
                // the current record pointer is for each Recordset.
                printf("Recordsets from stores table:\n");

                _bstr_t str1 = arstStores[0]->Fields->
                    GetItem("stor_name")->Value;
                printf("\t1 - Original - Record pointer at %s",
                    (LPCSTR)str1);

                _bstr_t str2 = arstStores[1]->Fields->
                    GetItem("stor_name")->Value;
                printf("\n\t2 - Clone - Record pointer at %s",
                    (LPCSTR)str2);

                _bstr_t str3 = arstStores[2]->Fields->
                    GetItem("stor_name")->Value;
                printf("\n\t3 - Clone - Record pointer at %s",
                    (LPCSTR)str3);

                printf("\n\nEnter search string for # %d, "
                    "or press Enter to quit.\n", intLoop);
                mygets(m_szS_stor_name, 150);

                // Trim the String.
                tempStr = strtok(m_szS_stor_name, "  \t");
                strMessage = tempStr;
                if (tempStr == NULL)
                {
                    boolFlag = FALSE;
                    break;
                }

                // Find the search string; if there's no
                // match, jump to the last record.
                intLoop1 = intLoop - 1;

                arstStores[intLoop1]->Filter = "stor_name >= '" +
                    strMessage + "'";

                if (arstStores[intLoop1]->EndOfFile)
                {
                    arstStores[intLoop1]->Filter = (long)adFilterNone;
                    arstStores[intLoop1]->MoveLast();
                }
            }
        } // End of While Loop
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _variant_t vtConnect;

        vtConnect = arstStores[0]->GetActiveConnection();

        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    if (arstStores[0])
        if (arstStores[0]->State == adStateOpen)
            arstStores[0]->Close();
    if (arstStores[1])
        if (arstStores[1]->State == adStateOpen)
            arstStores[1]->Close();
    if (arstStores[2])
        if (arstStores[2]->State == adStateOpen)
            arstStores[2]->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr pErr = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
};

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

    // Print Com errors.
    printf("Error\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    printf("\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
};
// EndCloneCpp

CloneX.h

// BeginCloneH
#include "icrsint.h"

// This Class extracts only store name
// from "stores" table.
class CStores : public CADORecordBinding
{
BEGIN_ADO_BINDING(CStores)

    //Column stor_name is the 1st field in the recordset

    ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_szS_stor_name,
         sizeof(m_szS_stor_name), lS_stor_nameStatus, FALSE)

END_ADO_BINDING()

public:
    CHAR    m_szS_stor_name[150];
    ULONG   lS_stor_nameStatus;
};

// EndCloneH

请参阅

Clone 方法 | Recordset 对象


CompareBookmarks 方法范例 (VC++)

本范例演示 CompareBookmarks 方法。除了特殊的书签以外，不需要书签的相对值。

将源于 Authors 表的 Recordset 的随机行指定为搜索目标。然后显示每一行相对于该目标的位置。

// BeginCompareBookmarksCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void CompareBookMarksX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

//////////////////////////////////////////////////////////
//                                                      //
//        Main Function                                 //
//                                                      //
//////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    CompareBookMarksX();

    printf("Press any key to continue...");
    getch();
    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//           CompareBookMarksX Function                 //
//                                                      //
//////////////////////////////////////////////////////////

void CompareBookMarksX(void)
{
    HRESULT hr = S_OK;

    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
        "Initial Catalog='pubs';Integrated Security='SSPI';");

    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr pRstAuthors = NULL;
    _variant_t vTarget;
    _bstr_t strAns;
    _bstr_t strTitle;
    strTitle = "CompareBookmarks Example";
    try
    {
        TESTHR(pRstAuthors.CreateInstance(__uuidof(Recordset)));

        pRstAuthors->Open("SELECT * FROM authors ORDER BY au_id", strCnn,
            adOpenStatic, adLockReadOnly, adCmdText);

        long count = pRstAuthors->RecordCount;
        printf("Rows in the Recordset = %d\n", count);
        if (count == 0)
            exit(1);     //Exit if an empty recordset

        srand( (unsigned)time( NULL ) ); //Randomize

        count = int(rand() % (count-1)); //Get position between 1 and count-1
        if(!count) {count++;};

        printf("Randomly chosen row position = %d\n", count);

        _variant_t vtBookMark = (short)adBookmarkFirst;

        pRstAuthors->Move(count,vtBookMark); //Move row to random position

        vTarget = pRstAuthors->Bookmark;    //Remember the mystery row.
        count = 0;
        long intLineCnt = 3;
        pRstAuthors->MoveFirst();

        while (!(pRstAuthors->EndOfFile))       //Loop through recordset
        {
            intLineCnt++;
            if (intLineCnt%20 == 0)
            {
                printf("\nPress any key to continue...\n");
                getch();
            }
            long result = pRstAuthors->CompareBookmarks(
                pRstAuthors->Bookmark, vTarget);

            if (result == adCompareNotEqual)
                printf("Row %d: Bookmarks are not equal. %d\n", count, result);
            else if  (result == adCompareNotComparable)
                printf("Row %d: Bookmarks are not comparable.\n", count);
            else
            {
                switch(result)
                {
                    case adCompareLessThan:
                        strAns = "less than";
                        break;
                    case adCompareEqual:
                        strAns = "equal to";
                        break;
                    case adCompareGreaterThan:
                        strAns = "greater than";
                        break;
                    default:
                        strAns = "in error comparing to";
                        break;
                }
                printf ("Row position  %d  is  %s  the target.\n",
                    count,(LPCSTR)strAns);
            }
            count++;
            pRstAuthors->MoveNext();
        }
   }
   catch(_com_error &e)
   {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstAuthors->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    if (pRstAuthors)
        if (pRstAuthors->State == adStateOpen)
            pRstAuthors->Close();
}

//////////////////////////////////////////////////////////
//                                                      //
//            PrintProviderError Function               //
//                                                      //
//////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr pErr = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,
                pErr->Description);
        }
    }
}

//////////////////////////////////////////////////////////
//                                                      //
//        PrintComError Function                        //
//                                                      //
//////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndCompareBookmarksCpp

请参阅

CompareBookmarks 方法 | Recordset 对象


ConnectionString、ConnectionTimeout 和 State 属性范例 (VC++)

本范例演示使用 ConnectionString 属性打开 Connection 对象的不同方式。范例中还使用 ConnectionTimeout 属性来设置连接超时的时间段，并使用 State 属性来检查连接的状态。运行此过程需要 GetState 函数。

// BeingConnectionStringCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void ConnectionStringX();
_bstr_t GetState(int intState);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    ConnectionStringX();

    //Wait here for user to see the output..
    printf("\nPress any key to continue...");
    getch();

    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      ConnectionStringX Function                       //
//                                                       //
///////////////////////////////////////////////////////////

void ConnectionStringX()
{
    // Define Connection object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace
     _ConnectionPtr pConnection1 = NULL;
     _ConnectionPtr pConnection2 = NULL;
     _ConnectionPtr pConnection3 = NULL;
     _ConnectionPtr pConnection4 = NULL;

    //Define Other Variables
    HRESULT  hr = S_OK;

    try
    {
        // Open a connection using OLE DB syntax.
        TESTHR(pConnection1.CreateInstance(__uuidof(Connection)));
        pConnection1->ConnectionString =
            "Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='Pubs';Integrated Security='SSPI';";
        pConnection1->ConnectionTimeout = 30;
        pConnection1->Open("","","",adConnectUnspecified);
        printf("cnn1 state: %s\n",
            (LPCTSTR)GetState(pConnection1->State));

        // Open a connection using a DSN and ODBC tags.
        // It is assumed that you have create DSN 'Pubs' with a user name as
        // 'MyUserId' and password as 'MyPassword'.
        TESTHR(pConnection2.CreateInstance(__uuidof(Connection)));
        pConnection2->ConnectionString = "DSN=Pubs;UID=MyUserId;PWD=MyPassword;";
        pConnection2->Open("","","",adConnectUnspecified);
        printf("cnn2 state: %s\n",
            (LPCTSTR)GetState(pConnection2->State));

        // Open a connection using a DSN and OLE DB tags.
        TESTHR(pConnection3.CreateInstance(__uuidof(Connection)));
        pConnection3->ConnectionString = "Data Source=Pubs;";
        pConnection3->Open("","","",adConnectUnspecified);
        printf("cnn3 state: %s\n",
            (LPCTSTR)GetState(pConnection3->State));

        // Open a connection using a DSN and individual
        // arguments instead of a connection string.
        // It is assumed that you have create DSN 'Pubs' with a user name as
        // 'MyUserId' and password as 'MyPassword'.
        TESTHR(pConnection4.CreateInstance(__uuidof(Connection)));
        pConnection4->Open("Pubs","MyUserId","MyPassword",adConnectUnspecified);
        printf("cnn4 state: %s\n",
            (LPCTSTR)GetState(pConnection4->State));
    }
    catch(_com_error &e)
    {
        // Notify user of any errors.
        // Pass a connection pointer accessed from the Connection.
        PrintProviderError(pConnection1);
        if(pConnection2)
            PrintProviderError(pConnection2);
        if(pConnection3)
            PrintProviderError(pConnection3);
        if(pConnection4)
            PrintProviderError(pConnection4);
        PrintComError(e);
    }

    //Cleanup objects before exit.
    if (pConnection1)
        if (pConnection1->State == adStateOpen)
            pConnection1->Close();
    if (pConnection2)
        if (pConnection2->State == adStateOpen)
            pConnection2->Close();
    if (pConnection3)
        if (pConnection3->State == adStateOpen)
            pConnection3->Close();
    if (pConnection4)
        if (pConnection4->State == adStateOpen)
            pConnection4->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      GetState Function                                //
//                                                       //
///////////////////////////////////////////////////////////

_bstr_t GetState(int intState)
{
    _bstr_t strState;
    switch(intState)
    {
        case adStateClosed:
            strState = "adStateClosed";
            break;
        case adStateOpen:
            strState = "adStateOpen";
            break;
        default:
        ;
    }
    return strState;
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr  pErr = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;

        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,
                (LPCSTR)pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

    // Print Com errors.
    printf("Error\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    printf("\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndConnectionStringCpp

请参阅

Connection 对象 | ConnectionString 属性 | ConnectionTimeout 属性 | State 属性


Count 属性范例 (VC++)

本范例使用 Employee 数据库中的两个集合演示 Count 属性。该属性获取每个集合的对象数，并设置枚举这些集合的循环上限。枚举这些集合的另一种方法不使用 Count 属性，而是使用 For Each...Next 语句。

// BeginCountCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include<conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void CountX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    CountX();

    //Wait here for user to see the output..
    printf("\nPress any key to Exit...");
    getch();

    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      CountX Function                                  //
//                                                       //
///////////////////////////////////////////////////////////

void CountX()
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace
    _RecordsetPtr pRstEmployee = NULL;

    //Define Other Variables
    HRESULT hr = S_OK;
    _variant_t Index;
    Index.vt = VT_I2;
    int j = 0;

    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
        "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        // Open recordset with data from Employee table.
        TESTHR(pRstEmployee.CreateInstance(__uuidof(Recordset)));
        pRstEmployee->Open("Employee", strCnn, adOpenForwardOnly,
            adLockReadOnly, adCmdTable);

        // Print information about Fields collection.
        printf("%d Fields in Employee\n", pRstEmployee->Fields->Count);
        for (int intLoop = 0;
             intLoop <= (pRstEmployee->Fields->Count-1);
             intLoop++)
        {
            Index.iVal = intLoop;
            printf(" %s\n",(LPSTR) pRstEmployee->Fields->
                GetItem(Index)->Name);
        }

        // Print information about Properties collection.
        printf("\n%d Properties in Employee\n", pRstEmployee->
            Properties->Count);
        for (intLoop = 0;
             intLoop <= (pRstEmployee->Properties->Count - 1);
             intLoop++)
        {
            j++;
            Index.iVal = intLoop;
            printf(" %s\n" ,(LPSTR)pRstEmployee->Properties->
                GetItem(Index)->Name);
            if (((j % 23) == 0) || (intLoop == 11))
            {
                printf("\nPress any key to continue...");
                getch();

                //Clear the screen for the next display
                system("cls");
                j = 0;
            }
        }
    }
    catch(_com_error &e)
    {
        // Notify user of any errors that result from
        // executing the query.
        // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstEmployee->GetActiveConnection();

        switch(vtConnect.vt)
        {
        case VT_BSTR:
            PrintComError(e);
            break;
        case VT_DISPATCH:
            PrintProviderError(vtConnect);
            break;
        default:
            printf("Errors occured.");
            break;
        }
    }
    // Clean up objects before exit.
    if (pRstEmployee)
        if (pRstEmployee->State == adStateOpen)
            pRstEmployee->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr pErr = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;

        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n",pErr->Number,
                pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

    // Print Com errors.
    printf("Error\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    printf("\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndCountCpp

请参阅

Count 属性


CursorType、LockType 和 EditMode 属性范例 (VC++)

本范例演示在打开 Recordset 前设置 CursorType 和 LockType 属性。范例还显示不同条件下 EditMode 属性的值。运行此过程需要 EditModeOutput 函数。

// BeginEditModeCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>

// Function declaration
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void EditModeX(void);
void EditModeOutput(char *, int);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

     EditModeX();

    // Wait here for the user to see the output
    printf("\n\nPress any key to continue...");
    getch();

    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      EditModeX Function                               //
//                                                       //
///////////////////////////////////////////////////////////
void EditModeX(void)
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr     pRstEmployees = NULL;
    _ConnectionPtr    pConnection  = NULL;

    HRESULT hr = S_OK;

    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
        "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        // Open a connection
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        hr = pConnection->Open(strCnn,"","",adConnectUnspecified);

        // Open recordset with data from employee table
        TESTHR(pRstEmployees.CreateInstance(__uuidof(Recordset)));

        pRstEmployees->CursorLocation = adUseClient;
        pRstEmployees->CursorType = adOpenStatic;
        pRstEmployees->LockType  = adLockBatchOptimistic;

        pRstEmployees->Open("employee",
             _variant_t((IDispatch *) pConnection,true),
            adOpenStatic,adLockBatchOptimistic,adCmdTable);

        // Show the EditMode property under different editing states.
        pRstEmployees->AddNew ();
        pRstEmployees->Fields->Item["emp_id"]->Value =
            (_bstr_t)("T-T55555M");
        pRstEmployees->Fields->Item["fname"]->Value =
            (_bstr_t)("temp_fname");
        pRstEmployees->Fields->Item["lname"]->Value =
            (_bstr_t)("temp_lname");
        EditModeOutput("After AddNew: ", pRstEmployees->EditMode);

        pRstEmployees->UpdateBatch(adAffectCurrent);
        EditModeOutput("After Update: ", pRstEmployees->EditMode);

        pRstEmployees->Fields->Item["fname"]->Value = (_bstr_t)("test");
        EditModeOutput("After Edit: ", pRstEmployees->EditMode);

        // Delete new record because this is a demonstration.
        pConnection->Execute("DELETE FROM employee WHERE emp_id = "
            "'T-T55555M'", NULL, adCmdText);
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        // Pass a connection pointer accessed from the Recordset.
        PrintProviderError(pConnection);
        PrintComError(e);
    }

    // Clean up objects before exit.
    if (pRstEmployees)
        if (pRstEmployees->State == adStateOpen)
            pRstEmployees->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      EditModeOutput() Function                        //
//                                                       //
///////////////////////////////////////////////////////////
void EditModeOutput(char *strTemp, int intEditMode)
{
    // Print report based on the value of the EditMode property.
    printf("\n%s", strTemp);
    printf("\n  EditMode = ");

    switch (intEditMode)
    {
        case adEditNone :
            printf("adEditNone");
            break;
        case adEditInProgress :
            printf("adEditInProgress");
            break;
        case adEditAdd :
            printf("adEditAdd");
            break;
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr  pErr = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\n\t Error number: %x\t%s\n", pErr->Number,
                (LPCSTR)pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

    // Print Com errors.
    printf("Error\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    printf("\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}

// EndEditModeCpp

请参阅

CursorType 属性 | EditMode 属性 | LockType 属性 | Recordset 对象


Delete 方法范例 (VC++)

本范例使用 Delete 方法从 Recordset 中删除指定的记录。

// BeginDeleteCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <stdio.h>
#include <ole2.h>
#include <conio.h>
#include "DeleteX.h"

//Function Declarations.
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void DeleteX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);
inline char* mygets(char* strDest, int n)
{
    char strExBuff[10];
    char* pstrRet = fgets(strDest, n, stdin);

    if (pstrRet == NULL)
        return NULL;

    if (!strrchr(strDest, '\n'))
        // Exhaust the input buffer.
        do
        {
            fgets(strExBuff, sizeof(strExBuff), stdin);
        }while (!strrchr(strExBuff, '\n'));
    else
        // Replace '\n' with '\0'
        strDest[strrchr(strDest, '\n') - strDest] = '\0';

    return pstrRet;
}

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    DeleteX();

    // Wait here for the user to see the output
    printf("\n\nPress any key to continue...");
    getch();

    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      DeleteX Function                                 //
//                                                       //
///////////////////////////////////////////////////////////

void DeleteX(void)
{

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr  pRstRoySched = NULL;

    // Define Other Variables
    IADORecordBinding   *picRs = NULL;  //Interface Pointer declared.
    CRoySchedRs    royschrs;            //C++ class object
    HRESULT hr = S_OK;

    char  strTitleID[10], strTmpTitleID[10]="";
    long  longHiRange;
    int   intRoyalty, intLoRange, cnt=0;
    bool  blnFound = TRUE;

    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        // Open RoySched table
        TESTHR(pRstRoySched.CreateInstance(__uuidof(Recordset)));

        pRstRoySched->CursorLocation = adUseClient;
        pRstRoySched->CursorType = adOpenStatic;
        pRstRoySched->LockType  = adLockBatchOptimistic;

        TESTHR(pRstRoySched->Open("SELECT * FROM roysched WHERE"
            " royalty = 20",strCnn,adOpenStatic,adLockBatchOptimistic,
            adCmdText));

        // Prompt for a record to delete.
        printf("Before delete there are %d titles with 20 percent "
            "royalty :\n", pRstRoySched->RecordCount);

        // Open an IADORecordBinding interface pointer which we'll use
        // for Binding Recordset to a class.
        TESTHR(pRstRoySched->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        // Bind the Recordset to a C++ Class here
        TESTHR(picRs->BindToRecordset(&royschrs));

        while(!(pRstRoySched->EndOfFile))
        {
            printf("%s\n", royschrs.lemp_titleidStatus == adFldOK ?
                royschrs.m_sz_titleid : "<NULL>");
            pRstRoySched->MoveNext();
        }

        printf("\nEnter the ID of a record to delete: ");
        mygets(strTitleID, 10);

        // Converting the title_id to upper case
        for( cnt=0; cnt<10; cnt++)
        {
            if(strTitleID[cnt] != NULL)
            {
                if( IsCharAlpha( strTitleID[cnt]) )
                {
                    if( islower( strTitleID[cnt]) )
                        strTmpTitleID[cnt] = _toupper(strTitleID[cnt]);
                    else
                        strTmpTitleID[cnt] = strTitleID[cnt];
                }
                else
                {
                    strTmpTitleID[cnt] = strTitleID[cnt];
                }
            }
        }

        // Move to the record and save data so it can be restored.
        pRstRoySched->PutFilter ("title_id = '" +
            (_bstr_t)(LPCSTR)strTmpTitleID + "'");

        if(pRstRoySched->RecordCount != 0)
        {
            intLoRange = royschrs.m_sz_lorange;
            longHiRange = royschrs.m_sz_hirange;
            intRoyalty = royschrs.m_sz_royalty;

            // Delete the record
            pRstRoySched->Delete(adAffectCurrent);
            pRstRoySched->UpdateBatch(adAffectCurrent);
        }
        else
        {
            blnFound = FALSE;
            printf("This Title ID not available");
        }

        // Show the results.
        VARIANT varFilter;
        varFilter.vt = VT_I2;
        varFilter.iVal = adFilterNone;
        pRstRoySched->PutFilter (varFilter);
        pRstRoySched->Requery(-1);

        // Bind the Recordset to a C++ Class here.
        TESTHR(picRs->BindToRecordset(&royschrs));

        printf("\nAfter delete there are %d titles with 20 percent"
            " royalty: ", pRstRoySched->RecordCount);

        while(!(pRstRoySched->EndOfFile))
        {
            printf("\n%s", royschrs.lemp_titleidStatus == adFldOK ?
                royschrs.m_sz_titleid : "<NULL>");
            pRstRoySched->MoveNext();
        }

        // Restore the data because this is a demonstration.
        if(blnFound)
        {
            // Set the final character of the destination string to NULL.
            royschrs.m_sz_titleid[sizeof(royschrs.m_sz_titleid)-1] = '\0';
            // The source string will get truncated if its length is
            // longer than the length of the destination string minus one.
            strncpy(royschrs.m_sz_titleid,strTmpTitleID,sizeof(royschrs.m_sz_titleid)-1);
            royschrs.m_sz_lorange = intLoRange;
            royschrs.m_sz_hirange = longHiRange;
            royschrs.m_sz_royalty = intRoyalty;

            TESTHR(picRs->AddNew(&royschrs));

            pRstRoySched->UpdateBatch(adAffectCurrent);
        }
    }
    catch(_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstRoySched->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (pRstRoySched)
        if (pRstRoySched->State == adStateOpen)
            pRstRoySched->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr  pErr = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndDeleteCpp

DeleteX.h

// BeginDeleteH
#include "icrsint.h"

// This Class extracts titleid, lorange, hirange and royalty
// from the "roysched" table.

class CRoySchedRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CRoySchedRs)

    //Column empid is the 1st field in the recordset

    ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_sz_titleid,
         sizeof(m_sz_titleid), lemp_titleidStatus, TRUE)

    ADO_VARIABLE_LENGTH_ENTRY2(2, adInteger, m_sz_lorange,
         sizeof(m_sz_lorange), lemp_lorangeStatus, TRUE)

    ADO_VARIABLE_LENGTH_ENTRY2(3, adInteger, m_sz_hirange,
         sizeof(m_sz_hirange), lemp_hirangeStatus, TRUE)

    ADO_VARIABLE_LENGTH_ENTRY2(4, adInteger, m_sz_royalty,
         sizeof(m_sz_royalty), lemp_royaltyStatus, TRUE)

END_ADO_BINDING()

public:

    CHAR     m_sz_titleid[10];
    ULONG    lemp_titleidStatus;
    ULONG    m_sz_lorange;
    ULONG    lemp_lorangeStatus;
    ULONG    m_sz_hirange;
    ULONG    lemp_hirangeStatus;
    ULONG    m_sz_royalty;
    ULONG    lemp_royaltyStatus;
};
// EndDeleteH

请参阅

Delete 方法 (ADO Recordset) | Recordset 对象


Description、HelpContext、HelpFile、NativeError、Number、Source 和 SQLState 属性范例 (VC++)

本范例触发并捕获错误，同时显示产生的 Error 对象的 Description、HelpContext、HelpFile、NativeError、Number、Source 和 SQLState 属性。

// BeginDescriptionCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include<conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void DescriptionX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    DescriptionX();

    //Wait here for user to see the output..
    printf("\nPress any key to continue...");
    getch();
    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      DescriptionX Function                            //
//                                                       //
///////////////////////////////////////////////////////////

void DescriptionX()
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace
    _ConnectionPtr pConnection = NULL;
    ErrorPtr errorLoop = NULL;

    //Define Other Variables
    HRESULT hr = S_OK;

    try
    {
        // Intentionally trigger an error.
        // open connection
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));

        if (FAILED(hr = pConnection->Open("nothing","","",adConnectUnspecified)))
        {
            _com_issue_error(hr);
            exit(1);
        }

        // Cleanup object before exit.
        pConnection->Close();
    }
    catch(_com_error)
    {
        // Pass a connection pointer.
        PrintProviderError(pConnection);
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    //Define Other Variables
    HRESULT  hr = S_OK;
    _bstr_t  strError;
    ErrorPtr  pErr = NULL;

    try
    {
        // Enumerate Errors collection and display
        // properties of each Error object.
        long nCount = pConnection->Errors->Count;

        // Collection ranges from 0 to nCount - 1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error #%d\n", pErr->Number);
            printf(" %s\n",(LPCSTR)pErr->Description);
            printf(" (Source: %s)\n",(LPCSTR)pErr->Source);
            printf(" (SQL State: %s)\n",(LPCSTR)pErr->SQLState);
            printf(" (NativeError: %d)\n",(LPCSTR)pErr->NativeError);
            if ((LPCSTR)pErr->GetHelpFile() == NULL)
            {
                printf("\tNo Help file available\n");
            }
            else
            {
                printf("\t(HelpFile: %s\n)" ,pErr->HelpFile);
                printf("\t(HelpContext: %s\n)" , pErr->HelpContext);
            }
        }
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        PrintComError(e);
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
   // Notify the user of errors if any.
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.

   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndDescriptionCpp

请参阅

Description 属性 | Error 对象 | HelpContext 属性 | HelpFile 属性 | NativeError 属性 | Number 属性 | Source 属性 (ADO Error) | SQLState 属性


Execute、Requery 和 Clear 方法范例 (VC++)

本范例演示从 Command 和 Connection 对象运行 Execute 方法。范例中还使用 Requery 方法检索 Recordset 中的当前数据，并使用 Clear 方法清除 Errors 集合的内容。运行本范例需要 ExecuteCommand 和 PrintOutput 函数。

// BeginExecuteCpp
#include <ole2.h>
#include <stdio.h>

#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void ExecuteX(void);
void ExecuteCommand(_CommandPtr pCmdTemp, _RecordsetPtr pRstTemp);
void PrintOutput(_RecordsetPtr pRstTemp);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

////////////////////////////////
//      Main Function         //
////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    ExecuteX();

    ::CoUninitialize();
}

///////////////////////////////////
//      ExecuteX Function        //
///////////////////////////////////

void ExecuteX(void)
{
   HRESULT    hr = S_OK;

    // Define string variables.
   _bstr_t strSQLChange("UPDATE Titles SET Type = "
            "'self_help' WHERE Type = 'psychology'");
   _bstr_t strSQLRestore("UPDATE Titles SET Type = "
            "'psychology' WHERE Type = 'self_help'");
   _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _ConnectionPtr  pConnection = NULL;
    _CommandPtr     pCmdChange  = NULL;
    _RecordsetPtr   pRstTitles  = NULL;

    try
    {
        // Open connection.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        pConnection->Open (strCnn, "", "", adConnectUnspecified);

        // Create command object.
        TESTHR(pCmdChange.CreateInstance(__uuidof(Command)));
        pCmdChange->ActiveConnection = pConnection;
        pCmdChange->CommandText = strSQLChange;

        // Open titles table, casting Connection pointer to an
        // IDispatch type so converted to correct type of variant.
        TESTHR(pRstTitles.CreateInstance(__uuidof(Recordset)));
        pRstTitles->Open ("Titles", _variant_t((IDispatch *) pConnection,
            true), adOpenStatic, adLockOptimistic, adCmdTable);

        // Print report of original data.
        printf(
            "\n\nData in Titles table before executing the query: \n");

        // Call function to print loop recordset contents.
        PrintOutput(pRstTitles);

        // Clear extraneous errors from the Errors collection.
        pConnection->Errors->Clear();

        // Call ExecuteCommand subroutine to execute pCmdChange command.
        ExecuteCommand(pCmdChange, pRstTitles);

        // Print report of new data.
        printf(
            "\n\n\tData in Titles table after executing the query: \n");
        PrintOutput(pRstTitles);

        // Use the Connection object's execute method to
        // execute SQL statement to restore data.
        pConnection->Execute(strSQLRestore, NULL, adExecuteNoRecords);

        // Retrieve the current data by requerying the recordset.
        pRstTitles->Requery(adCmdUnknown);

        // Print report of restored data.
        printf(
            "\n\n\tData after exec. query to restore original info: \n");
        PrintOutput(pRstTitles);
    }
    catch (_com_error &e)
    {
        PrintProviderError(pConnection);
        PrintComError(e);
    }

    // Clean up objects before exit.
    if (pRstTitles)
        if (pRstTitles->State == adStateOpen)
            pRstTitles->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

//////////////////////////////////////////
//      ExecuteCommand Function         //
//////////////////////////////////////////

void ExecuteCommand(_CommandPtr pCmdTemp, _RecordsetPtr pRstTemp)
{
    try
    {
        // CommandText property already set before function was called.
        pCmdTemp->Execute(NULL, NULL, adCmdText);

        // Retrieve the current data by requerying the recordset.
        pRstTemp->Requery(adCmdUnknown);
    }

    catch(_com_error &e)
    {
        // Notify user of any errors that result from
        // executing the query.
        // Pass a connection pointer accessed from the Recordset.
        PrintProviderError(pRstTemp->GetActiveConnection());
        PrintComError(e);
    }
}

/////////////////////////////////////
//      PrintOutput Function       //
/////////////////////////////////////

void PrintOutput(_RecordsetPtr pRstTemp)
{
    // Ensure at top of recordset.
    pRstTemp->MoveFirst();

    // If EOF is true, then no data and skip print loop.
    if( pRstTemp->EndOfFile )
    {
        printf("\tRecordset empty\n");
    }
    else
    {
        // Define temporary strings for output conversions.
        // Initialize to first record's values.
        _bstr_t bstrTitle;
        _bstr_t bstrType;

        // Enumerate Recordset and print from each.
        while(!(pRstTemp->EndOfFile))
            {
            // Convert variant string to convertable string type.
            bstrTitle = pRstTemp->Fields->GetItem("Title")->Value;
            bstrType  = pRstTemp->Fields->GetItem("Type")->Value;
            printf("\t%s, %s \n",
                (LPCSTR) bstrTitle,
                (LPCSTR) bstrType);

            pRstTemp->MoveNext();
        }
    }
}

///////////////////////////////////////////////
//      PrintProviderError Function          //
///////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr  pErr = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                pErr->Description);
        }
    }
}

//////////////////////////////////////
//      PrintComError Function      //
//////////////////////////////////////

void PrintComError(_com_error &e)
{
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

    // Print Com errors.
    printf("Error\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    printf("\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndExecuteCpp

请参阅

Clear 方法 | Command 对象 | Connection 对象 | Errors 集合 | Execute 方法 (ADO Command) | Execute 方法 (ADO Connection) | Requery 方法


Filter 和 RecordCount 属性范例 (VC++)

本范例基于应用在现有 Recordset 的特定条件，使用 Filter 属性打开新的 Recordset。范例中使用 RecordCount 属性显示两个 Recordset 中的记录数目。运行此过程需要 FilterField 函数。

// BeginFilterCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <stdio.h>
#include <ole2.h>
#include <conio.h>
#include "FilterX.h"

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void FilterX(void);
_RecordsetPtr FilterField(_RecordsetPtr rstTemp, _bstr_t strField, _bstr_t strFilter);
void FilterX2(void);
void PrintProviderError(_ConnectionPtr pCnn1);
void PrintComError(_com_error &e);
inline char* mygets(char* strDest, int n)
{
    char strExBuff[10];
    char* pstrRet = fgets(strDest, n, stdin);

    if (pstrRet == NULL)
        return NULL;

    if (!strrchr(strDest, '\n'))
        // Exhaust the input buffer.
        do
        {
            fgets(strExBuff, sizeof(strExBuff), stdin);
        }while (!strrchr(strExBuff, '\n'));
    else
        // Replace '\n' with '\0'
        strDest[strrchr(strDest, '\n') - strDest] = '\0';

    return pstrRet;
}

void main()
{
    HRESULT hr = S_OK;

    if(FAILED(::CoInitialize(NULL)))
        return;

    FilterX();

    //Wait here for user to see the output..
    printf("\nPress any key to Continue...");
    getch();

    //Clear the screen for the next display
    system("cls");

    FilterX2();

    //Wait here for user to see the output..
    printf("\nPress any key to Exit...");
    getch();
    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      FilterX Function                                 //
//                                                       //
///////////////////////////////////////////////////////////

void  FilterX()
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr rstPublishers = NULL;
    _RecordsetPtr rstPublishersCountry = NULL;

    //Define Other Variables
    HRESULT hr = S_OK;
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");
    int intPublisherCount = 0;
    long recCount = 0;
    _bstr_t strCountry;
    _bstr_t strMessage;
    char *tempStr;
    CHAR sz_CountryName[50];
    bool boolFlag = TRUE;
    try
    {
        // Open recordset with data from Publishers table.
        rstPublishers.CreateInstance(__uuidof(Recordset));
        rstPublishersCountry.CreateInstance(__uuidof(Recordset));

        rstPublishers->CursorType = adOpenStatic;

        TESTHR(rstPublishers->Open("publishers",strCnn,
             adOpenStatic , adLockReadOnly,adCmdTable));

        // Populate the Recordset.
        intPublisherCount = rstPublishers->RecordCount;

        // Get user input.
        printf("Enter a country to filter on:");
        mygets(sz_CountryName, 50);

        // Trim the string
        tempStr = strtok(sz_CountryName, "  \t");
        strCountry = tempStr;
        if (tempStr == NULL)
        {
            boolFlag = FALSE;
        }

        if (boolFlag)
        {
            if (strcmp(sz_CountryName,""))
            {
                // Open a filtered Recordset object.
                rstPublishersCountry = FilterField(rstPublishers,
                    "Country", strCountry);
                recCount = rstPublishersCountry->GetRecordCount();
                if (recCount==0)
                {
                    printf("\nNo publishers from that country.\n");
                }
                else
                {
                    // Print number of records for the original
                    // Recordset object and the filtered Recordset
                    // object.
                    printf("\nOrders in original recordset:\n%d",
                        intPublisherCount);
                    printf("\nOrders in filtered recordset "
                        "(Country = '%s'): \n%d\n\n", (LPCSTR)strCountry ,
                        rstPublishersCountry->RecordCount);
                }
            }
        }
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _variant_t vtConnect = rstPublishers->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    if (rstPublishers)
        if (rstPublishers->State == adStateOpen)
            rstPublishers->Close();
    if (rstPublishersCountry)
        if (rstPublishersCountry->State == adStateOpen)
            rstPublishersCountry->Close();
}

_RecordsetPtr FilterField(_RecordsetPtr rstTemp,_bstr_t strField,
    _bstr_t strFilter)
{
        // Set a filter on the specified Recordset object and then
        // open a new Recordset object.
        rstTemp->Filter  = strField + " = '" + strFilter + "'";
        return rstTemp;
}

void FilterX2(void)
{
    _RecordsetPtr rstPublishers;
    CPublishers publishers;

    //Define Other Variables
    HRESULT hr = S_OK;
    IADORecordBinding   *picRs = NULL;  //Interface Pointer declared...

    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");
    try
    {
        // Open recordset with data from Publishers table.
        rstPublishers.CreateInstance(__uuidof(Recordset));

        rstPublishers->CursorType = adOpenStatic;

        TESTHR(rstPublishers->Open("SELECT * FROM publishers WHERE "
            "Country='USA'",strCnn,adOpenStatic,adLockReadOnly,
            adCmdText));

        //Open an IADORecordBinding interface pointer
        //which we'll use for Binding Recordset to a class
        TESTHR(rstPublishers->QueryInterface(
            __uuidof(IADORecordBinding), (LPVOID*)&picRs));

        //Bind the Recordset to a C++ Class here
        TESTHR(picRs->BindToRecordset(&publishers));

        // Print current data in recordset.
        rstPublishers->MoveFirst();

        while (!rstPublishers->EndOfFile)
        {
            printf("%s, %s\n",
                publishers.lP_pubnameStatus == adFldOK ?
                publishers.m_szP_pubname: "<NULL>",
                publishers.lP_countryStatus == adFldOK ?
                publishers.m_szP_country: "<NULL>");

            rstPublishers->MoveNext();
        }
    }
    catch (_com_error &e)
    {
        // Notify the user of errors if any.
        _variant_t vtConnect = rstPublishers->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (rstPublishers)
        if (rstPublishers->State == adStateOpen)
            rstPublishers->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pCnn1)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr  pErr  = NULL;

    if( (pCnn1->Errors->Count) > 0)
    {
        long nCount = pCnn1->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pCnn1->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
    printf("Error\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    printf("\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndFilterCpp

FilterX.h

// BeginFilterH
#include "icrsint.h"

//This Class extracts only Pub Name and Country Name.
class CPublishers : public CADORecordBinding
{
BEGIN_ADO_BINDING(CPublishers)

    //Column Pub Name is the 2nd field in the recordset
    ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_szP_pubname,
         sizeof(m_szP_pubname), lP_pubnameStatus, TRUE)

    //Column Country Name is the 5th field in the recordset
    ADO_VARIABLE_LENGTH_ENTRY2(5, adVarChar, m_szP_country ,
        sizeof(m_szP_country), lP_countryStatus, TRUE)

END_ADO_BINDING()

public:
    CHAR    m_szP_pubname[50];
    ULONG   lP_pubnameStatus;
    CHAR    m_szP_country[50];
    ULONG   lP_countryStatus;
};
// EndFilterH

请参阅

Filter 属性 | RecordCount 属性 | Recordset 对象


Find 方法范例 (VC++)

本范例使用 Recordset 对象的 Find 方法对 Pubs 数据库中的业务标题数进行定位和计数。范例中假设基本提供者不支持相似的功能。

// BeginFindCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>
#include "FindX.h"

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void FindX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

//////////////////////////////////////////////////////////
//                                                      //
//      Main Function                                   //
//                                                      //
//////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    FindX();

    //Wait here for the user to see the output.
    printf("Press any key to continue...");
    getch();
    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//             FindX Function                           //
//                                                      //
//////////////////////////////////////////////////////////

void FindX(void)
{
    HRESULT    hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _ConnectionPtr    pConnection  = NULL;
    _RecordsetPtr     pRstTitles   = NULL;
    IADORecordBinding   *picRs     = NULL;  //Interface Pointer declared.
    CTitlesRs titlers;                      //C++ class object

    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        // Open connection.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        pConnection->Open (strCnn, "", "", adConnectUnspecified);

        // Open title Table
        TESTHR(pRstTitles.CreateInstance(__uuidof(Recordset)));

        pRstTitles->Open("SELECT title_id FROM titles",
            _variant_t((IDispatch *)pConnection),
            adOpenStatic, adLockReadOnly, adCmdText);

        // The default parameters are sufficient to search forward
        // through a Recordset.

        pRstTitles->Find ("title_id LIKE 'BU%'",0,adSearchForward,"");

        //Open an IADORecordBinding interface pointer which
        //we'll use for Binding Recordset to a class
        TESTHR(pRstTitles->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        //Bind the Recordset to a C++ Class here
        TESTHR(picRs->BindToRecordset(&titlers));

        // Skip the current record to avoid finding the same
        // row repeatedly. The bookmark is redundant because Find
        // searches from the current position.
        int count = 0;

        //Continue if last find succeeded.
        while (!(pRstTitles->EndOfFile))
        {
            printf("Title ID: %s\n",titlers.lt_titleidStatus == adFldOK ?
                titlers.m_szt_titleid : "<NULL>");
            count++;                       //Count the last title found.

            _variant_t mark = pRstTitles->Bookmark;  //Note current pos.
            pRstTitles->Find("title_id LIKE 'BU%'", 1, adSearchForward,
                mark);
        }
        printf("The number of business titles is %d\n",count);
    }
    catch(_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
       PrintProviderError(pConnection);
       PrintComError(e);
    }

    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (pRstTitles)
        if (pRstTitles->State == adStateOpen)
            pRstTitles->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

//////////////////////////////////////////////////////////
//                                                      //
//       PrintProviderError Function                    //
//                                                      //
//////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                (LPCSTR)pErr->Description);
        }
    }
}

//////////////////////////////////////////////////////////
//                                                      //
//       PrintComError Function                         //
//                                                      //
//////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndFindCpp

FindX.h

// BeginFindH
#include "icrsint.h"

//This Class extracts only titleId from Titles table.
class CTitlesRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CTitlesRs)

    // Column title_id is the 1st field in the recordset
    // from Titles table.
    ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_szt_titleid,
         sizeof(m_szt_titleid), lt_titleidStatus, FALSE)

END_ADO_BINDING()

public:
   CHAR   m_szt_titleid[150];
   ULONG   lt_titleidStatus;
};
// EndFindH

请参阅

Find 方法 | Recordset 对象


GetRows 方法范例 (VC++)

本范例使用 GetRows 方法从 Recordset 中检索指定数目的行，并将结果数据填充到数组。在两种情况下 GetRows 方法返回的行数将少于所需的数目：一种情况是因为达到了 EOF，另一种情况是因为 GetRows 试图检索其他用户删除的记录。仅在发生第二种情况时，该函数才返回 False。运行此过程需要 GetRowsOK 函数。

// BeginGetRowsCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <stdio.h>
#include <ole2.h>
#include <conio.h>

// Function Declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void GetRowsX(void);
bool GetRowsOK(_RecordsetPtr pRstTemp,int intNumber,
        _variant_t& avarData);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

     GetRowsX();

    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      GetRowsX Function                                //
//                                                       //
///////////////////////////////////////////////////////////

void GetRowsX(void)
{
    HRESULT hr = S_OK;

    // Define string variables.
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr pRstEmployees = NULL;

    try
    {
        // Open recordset with names and hire dates from employee table.
        TESTHR(pRstEmployees.CreateInstance(__uuidof(Recordset)));

        pRstEmployees->Open("SELECT fName, lName, hire_date "
            "FROM Employee ORDER BY lName",strCnn,
            adOpenStatic, adLockReadOnly,adCmdText);

        while (true) //continuous loop
        {
            int intLines = 0;

            // Get user input for number of rows.
            printf("\nEnter number of rows to retrieve (0 to exit): ");
            int intRows;
            scanf("%d", &intRows);

            if (intRows <= 0)
                break;

            //Clear the screen for the next display
            system("cls");

            // If GetRowsOK is successful, print the results,
            // noting if the end of the file was reached.
            _variant_t avarRecords;

            if (GetRowsOK(pRstEmployees, intRows, avarRecords))
            {
                long lUbound;
                HRESULT hr = SafeArrayGetUBound(avarRecords.parray,
                    2,&lUbound);

                if (hr == 0)
                {
                    if (intRows > lUbound + 1)
                    {
                        printf("\n(Not enough records in Recordset to "
                            "retrieve %d rows)\n", intRows);
                    }
                }
                printf("%d records found.", lUbound+1);

                // Print the retrieved data.
                for (int intRecords = 0;intRecords < lUbound+1;
                     intRecords++)
                {
                    printf("\n ");

                    long rgIndices[2];
                    rgIndices[0] = 0;
                    rgIndices[1] = intRecords;
                    _variant_t result;
                    result.vt = VT_BSTR;

                    hr= SafeArrayGetElement(avarRecords.parray,
                        rgIndices, &result);

                    if (hr == 0){printf("%s ",(LPCSTR)(_bstr_t)result);}

                    rgIndices[0] = 1;

                    hr= SafeArrayGetElement(avarRecords.parray,
                        rgIndices, &result);

                    if (hr == 0){printf("%s, ",(LPCSTR)(_bstr_t)result);}

                    rgIndices[0] = 2;

                    hr= SafeArrayGetElement(avarRecords.parray,
                        rgIndices, &result);

                    if (hr == 0){printf("%s",(LPCSTR)(_bstr_t)result);}

                    intLines ++;

                    if (intLines % 10 == 0)
                    {
                        printf("\nPress any key to continue...");
                        getch();

                        intLines = 0;

                        //Clear the screen for the next display
                        system("cls");
                    }
                }
            }
            else
            {
                // Assuming the GetRows error was due to data
                // changes by another user, use Requery to
                // refresh the Recordset and start over.
                printf("GetRows failed--retry?\n");
                char chKey;
                do
                {
                    chKey = getch();
                }while(toupper(chKey) != 'Y'  && toupper(chKey) != 'N');

                if(toupper(chKey) == 'Y')
                {
                    pRstEmployees->Requery(adOptionUnspecified);
                }
                else
                {
                    printf("GetRows failed!\n");
                    break;
                }
            }

            // Because using GetRows leaves the current
            // record pointer at the last record accessed,
            // move the pointer back to the beginning of the
            // Recordset before looping back for another search.
            pRstEmployees->MoveFirst();
        }
    }
    catch(_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstEmployees->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    //Clean up objects before exit.
    if (pRstEmployees)
        if (pRstEmployees->State == adStateOpen)
            pRstEmployees->Close();
}

bool GetRowsOK(_RecordsetPtr pRstTemp,int intNumber,
        _variant_t& avarData)
{
    // Store results of GetRows method in array.
    avarData = pRstTemp->GetRows(intNumber);

    // Return False only if fewer than the desired
    // number of rows were returned, but not because the
    // end of the Recordset was reached.
    long lUbound;
    HRESULT hr = SafeArrayGetUBound(avarData.parray,2,&lUbound);
    if (hr == 0)
    {
        if ((intNumber > lUbound + 1) && (!(pRstTemp->EndOfFile)))
            return false;
        else
            return true;
    }
    else
    {
        printf ("\nUnable to Get the Array's Upper Bound\n");
        return false;
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr  pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndGetRowsCpp

请参阅

BOF、EOF 属性 | GetRows 方法 | Recordset 对象


GetString 方法范例 (VC++)

本范例演示 GetString 方法。

假设用户要调试数据访问问题，并且想用一种快速便捷的方式打印小型 Recordset 的当前内容。

// BeginGetStringCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void GetStringX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

//////////////////////////////////////////////////////////
//                                                      //
//      Main Function                                   //
//                                                      //
//////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    GetStringX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//          GetStringX Function                         //
//                                                      //
//////////////////////////////////////////////////////////

void GetStringX(void)
{
    HRESULT  hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
   _ConnectionPtr  pConnection   = NULL;
   _RecordsetPtr   pRstAuthors   = NULL;

    // Define string variables.
    _bstr_t strCnn("Provider='sqloledb';Data Source='localhost';"
            "Initial Catalog='Northwind';Integrated Security='SSPI';");
    _bstr_t varOutput;
    char *strPrompt = "Enter a state (CA, IN, KS, MD, MI, OR, TN, UT): ";
    char strState[2], *pState;

    try
    {
       // Open connection.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));

        // Open a command object for a stored procedure,
        // with one parameter.
        TESTHR(pRstAuthors.CreateInstance(__uuidof(Recordset)));

        printf("%s",strPrompt);
        gets(strState);

        pState = strtok(strState," \t");

        char strQry[100] = "SELECT au_fname, au_lname, address, city "
            "FROM authors WHERE state = ";

        strcat(strQry,"'");
        strcat(strQry,pState);
        strcat(strQry,"'");

        _bstr_t strQuery(strQry);

        pConnection->Open (strCnn, "", "", adConnectUnspecified);

        pRstAuthors->Open(strQuery, _variant_t((IDispatch*)pConnection,
            true),
        adOpenStatic, adLockReadOnly, adCmdText);

        if (pRstAuthors->RecordCount > 0)
        {
            // Use all defaults: get all rows, TAB column delimiter,
            // CARRIAGE RETURN row delimiter, empty-string null delimiter
            long lRecCount =  pRstAuthors->RecordCount;
            _bstr_t varTab("\t");
            _bstr_t varRet("\r");
            _bstr_t varNull("");
            varOutput = pRstAuthors->GetString(adClipString,lRecCount,
                varTab,varRet,varNull);
            printf("State = '%s'\n", strState);
            printf ("Name               Address               City\n");
            printf ("%s\n", (LPCTSTR)varOutput);
        }
        else
        {
            printf("\nNo rows found for state = '%s'\n",pState);
        }
        // Clean up objects before exit.
        pRstAuthors->Close();
        pConnection->Close();
   }

   catch(_com_error &e)
   {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
       PrintProviderError(pConnection);
       PrintComError(e);
   }
}

//////////////////////////////////////////////////////////
//                                                      //
//        PrintProviderError Function                   //
//                                                      //
//////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr   pErr = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                pErr->Description);
        }
    }
}

//////////////////////////////////////////////////////////
//                                                      //
//      PrintComError Function                          //
//                                                      //
//////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);

}
// EndGetStringCpp

请参阅

GetString 方法 | Recordset 对象


IsolationLevel 和 Mode 属性范例 (VC++)

本范例使用 Mode 属性打开独占连接，使用 IsolationLevel 属性打开独立于其他事务执行的事务。

// BeginIsolationLevelCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll"\
    no_namespace rename("EOF","EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>
#include "IsolationLevelX.h"

// Function Declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void IsolationLevelX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

/////////////////////////////////////////////////////////////////
//                                                             //
//                                                             //
//                        Main Function                        //
//                                                             //
//                                                             //
/////////////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    IsolationLevelX();

    printf("Press any key to continue...");
    getch();
    ::CoUninitialize();
}

/////////////////////////////////////////////////////////////////
//                                                             //
//      IsolationLevelX()  Function                            //
//                                                             //
/////////////////////////////////////////////////////////////////

void IsolationLevelX(void)
{
    // Define ADO ObjectPointers
    // Initialize Pointers on define
    // These are in the ADODB :: namespace
    _RecordsetPtr  pRstTitles  = NULL;
    _ConnectionPtr pConnection = NULL;

    // Define other Variables
    HRESULT hr = S_OK;
    IADORecordBinding *picRs  = NULL;  // Interface Pointer Declared
    CTitleRs titlers;                  // C++ Class Object
    LPSTR p_TempStr = NULL;

    //Assign Connection String to Variable
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
                    "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        // Open Connection and Titles Table
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        pConnection->Mode = adModeShareExclusive;
        pConnection->IsolationLevel = adXactIsolated;
        pConnection->Open(strCnn,"","",adConnectUnspecified);

        TESTHR(pRstTitles.CreateInstance(__uuidof(Recordset)));
        pRstTitles->CursorType = adOpenDynamic;
        pRstTitles->LockType = adLockPessimistic;

        pRstTitles->Open("titles",_variant_t((IDispatch*) pConnection,
            true),adOpenDynamic,adLockPessimistic,adCmdTable);

        pConnection->BeginTrans();

        // Display Connection Mode
        if(pConnection->Mode == adModeShareExclusive)
        {
            printf("Connection Mode Is Exclusive");
        }
        else
        {
            printf("Connection Mode Is Not Exclusive");
        }

        // Display Isolation Level
        if(pConnection->IsolationLevel == adXactIsolated)
        {
            printf("\n\nTransaction is Isolated");
            printf("\n\nPress any key to continue...\n\n");
            getch();
        }
        else
        {
            printf("\n\nTransaction is not Isolated");
            printf("\n\nPress any key to continue...\n\n");
            getch();
        }

        // Open an IADORecordBinding interface pointer which
        // we will use for binding Recordset to a class
        TESTHR(pRstTitles->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        // Bind the Recordset to a C++ class here
        TESTHR(picRs->BindToRecordset(&titlers));

        // Change the type of psychology titles.
        p_TempStr = (LPSTR) malloc(sizeof(titlers.m_szau_Type));

        while (!(pRstTitles->EndOfFile))
        {
            // Set the final character of the destination string to NULL.
            p_TempStr[sizeof(titlers.m_szau_Type)-1] = '\0';
            // The source string will get truncated if its length is
            // longer than the length of the destination string minus one.
            strncpy(p_TempStr,strtok(titlers.m_szau_Type," "),sizeof(titlers.m_szau_Type)-1);

            // Compare type with psychology
            if (!strcmp(p_TempStr,"psychology"))
            {
                // Set the final character of the destination string to NULL.
                titlers.m_szau_Type[sizeof(titlers.m_szau_Type)-1] = '\0';
                // Copy "self_help" title field
                // The source string will get truncated if its length is
                // longer than the length of the destination string minus one.
                strncpy(titlers.m_szau_Type,"self_help",sizeof(titlers.m_szau_Type)-1);
                picRs->Update(&titlers);
            }
            pRstTitles->MoveNext();
        }
        // Print current data in recordset.
        pRstTitles->Requery(adOptionUnspecified);

        // Open again IADORecordBinding interface pointer for Binding
        // Recordset to a class.
        TESTHR(pRstTitles->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        // ReBinding the Recordset to a C++ Class
        TESTHR(picRs->BindToRecordset(&titlers));

        // Move to the first record of the title table
        pRstTitles->MoveFirst();

        //Clear the screen for the next display
        system("cls");

        while (!pRstTitles->EndOfFile)
        {
            printf("%s -  %s\n",titlers.lau_TitleStatus == adFldOK ?
                titlers.m_szau_Title :"<NULL>",
                titlers.lau_TypeStatus == adFldOK ?
                titlers.m_szau_Type :"<NULL>");
            pRstTitles->MoveNext();
        }
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        PrintProviderError(pConnection);
        PrintComError(e);
    }

    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (pRstTitles)
        if (pRstTitles->State == adStateOpen)
            pRstTitles->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
        {
            // Restore Original Data
            pConnection->RollbackTrans();

            pConnection->Close();
        }

    // Deallocate the memory
    if (p_TempStr)
        free(p_TempStr);
}

/////////////////////////////////////////////////////////////////
//                                                             //
//                  PrintProviderError Function                //
//                                                             //
/////////////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    //Print Provider Errors from Connection object
    //pErr is a record object in the Connection's Error collection
    ErrorPtr    pErr = NULL;

    if((pConnection->Errors->Count)>0)
    {
        long nCount = pConnection->Errors->Count;

        //Collection ranges from 0 to nCount-1
        for(long i = 0;i < nCount;i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error Number :%x \t %s",pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
    printf("Error\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    printf("\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndIsolationLevelCpp

IsolationLevelX.h

// BeginIsolationLevelH

#include "icrsint.h"

//This class extracts titles and type from Title table

class CTitleRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CTitleRs)
        // Column title is the 2nd field in the table
        ADO_VARIABLE_LENGTH_ENTRY2(2,adVarChar,m_szau_Title,
            sizeof(m_szau_Title),lau_TitleStatus,FALSE)
        // Column type is the 3rd field in the table
        ADO_VARIABLE_LENGTH_ENTRY2(3,adVarChar,m_szau_Type,
            sizeof(m_szau_Type),lau_TypeStatus,TRUE)
END_ADO_BINDING()

public:
    CHAR  m_szau_Title[81];
    ULONG lau_TitleStatus;
    CHAR  m_szau_Type[13];
    ULONG lau_TypeStatus;
};
// EndIsolationLevelH

请参阅

IsolationLevel 属性 | Mode 属性


Item 属性范例 (VC++)

本范例演示 Item 属性访问集合成员的方式。本范例使用参数化命令打开 Pubs 数据库的 Authors 表。

从 Command 对象的 Parameters 集合中，按索引和名称访问针对数据库发出的命令中的参数。然后按索引和名称从该对象的 Fields 集合访问返回的 Recordset 的字段。

// BeginItemCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void ItemX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

//////////////////////////////////////////////////////////
//                                                      //
//       Main Function                                  //
//                                                      //
//////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

        ItemX();

     //Wait here for the user to see the output
     printf("Press any key to continue...");
     getch();
    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//       ItemX Function                                 //
//                                                      //
//////////////////////////////////////////////////////////

void ItemX(void)
{
    HRESULT  hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
   _ConnectionPtr  pConnection  = NULL;
   _RecordsetPtr   pRst     = NULL;
   _CommandPtr     pCmd     = NULL;
   _ParameterPtr   pPrm     = NULL;
    FieldPtr       pFld     = NULL;

    // Other Variables.
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");
    _variant_t    Column[9];
    _variant_t    vIndex;

    try
    {
       // Open connection.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));

        TESTHR(pRst.CreateInstance(__uuidof(Recordset)));

        TESTHR(pCmd.CreateInstance(__uuidof(Command)));

        //Set the array with the authors table field (column) names
        Column[0] = "au_id";
        Column[1] = "au_lname";
        Column[2] = "au_fname";
        Column[3] = "phone";
        Column[4] = "address";
        Column[5] = "city";
        Column[6] = "state";
        Column[7] = "zip";
        Column[8] = "contract";

        _bstr_t strText("SELECT * FROM authors WHERE state = ?");
        pCmd->CommandText = strText;

        pPrm = pCmd->CreateParameter("ItemXparm", adChar, adParamInput,
            2, "CA");
        pCmd->Parameters->Append(pPrm);

        pConnection->Open(strCnn, "", "", adConnectUnspecified);
        pCmd->ActiveConnection = pConnection;

        // Connection and CommandType are omitted because
        // a Command object is provided.
        _variant_t Conn;
        Conn.vt = VT_ERROR;
        Conn.scode = DISP_E_PARAMNOTFOUND;

        pRst->Open((_variant_t((IDispatch *) pCmd)),Conn,adOpenStatic,
            adLockReadOnly, -1);

        printf("The Parameters collection accessed by index...\n");

        vIndex = (short) 0;
        pPrm = pCmd->Parameters->GetItem(&vIndex);
        printf("Parameter name = '%s', value = '%s'\n",
            (LPCSTR)pPrm->Name, (LPSTR)(_bstr_t)pPrm->Value);

        printf("\nThe Parameters collection accessed by name...\n");
        pPrm = pCmd->Parameters->Item["ItemXparm"];
        printf("Parameter name = '%s', value = '%s'\n",
            (LPCSTR)pPrm->Name, (LPSTR)(_bstr_t)pPrm->Value);

        printf("\nThe Fields collection accessed by index...\n");
        pRst->MoveFirst();
        long limit = 0;
        limit = ((pRst->Fields->Count) - 1);
        int intLineCnt = 8;
        for (short iIndex = 0; iIndex <= limit; iIndex++)
        {
            vIndex = iIndex;
            intLineCnt++;
            if (intLineCnt%15 == 0)
            {
                printf("\nPress any key to continue...\n");
                getch();
            }
            pFld = pRst->Fields->GetItem(&vIndex);
            printf("Field %d : Name =  '%s', ", iIndex,
                (LPCSTR)pFld->GetName());
            _variant_t FldVal = pFld->GetValue();

            // Because Value is the default property of a
            // Property object,the use of the actual keyword
            // here is optional.
            switch(FldVal.vt)
            {
                case (VT_BOOL):
                    if(FldVal.boolVal)
                    {
                        printf("Value = 'True'");
                    }
                    else
                    {
                        printf("Value = 'False'");
                    }
                    printf("\n");
                    break;
                case (VT_BSTR):
                    printf("Value = '%s'",
                        (LPCSTR)(_bstr_t)FldVal.bstrVal);
                    printf("\n");
                    break;
                case (VT_I4):
                    printf("Value = '%s'",(LPCSTR)FldVal.iVal);
                    printf("\n");
                    break;
                case (VT_EMPTY):
                    printf("Value = '%s'",(LPCSTR)FldVal.lVal);
                    printf("\n");
                    break;
                default:
                    break;
            }
        }

        printf("\nThe Fields collection accessed by name...\n");
        pRst->MoveFirst();
        for (iIndex = 0; iIndex <= 8; iIndex++)
        {
            intLineCnt++;
            if (intLineCnt%15 == 0)
            {
                printf("\nPress any key to continue...\n");
                getch();
            }
            pFld = pRst->Fields->GetItem(Column[iIndex]);
            printf("Field name = '%s', ",(LPCSTR)pFld->GetName());
            _variant_t FldVal = pFld->GetValue();

            // Because Value is the default property of a
            // Property object,the use of the actual keyword
            // here is optional.
            switch(FldVal.vt)
            {
                case (VT_BOOL):
                    if(FldVal.boolVal)
                    {
                        printf("Value = 'True'");
                    }
                    else
                    {
                        printf("Value = 'False'");
                    }
                    printf("\n");
                    break;
                case (VT_BSTR):
                    printf("Value = '%s'",
                        (LPCSTR)(_bstr_t)FldVal.bstrVal);
                    printf("\n");
                    break;
                case (VT_I4):
                    printf("Value = '%s'",(LPCSTR)FldVal.iVal);
                    printf("\n");
                    break;
                case (VT_EMPTY):
                    printf("Value = '%s'",(LPCSTR)FldVal.lVal);
                    printf("\n");
                    break;
                default:
                    break;
            }
        }
    }
    catch(_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
       PrintProviderError(pConnection);
       PrintComError(e);
    }

    // Clean up objects before exit.
    if (pRst)
        if (pRst->State == adStateOpen)
            pRst->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

//////////////////////////////////////////////////////////
//                                                      //
//      PrintProviderError Function                     //
//                                                      //
//////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                pErr->Description);
        }
    }
}

//////////////////////////////////////////////////////////
//                                                      //
//       PrintComError Function                         //
//                                                      //
//////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndItemCpp

请参阅

Command 对象 | Fields 集合 | Item 属性 | Parameters 集合 | Recordset 对象


MarshalOptions 属性范例 (VC++)

本范例使用 MarshalOptions 属性指定发送回服务器的行（所有行或已修改的行）。

// BeginMarshalOptionsCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <stdio.h>
#include <ole2.h>
#include <conio.h>
#include <malloc.h>
#include "MarshalOptionsX.h"

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void MarshalOptionsX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////////////////
//                                                       //
//               Main Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

      MarshalOptionsX();

    printf("Press any key to continue...");
    getch();
    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      Marshal Options Function                         //
//                                                       //
///////////////////////////////////////////////////////////

void   MarshalOptionsX(void)
{

    // Define string variables
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace
    _RecordsetPtr pRstEmployees = NULL;

    // Define Other Variables
    IADORecordBinding   *picRs  = NULL;  //Interface Pointer declared
    CEmployeeRs emprs;               //C++ Class Object
    HRESULT hr = S_OK;
    LPSTR strOldFirst = NULL;
    LPSTR strOldLast = NULL;

    try
    {
        // Open recordset with names from Employee table.
        TESTHR(pRstEmployees.CreateInstance(__uuidof(Recordset)));
        pRstEmployees->CursorType = adOpenKeyset;
        pRstEmployees->LockType = adLockOptimistic;
        pRstEmployees->CursorLocation = adUseClient;
        pRstEmployees->Open("SELECT fname, lname FROM Employee "
            "ORDER BY lname",strCnn,
            adOpenKeyset, adLockOptimistic,adCmdText);

        // Open an IADORecordBinding interface pointer which
        // we'll use for Binding Recordset to a class.
        TESTHR(pRstEmployees->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        // Bind the Recordset to a C++ Class here.
        TESTHR(picRs->BindToRecordset(&emprs));

        // Store Original Data
        strOldFirst = (LPSTR) malloc(sizeof(emprs.m_szemp_fname));
        strOldLast  = (LPSTR) malloc(sizeof(emprs.m_szemp_lname));
        // Set the final character of the destination string to NULL.
        strOldFirst[sizeof(emprs.m_szemp_fname)-1] = '\0';
        // The source string will get truncated if its length is
        // longer than the length of the destination string minus one.
        strncpy(strOldFirst,strtok(emprs.m_szemp_fname," "),
            sizeof(emprs.m_szemp_fname)-1);
        // Set the final character of the destination string to NULL.
        strOldLast[sizeof(emprs.m_szemp_lname)-1] = '\0';
        // The source string will get truncated if its length is
        // longer than the length of the destination string minus one.
        strncpy(strOldLast,strtok(emprs.m_szemp_lname," "),
            sizeof(emprs.m_szemp_lname)-1);

        //Change Data in Edit Buffer
        // Set the final character of the destination string to NULL.
        emprs.m_szemp_fname[sizeof(emprs.m_szemp_fname)-1] = '\0';
        // The source string will get truncated if its length is
        // longer than the length of the destination string minus one.
        strncpy(emprs.m_szemp_fname,"Linda",sizeof(emprs.m_szemp_fname)-1);
        // Set the final character of the destination string to NULL.
        emprs.m_szemp_lname[sizeof(emprs.m_szemp_lname)-1] = '\0';
        // The source string will get truncated if its length is
        // longer than the length of the destination string minus one.
        strncpy(emprs.m_szemp_lname,"Kobara",sizeof(emprs.m_szemp_lname)-1);

        // Show contents of buffer and get user input
        printf("Edit in Progress:\n");
        printf("Original Data = %s  %s \n",strOldFirst,strOldLast);
        printf("Data in buffer = %s  %s \n", emprs.lemp_fnameStatus ==
            adFldOK ? emprs.m_szemp_fname : "<NULL>",
            emprs.lemp_lnameStatus == adFldOK ?
            emprs.m_szemp_lname : "<NULL>");
        printf("Use Update to replace the original data with the "
            "buffered data in the Recordset?\nEnter (y/n) :?");
        char opt1=getch();

        if(toupper(opt1)=='Y')
        {
                printf("\nWould you like to send all the rows in "
                    "the recordset back to the server?\nEnter (y/n):");
                char opt2 = getch();
                if(toupper(opt2) == 'Y')
                {
                    {
                        pRstEmployees->MarshalOptions = adMarshalAll;
                        picRs->Update(&emprs);
                    }
                }
                else
                {
                    printf("\nWould you like to send only modified "
                        "rows back to the server?\nEnter (y/n):");
                    char opt3=getch();
                    if(toupper(opt3) == 'Y')
                        {
                            pRstEmployees->MarshalOptions =
                                adMarshalModifiedOnly;
                            picRs->Update(&emprs);
                        }
                }
        }
        // Show the resulting data
        printf("\nData In the Recordset = %s  %s\n",
            emprs.lemp_fnameStatus == adFldOK ?
            emprs.m_szemp_fname : "<NULL>",
            emprs.lemp_lnameStatus == adFldOK ?
            emprs.m_szemp_lname : "<NULL>");

        // Restore original data because this is a demonstration
        if((strcmp(strOldFirst,emprs.m_szemp_fname)) &&
           (strcmp(strOldLast,emprs.m_szemp_lname)))
        {
            // Set the final character of the destination string to NULL.
            emprs.m_szemp_fname[sizeof(emprs.m_szemp_fname)-1] = '\0';
            // The source string will get truncated if its length is
            // longer than the length of the destination string minus one.
            strncpy(emprs.m_szemp_fname,strOldFirst,
                sizeof(emprs.m_szemp_fname)-1);
            // Set the final character of the destination string to NULL.
            emprs.m_szemp_lname[sizeof(emprs.m_szemp_lname)-1] = '\0';
            // The source string will get truncated if its length is
            // longer than the length of the destination string minus one.
            strncpy(emprs.m_szemp_lname,strOldLast,
                sizeof(emprs.m_szemp_lname)-1);
            picRs->Update(&emprs);
        }
    }
    catch(_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstEmployees->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    // Deallocate memory
    if (strOldFirst)
        free(strOldFirst);
    if (strOldLast)
        free(strOldLast);

    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (pRstEmployees)
        if (pRstEmployees->State == adStateOpen)
            pRstEmployees->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr     pErr   = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

     // Print Com errors.
    printf("Error\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    printf("\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndMarshalOptionsCpp

MarshalOptionsX.h

// BeginMarshalOptionsH

#include "icrsint.h"

//This Class extracts only fname,lname from employees table
class CEmployeeRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CEmployeeRs)

    //Column fname is the 1st field in the recordset
    ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_szemp_fname,
         sizeof(m_szemp_fname), lemp_fnameStatus, TRUE)

     //Column lname is the 2nd field in the recordset
    ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_szemp_lname,
         sizeof(m_szemp_lname), lemp_lnameStatus, TRUE)

END_ADO_BINDING()

public:
   CHAR   m_szemp_fname[21];
   ULONG   lemp_fnameStatus;
   CHAR   m_szemp_lname[31];
   ULONG   lemp_lnameStatus;
};
// EndMarshalOptionsH

请参阅

MarshalOptions 属性


MaxRecords 属性范例 (VC++)

本范例使用 MaxRecords 属性打开包含 Titles 表中 10 个最有价值标题的 Recordset。

// BeginMaxRecordsCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll"\
    no_namespace rename("EOF","EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>
#include "MaxRecordsX.h"

// Function Declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void MaxRecordsX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

//////////////////////////////////////////////////////////////
//                                                          //
//                        Main Function                     //
//                                                          //
//////////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    MaxRecordsX();

    printf("Press any key to continue...");
    getch();
    ::CoUninitialize();
}

//   MaxRecordsX()  Function
void  MaxRecordsX(void)
{
    // Define ADO ObjectPointers
    // Initialize Pointers on define
    // These are in the ADODB :: namespace
    _RecordsetPtr pRstTemp    = NULL;

    // Define Other Variables
    IADORecordBinding *picRs  = NULL;   // Interface Pointer Declared
    CTitleRs titlers;            // C++ Class Object
    HRESULT hr = S_OK;

    try
    {
        //Assign Connection String to Variable
        _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
                    "Initial Catalog='pubs';Integrated Security='SSPI';");

        // Open Recordset containing the 10 most expensive titles in the
        // Titles table.
        TESTHR(pRstTemp.CreateInstance(__uuidof(Recordset)));

        pRstTemp->MaxRecords=10;

        pRstTemp->Open("SELECT title,price FROM Titles "
            "ORDER BY Price DESC",strCnn,adOpenForwardOnly,
            adLockReadOnly,adCmdText);

        // Open an IADORecordBinding interface pointer which
        // we will use for binding Recordset to a class
        TESTHR(pRstTemp->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        // Bind the Recordset to a C++ class here
        TESTHR(picRs->BindToRecordset(&titlers));

        // Display the contents of the Recordset
        printf("Top Ten Titles by Price:\n\n");

        while(!(pRstTemp->EndOfFile))
        {
            printf("%s ---  %6.2lf\n\n",titlers.lau_TitleStatus ==
                adFldOK ? titlers.m_szau_Title : "<NULL>",
                    titlers.lau_PriceStatus == adFldOK ?
                    titlers.m_szau_Price : 0.00);
            pRstTemp->MoveNext();
        }
    }
    catch(_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstTemp->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (pRstTemp)
        if (pRstTemp->State == adStateOpen)
            pRstTemp->Close();
};

//////////////////////////////////////////////////////////////
//                                                          //
//                  PrintProviderError Function             //
//                                                          //
//////////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    //Print Provider Errors from Connection object
    //pErr is a record object in the Connection's Error collection
    ErrorPtr    pErr = NULL;

    if((pConnection->Errors->Count)>0)
    {
        long nCount = pConnection->Errors->Count;

        //Collection ranges from 0 to nCount-1
        for(long i = 0;i < nCount;i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error Number :%x \t %s",pErr->Number,
                pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

    // Print Com errors.
    printf("Error\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    printf("\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndMaxRecordsCpp

请参阅

MaxRecords 属性 | Recordset 对象


Move 方法范例 (VC++)

本范例使用 Move 方法按用户输入定位记录指针。

// BeginMoveCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <stdio.h>
#include <ole2.h>
#include <stdlib.h>
#include <conio.h>
#include "MoveX.h"

// Function Declaration.
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void MoveX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);
inline char* mygets(char* strDest, int n)
{
    char strExBuff[10];
    char* pstrRet = fgets(strDest, n, stdin);

    if (pstrRet == NULL)
        return NULL;

    if (!strrchr(strDest, '\n'))
        // Exhaust the input buffer.
        do
        {
            fgets(strExBuff, sizeof(strExBuff), stdin);
        }while (!strrchr(strExBuff, '\n'));
    else
        // Replace '\n' with '\0'
        strDest[strrchr(strDest, '\n') - strDest] = '\0';

    return pstrRet;
}

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

     MoveX();

     ::CoUninitialize();
}

//////////////////////////////////////////////////
//                                              //
//      MoveX Function                          //
//                                              //
//////////////////////////////////////////////////

void MoveX(void)
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr  pRstAuthors    = NULL;

    // Define Other Variables
    IADORecordBinding   *picRs = NULL;  //Interface Pointer declared
    CAuthorsRs    authorsrs;         //C++ class object
    HRESULT hr = S_OK;

    // Open Authors table
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        // Open recordset from Authors table.
        TESTHR(pRstAuthors.CreateInstance(__uuidof(Recordset)));

        pRstAuthors->CursorType = adOpenStatic;
        // Use client cursor to allow use of AbsolutePosition property.
        pRstAuthors->CursorLocation = adUseClient;

        pRstAuthors->Open("SELECT au_id, au_fname, au_lname, city, "
            "state FROM Authors ORDER BY au_lname", strCnn, adOpenStatic,
            adLockReadOnly, adCmdText);

        // Open an IADORecordBinding interface pointer which we'll use
        // for Binding Recordset to a class.
        TESTHR(pRstAuthors->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        // Bind the Recordset to a C++ Class here.
        TESTHR(picRs->BindToRecordset(&authorsrs));

        pRstAuthors->MoveFirst();

        char *strMove;
        char strTemp[5];
        while(true)
        {
            // Display information about current record and ask how many
            // records to move.
            printf("Record %ld of %d\n", pRstAuthors->AbsolutePosition,
                pRstAuthors->RecordCount);
            printf("Author: %s %s\n",
                authorsrs.lemp_fnameStatus == adFldOK ?
                authorsrs.m_au_fname : "<NULL>",
                authorsrs.lemp_lnameStatus == adFldOK ?
                authorsrs.m_au_lname : "<NULL>");
            printf("Location: %s, %s\n\n",
                authorsrs.lemp_cityStatus == adFldOK ?
                authorsrs.m_au_city : "<NULL>",
                authorsrs.lemp_stateStatus == adFldOK ?
                authorsrs.m_au_state : "<NULL>");

            printf("Enter number of records to Move "
                "\n(positive or negative, Enter to quit): ");
            mygets(strTemp, 5);

            strMove = strtok(strTemp," \t");

            if (strMove == NULL)
                break;

            // if the input is not numeric then notify the user.
            if(!atol(strMove))
            {
                printf("Expecting numeric value...\n");
                continue;
            }

            // Store bookmark in case the Move goes too far
            // forward or backward.
            _variant_t varBookmark = pRstAuthors->Bookmark;

            // Move method requires parameter of data type Long.
            long lngMove = atol(strMove);

            pRstAuthors->Move(lngMove);

            // Trap for BOF or EOF.
            if(pRstAuthors->BOF)
            {
                printf("Too far backward! Returning to current"
                    " record.\n");
                pRstAuthors->Bookmark = varBookmark;
            }

            if(pRstAuthors->EndOfFile)
            {
                printf("Too far forward! Returning to current"
                    " record.\n");
                pRstAuthors->Bookmark = varBookmark;
            }
        }
    }
    catch(_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstAuthors->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (pRstAuthors)
        if (pRstAuthors->State == adStateOpen)
            pRstAuthors->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr  pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                 (LPCSTR) pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndMoveCpp

MoveX.h

// BeginMoveH

#include "icrsint.h"

// This Class extracts fname, lname, city and state
// from the "authors" table.

class CAuthorsRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CAuthorsRs)

    // Column au_id is the 1st field in the recordset

    ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_au_fname,
         sizeof(m_au_fname), lemp_fnameStatus, TRUE)

    ADO_VARIABLE_LENGTH_ENTRY2(3, adVarChar, m_au_lname,
         sizeof(m_au_lname), lemp_lnameStatus, TRUE)

    ADO_VARIABLE_LENGTH_ENTRY2(4, adVarChar, m_au_city,
         sizeof(m_au_city), lemp_cityStatus, TRUE)

    ADO_VARIABLE_LENGTH_ENTRY2(5, adChar, m_au_state,
         sizeof(m_au_state), lemp_stateStatus, TRUE)

END_ADO_BINDING()

public:
    char     m_au_fname[21];
    ULONG    lemp_fnameStatus;
    char     m_au_lname[41];
    ULONG    lemp_lnameStatus;
    char     m_au_city[21];
    ULONG    lemp_cityStatus;
    char     m_au_state[3];
    ULONG    lemp_stateStatus;
};

// EndMoveH

请参阅

Move 方法


MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法范例 (VC++)

本范例使用 MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法，按照提供的命令移动 Recordset 的记录指针。运行本范例需要 MoveAny 函数。

// BeginMoveFirstCpp
#include <ole2.h>
#include <stdio.h>

#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void MoveFirstX();
void MoveAny(int intChoice, _RecordsetPtr pRstTemp);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

/////////////////////////////////
//      Main Function          //
/////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    MoveFirstX();

    ::CoUninitialize();
}

//////////////////////////////////////
//      MoveFirstX Function         //
//////////////////////////////////////

void MoveFirstX()
{
    HRESULT    hr = S_OK;
    _RecordsetPtr    pRstAuthors  = NULL;
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");
    _bstr_t strMessage("UPDATE Titles SET Type = "
            "'psychology' WHERE Type = 'self_help'");
    int intCommand = 0;

    // Temporary string variable for type conversion for printing.
    _bstr_t  bstrFName;
    _bstr_t  bstrLName;

    try
    {
        // Open recordset from Authors table.
        TESTHR(pRstAuthors.CreateInstance(__uuidof(Recordset)));
        pRstAuthors->CursorType = adOpenStatic;

        // Use client cursor to enable AbsolutePosition property.
        pRstAuthors->CursorLocation = adUseClient;
        pRstAuthors->Open("Authors", strCnn, adOpenStatic,
            adLockBatchOptimistic, adCmdTable);

        // Show current record information and get user's method choice.
        while (true)  // Continuous loop.
        {
            // Convert variant string to convertable string type.
            bstrFName = pRstAuthors->Fields->Item["au_fName"]->Value;
            bstrLName = pRstAuthors->Fields->Item["au_lName"]->Value;

            printf("Name: %s %s\n Record %d of %d\n\n",
                (LPCSTR) bstrFName,
                (LPCSTR) bstrLName,
                pRstAuthors->AbsolutePosition,
                pRstAuthors->RecordCount);
            printf("[1 - MoveFirst, 2 - MoveLast, \n");
            printf(" 3 - MoveNext, 4 - MovePrevious, 5 - Quit]\n");

            scanf("%d", &intCommand);

            if ((intCommand < 1) || (intCommand > 4))
                break;   // Out of range entry exits program loop.

            // Call method based on user's input.
            MoveAny(intCommand, pRstAuthors);
        }
    }
    catch (_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstAuthors->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    if (pRstAuthors)
        if (pRstAuthors->State == adStateOpen)
            pRstAuthors->Close();
}

/////////////////////////////////
//      MoveAny Function       //
/////////////////////////////////

void MoveAny(int intChoice, _RecordsetPtr pRstTemp)
{
    // Use specified method, trapping for BOF and EOF
    try
    {
        switch(intChoice)
        {
            case 1:
                pRstTemp->MoveFirst();
                break;
            case 2:
                pRstTemp->MoveLast();
                break;
            case 3:
                pRstTemp->MoveNext();
                if (pRstTemp->EndOfFile)
                {
                    printf("\nAlready at end of recordset!\n");
                    pRstTemp->MoveLast();
                }    //End If
                break;
            case 4:
                pRstTemp->MovePrevious();
                if (pRstTemp->BOF)
                {
                    printf("\nAlready at beginning of recordset!\n");
                    pRstTemp->MoveFirst();
                }
                break;
            default:
                ;
        }
    }

    catch(_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstTemp->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }
}

////////////////////////////////////////////
//      PrintProviderError Function       //
////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.

    // pErr is a record object in the Connection's Error collection.
    ErrorPtr  pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount - 1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                pErr->Description);
        }
    }
}

//////////////////////////////////////
//      PrintComError Function      //
//////////////////////////////////////

void PrintComError(_com_error &e)
{
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

    // Print Com errors.
    printf("Error\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    printf("\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndMoveFirstCpp

请参阅

MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法 | Recordset 对象


NextRecordset 方法范例 (VC++)

本范例使用 NextRecordset 方法，查看使用复合命令语句的记录集中的数据，其中的复合命令语句由三个独立 SELECT 语句组成。

// BeginNextRecordsetCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <stdio.h>
#include <ole2.h>
#include <conio.h>
#include <stdlib.h>

//Function Declaration.
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void NextRecordsetX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    NextRecordsetX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////
//                                              //
//      NextRecordsetX Function                 //
//                                              //
//////////////////////////////////////////////////

void NextRecordsetX(void)
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr    pRstCompound = NULL;

    // Define Other Variables
    HRESULT hr = S_OK;
    _variant_t index;
    index.vt = VT_I2;

    // Assign connection string to a variable.
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        // Open recordset from Authors table.
        TESTHR(pRstCompound.CreateInstance(__uuidof(Recordset)));

        // Pass the Cursor type and Lock type to the Recordset.
        pRstCompound->Open("SELECT * FROM authors; SELECT * FROM stores;"
            "SELECT * FROM jobs", strCnn, adOpenForwardOnly,
            adLockReadOnly, adCmdText);

        // Display results from each SELECT statement.
        int intCount = 1;
        while(!(pRstCompound==NULL))
        {
            printf("\n\nContents of recordset #%d\n", intCount);

            while(!pRstCompound->EndOfFile)
            {
                index.iVal = 0;
                printf("%s\t", (LPCSTR)(_bstr_t)pRstCompound->\
                            GetFields()->GetItem(& index)->Value);
                index.iVal = 1;
                printf("%s\n", (LPCSTR)(_bstr_t)pRstCompound->\
                                Fields->GetItem(& index)->Value);

                pRstCompound->MoveNext();

                int intLine = intLine + 1;
                if (intLine % 22 == 0)
                {
                    printf("\nPress any key to continue...");
                    getch();

                    //Clear the screen for the next display.
                    system("cls");
                }
            }
            long    lngRec = 0;
            pRstCompound = pRstCompound->
                NextRecordset((VARIANT *)lngRec);

            printf("\nPress any key to continue...");
            getch();
            intCount = intCount + 1;
        }
    }
    catch(_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstCompound->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    if (pRstCompound)
        if (pRstCompound->State == adStateOpen)
            pRstCompound->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr   = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

    // Print Com errors.
    printf("Error\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    printf("\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndNextRecordsetCpp

请参阅

NextRecordset 方法


NumericScale 和 Precision 属性范例 (VC++)

本范例使用 NumericScale 和 Precision 属性来显示在 Pubs 数据库 Discounts 表中的字段的数值范围和精度。

// BeginNumericScaleCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void NumericScaleX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    NumericScaleX();

    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      NumericScaleX Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void NumericScaleX(void)
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace
    _RecordsetPtr  pRstDiscounts  = NULL;
     FieldsPtr  fldTemp  = NULL;

    //Define Other Variables
    HRESULT  hr = S_OK;
    _variant_t Index;
    Index.vt = VT_I2;

    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
         "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        // Open recordset.
        TESTHR(pRstDiscounts.CreateInstance(__uuidof(Recordset)));
        pRstDiscounts->Open("discounts", strCnn, adOpenForwardOnly,
            adLockReadOnly, adCmdTable);

        // Display numeric scale and precision of
        // numeric and small integer fields.
        fldTemp = pRstDiscounts->GetFields();

        for (int intLoop=0;intLoop < (int)fldTemp->GetCount();intLoop++)
        {
            Index.iVal = intLoop;

            if ((fldTemp->GetItem(Index)->Type == adNumeric)
                || (fldTemp->GetItem(Index)->Type == adSmallInt))
            {
                printf("Field: %s\n" ,(LPCSTR)fldTemp->
                    GetItem(Index)->GetName());
                printf("Numeric scale: %d\n", fldTemp->
                    GetItem(Index)->GetNumericScale());
                printf("Precision: %d\n", fldTemp->
                    GetItem(Index)->GetPrecision());
            }
        }
    }
    catch(_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstDiscounts->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    if (pRstDiscounts)
        if (pRstDiscounts->State == adStateOpen)
            pRstDiscounts->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;

        // Collection ranges from 0 to nCount -1.
        for(long i = 0;i < nCount;i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print COM errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndNumericScaleCpp

请参阅

NumericScale 属性 | Precision 属性


Open 和 Close 方法范例 (VC++)

本范例在已打开的 Recordset 和 Connection 对象上使用 Open 和 Close 方法。

// BeginOpenCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <oledb.h>
#include <stdio.h>
#include <conio.h>
#include "OpenX.h"

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void OpenX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    OpenX();

    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//               OpenX Function                          //
//                                                       //
///////////////////////////////////////////////////////////

void OpenX(void)
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace
     _RecordsetPtr    pRstEmployee  = NULL;
     _ConnectionPtr pConnection    = NULL;

    // Define string variables.
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
        "Initial Catalog='pubs';Integrated Security='SSPI';");

    // Define Other Variables.
    HRESULT  hr = S_OK;
    IADORecordBinding   *picRs  = NULL;  // Interface Pointer declared.
    CEmployeeRs emprs;       // C++ Class object
    DBDATE varDate;

    try
    {
        // open connection and record set
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        pConnection->Open(strCnn,"","",adConnectUnspecified);

        TESTHR(pRstEmployee.CreateInstance(__uuidof(Recordset)));
        pRstEmployee->Open("Employee",
            _variant_t((IDispatch *)pConnection,true), adOpenKeyset,
            adLockOptimistic, adCmdTable);

        // Open an IADORecordBinding interface pointer which we'll
        // use for Binding Recordset to a class.
        TESTHR(pRstEmployee->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        //Bind the Recordset to a C++ Class here.
        TESTHR(picRs->BindToRecordset(&emprs));

        // Assign the first employee record's hire date
        // to a variable, then change the hire date.
        varDate = emprs.m_sze_hiredate;
        printf("\nOriginal data\n");
        printf("\tName - Hire Date\n");
        printf("  %s  %s - %d/%d/%d\n\n",
            emprs.le_fnameStatus == adFldOK ?
            emprs.m_sze_fname : "<NULL>",
            emprs.le_lnameStatus == adFldOK ?
            emprs.m_sze_lname : "<NULL>",
            emprs.le_hiredateStatus == adFldOK ?
            emprs.m_sze_hiredate.month : 0,
            emprs.le_hiredateStatus == adFldOK ?
            emprs.m_sze_hiredate.day : 0,
            emprs.le_hiredateStatus == adFldOK ?
            emprs.m_sze_hiredate.year : 0);

        emprs.m_sze_hiredate.year=1900;
        emprs.m_sze_hiredate.month=1;
        emprs.m_sze_hiredate.day=1;
        picRs->Update(&emprs);

        printf("\nChanged data\n");
        printf("\tName - Hire Date\n");
        printf("  %s %s - %d/%d/%d\n\n",
            emprs.le_fnameStatus == adFldOK ?
            emprs.m_sze_fname : "<NULL>",
            emprs.le_lnameStatus == adFldOK ?
            emprs.m_sze_lname : "<NULL>",
            emprs.le_hiredateStatus == adFldOK ?
            emprs.m_sze_hiredate.month : 0,
            emprs.le_hiredateStatus == adFldOK ?
            emprs.m_sze_hiredate.day : 0,
            emprs.le_hiredateStatus == adFldOK ?
            emprs.m_sze_hiredate.year : 0);

        // Requery Recordset and reset the hire date.
        pRstEmployee->Requery(adOptionUnspecified);
        // Open an IADORecordBinding interface pointer which we'll
        // use for Binding Recordset to a class.
        TESTHR(pRstEmployee->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        // Rebind the Recordset to a C++ Class here.
        TESTHR(picRs->BindToRecordset(&emprs));
        emprs.m_sze_hiredate = varDate;
        picRs->Update(&emprs);
        printf("\nData after reset\n");
        printf("\tName - Hire Date\n");
        printf("  %s %s - %d/%d/%d",emprs.le_fnameStatus == adFldOK ?
            emprs.m_sze_fname : "<NULL>",
            emprs.le_lnameStatus == adFldOK ?
            emprs.m_sze_lname : "<NULL>",
            emprs.le_hiredateStatus == adFldOK ?
            emprs.m_sze_hiredate.month : 0,
            emprs.le_hiredateStatus == adFldOK ?
            emprs.m_sze_hiredate.day : 0,
            emprs.le_hiredateStatus == adFldOK ?
            emprs.m_sze_hiredate.year : 0);
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        // Pass a connection pointer accessed from the Connection.
        PrintProviderError(pConnection);
        PrintComError(e);
    }

    // Clean up objects before exit.
    if (pRstEmployee)
        if (pRstEmployee->State == adStateOpen)
            pRstEmployee->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0;i < nCount;i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print COM errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndOpenCpp

OpenX.h:

// BeginOpenH
#include "icrsint.h"

// This Class extracts only fname,lastname and
// hire_date from employee table
class CEmployeeRs : public CADORecordBinding
{

BEGIN_ADO_BINDING(CEmployeeRs)

    // Column fname is the 2nd field in the table
   ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_sze_fname,
         sizeof(m_sze_fname), le_fnameStatus, FALSE)

    // Column lname is the 4th field in the table.
   ADO_VARIABLE_LENGTH_ENTRY2(4, adVarChar, m_sze_lname,
         sizeof(m_sze_lname), le_lnameStatus, FALSE)

    // Column hiredate is the 8th field in the table.
   ADO_VARIABLE_LENGTH_ENTRY2(8, adDBDate,m_sze_hiredate,
         sizeof(m_sze_hiredate), le_hiredateStatus, TRUE)

END_ADO_BINDING()

public:
   CHAR        m_sze_fname[21];
   ULONG    le_fnameStatus;
   CHAR        m_sze_lname[31];
   ULONG    le_lnameStatus;
   DBDATE    m_sze_hiredate;
   ULONG    le_hiredateStatus;
};
// EndOpenH

请参阅

Close 方法 | Connection 对象 | Open 方法 (ADO Connection) | Open 方法 (ADO Recordset) | Recordset 对象


OpenSchema 方法范例 (VC++)

本范例使用 OpenSchema 方法显示 Pubs 数据库中每个表的名称和类型。

// BeginOpenSchemaCpp
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <oleauto.h>
#include <conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void OpenSchemaX(void);
void OpenSchemaX2(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    OpenSchemaX();

    printf("Press any key to see the results of 2nd "
        "function...\n\n");
    getch();

    OpenSchemaX2();

    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      OpenSchemaX Function                             //
//                                                       //
///////////////////////////////////////////////////////////

void OpenSchemaX()
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _ConnectionPtr  pConnection    = NULL;
    _RecordsetPtr  pRstSchema  = NULL;

    //Other Variables
    HRESULT  hr = S_OK;

    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        // Open connection.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        pConnection->Open (strCnn, "", "", adConnectUnspecified);

        pRstSchema = pConnection->OpenSchema(adSchemaTables);

        while(!(pRstSchema->EndOfFile))
        {
            _bstr_t table_name = pRstSchema->Fields->
                GetItem("TABLE_NAME")->Value;

            printf("Table Name: %s\n",(LPCSTR) table_name);

            _bstr_t table_type = pRstSchema->Fields->
                GetItem("TABLE_TYPE")->Value;

            printf("Table type: %s\n\n",(LPCSTR) table_type);

            pRstSchema->MoveNext();

            int intLine = intLine + 1;
            if (intLine % 5 == 0)
            {
                printf("\nPress any key to continue...");
                getch();
                //Clear the screen for the next display
                system("cls");
            }
        }
    }
    catch (_com_error &e)
    {
        // Notify the user of errors if any.
        // Pass a connection pointer accessed from the Connection.
        PrintProviderError(pConnection);
        PrintComError(e);
    }

    // Clean up objects before exit.
    if (pRstSchema)
        if (pRstSchema->State == adStateOpen)
            pRstSchema->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      OpenSchemaX2 Function                            //
//                                                       //
///////////////////////////////////////////////////////////
void OpenSchemaX2()
{
    HRESULT  hr = S_OK;
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _ConnectionPtr  pConnection2  = NULL;
    _RecordsetPtr   pRstSchema  = NULL;

    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        // Open connection.
        TESTHR(pConnection2.CreateInstance(__uuidof(Connection)));
        pConnection2->Open (strCnn, "", "", adConnectUnspecified);

        // Create a safearray which takes four elements,and pass it as
        // 2nd parameter in OpenSchema method.
        SAFEARRAY FAR* psa = NULL;
        SAFEARRAYBOUND rgsabound;
        _variant_t  var;
        _variant_t  Array;
        rgsabound.lLbound = 0;
        rgsabound.cElements = 4;
        psa = SafeArrayCreate(VT_VARIANT, 1, &rgsabound);
        var.vt = VT_EMPTY;

        long ix;
        ix = 0;
        SafeArrayPutElement(psa, &ix, &var);

        ix= 1;
        SafeArrayPutElement(psa, &ix, &var);

        ix = 2;
        SafeArrayPutElement(psa, &ix, &var);

        var.vt = VT_BSTR;
        char * s1 = "VIEW";
        _bstr_t str = s1;
        var.bstrVal = str;

        ix = 3;
        SafeArrayPutElement(psa, &ix, &var);

        Array.vt = VT_ARRAY|VT_VARIANT;
        Array.parray = psa;

        pRstSchema = pConnection2->OpenSchema(adSchemaTables,&Array);

        while(!(pRstSchema->EndOfFile))
        {
            printf("Table Name: %s\n", (LPCSTR) (_bstr_t) pRstSchema->
                Fields->GetItem("TABLE_NAME")->Value);

            printf("Table type: %s\n\n",(LPCSTR) (_bstr_t) pRstSchema->
                Fields->GetItem("TABLE_TYPE")->Value);

            pRstSchema->MoveNext();

            int intLine = intLine + 1;
                if (intLine % 5 == 0)
                {
                    printf("\nPress any key to continue...");
                    getch();
                    //Clear the screen for the next display
                    system("cls");
                }
        }
    }    // End Try statement.
    catch (_com_error &e)
    {
        // Notify the user of errors if any.
        // Pass a connection pointer accessed from the Connection.
        PrintProviderError(pConnection2);
        PrintComError(e);
    }

    // Clean up objects before exit.
    if (pRstSchema)
        if (pRstSchema->State == adStateOpen)
            pRstSchema->Close();
    if (pConnection2)
        if (pConnection2->State == adStateOpen)
            pConnection2->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0;i < nCount;i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print COM errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndOpenSchemaCpp

请参阅

OpenSchema 方法


Optimize 属性范例 (VC++)

本范例演示 Field 对象的动态 Optimize 属性。Pubs 数据库的 Authors 表的 Zip 字段未被索引。将 zip 字段的 Optimize 属性设置为 True 将授权 ADO 建立索引，以提高 Find 方法的性能。

// BeginOptimizeCpp
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void OptimizeX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

//////////////////////////////////////////////////////////
//                                                      //
//    Main Function                                     //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    OptimizeX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//           OptimizeX Function                         //
//                                                      //
//////////////////////////////////////////////////////////
void OptimizeX(void)
{
    HRESULT   hr = S_OK;

    // Define string variables.
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr   pRst = NULL;

    try
    {
        TESTHR(pRst.CreateInstance(__uuidof(Recordset)));

        // Enable Index creation.
        pRst->CursorLocation = adUseClient;
        pRst->Open ("SELECT * FROM authors", strCnn,
            adOpenStatic, adLockReadOnly, adCmdText);

        // Create the index
        pRst->Fields->GetItem("zip")->Properties->
            GetItem("Optimize")->PutValue("True");

        // Find Akiko Yokomoto
        pRst->Find("zip = '94595'",1,adSearchForward);
        printf("\n%s %s    %s %s %s\n",
            (LPSTR) (_bstr_t) pRst->Fields->GetItem("au_fname")->Value,
            (LPSTR) (_bstr_t) pRst->Fields->GetItem("au_lname")->Value,
            (LPSTR) (_bstr_t) pRst->Fields->GetItem("address")->Value,
            (LPSTR) (_bstr_t) pRst->Fields->GetItem("city")->Value,
            (LPSTR) (_bstr_t) pRst->Fields->GetItem("state")->Value);

        // Delete the index
        pRst->Fields->GetItem("zip")->Properties->
            GetItem("Optimize")->PutValue("False");
    }
    catch (_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRst->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    if (pRst)
        if (pRst->State == adStateOpen)
            pRst->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////
void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;

        // Collection ranges from 0 to nCount -1.
        for(long i = 0;i < nCount;i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////
void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print COM errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndOptimizeCpp

请参阅

Field 对象 | Optimize 动态属性 (ADO)


OriginalValue 和 UnderlyingValue 属性范例 (VC++)

本范例演示 OriginalValue 和 UnderlyingValue 属性。如果在 Recordset 批更新过程中记录的基本数据发生了更改，就会显示一条信息。

// BeginOriginalValueCpp
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>
#include "OriginalValueX.h"

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void OriginalValueX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

   OriginalValueX();

    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//            OriginalValueX Function                    //
//                                                       //
///////////////////////////////////////////////////////////

void OriginalValueX(void)
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _ConnectionPtr   pConnection    = NULL;
     FieldPtr      pFldType   = NULL;
    _RecordsetPtr   pRstTitles   = NULL;

    // Define string variables.
    _bstr_t strSQLChange("UPDATE Titles SET Type = "
            "'sociology' WHERE Type = 'psychology'");
    _bstr_t strSQLRestore("UPDATE Titles SET Type = "
            "'psychology' WHERE Type = 'sociology'");

    // Define Other Variables
    HRESULT    hr = S_OK;
    IADORecordBinding   *picRs  = NULL;  //Interface Pointer declared
    CTitleRs titlers;        // C++ Class object

    try
    {
        _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

        // Open connection.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        pConnection->Open (strCnn, "", "", adConnectUnspecified);

        // Open Recordset for batch update.
        TESTHR(pRstTitles.CreateInstance(__uuidof(Recordset)));
        pRstTitles->PutActiveConnection(
            _variant_t((IDispatch *)pConnection,true));
        pRstTitles->CursorType = adOpenKeyset;
        pRstTitles->LockType = adLockBatchOptimistic;

        // Cast Connection pointer to an IDispatch type so converted
        // to correct type of variant.
        pRstTitles->Open("Titles",
            _variant_t((IDispatch *)pConnection,true),
            adOpenKeyset, adLockBatchOptimistic, adCmdTable);

        //Open an IADORecordBinding interface pointer which
        //we'll use for Binding Recordset to a class.
        TESTHR(pRstTitles->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        //Bind the Recordset to a C++ Class here
        TESTHR(picRs->BindToRecordset(&titlers));

        // Set field object variable for Type field.
        pFldType = pRstTitles->Fields->GetItem("type");

        // Change the type of psychology titles.
        while(!(pRstTitles->EndOfFile))
        {
            if (!strcmp(strtok((char *)titlers.m_szau_Type," "),
                "psychology"))
            {
                pFldType->Value = "self_help";
            }
            pRstTitles->MoveNext();
        }

        // Simulate a change by another user by updating data
        // using a command string.
        pConnection->Execute(strSQLChange,NULL,0);

        // Check for changes.
        pRstTitles->MoveFirst();
        while(!(pRstTitles->EndOfFile))
        {
            if (strcmp(pFldType->OriginalValue.pcVal,
                pFldType->UnderlyingValue.pcVal))
            {
                printf("\n\nData has changed!");

                printf("\n\nTitle ID: %s",titlers.lau_Title_idStatus ==
                    adFldOK ? titlers.m_szau_Title_id : "<NULL>");

                printf("\n\nCurrent Value: %s",
                    (LPCSTR) (_bstr_t) pFldType->Value);

                printf("\n\nOriginal Value: %s",
                    (LPCSTR) (_bstr_t) pFldType->OriginalValue);

                printf("\n\nUnderlying Value: %s\n\n",
                    (LPCSTR) (_bstr_t) pFldType->UnderlyingValue);

                printf("Press any key to continue...");
                getch();

                system("cls");
            }
            pRstTitles->MoveNext();
        }
    }
    catch (_com_error &e)
    {
        // Notify the user of errors if any.
        // Pass a connection pointer accessed from the Connection.
        PrintProviderError(pConnection);
        PrintComError(e);
    }

    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (pRstTitles)
        if (pRstTitles->State == adStateOpen)
        {
            // Cancel the update because this is a demonstration.
            pRstTitles->CancelBatch(adAffectAll);
            pRstTitles->Close();
        }
    if (pConnection)
        if (pConnection->State == adStateOpen)
        {
            // Restore Original Values.
            pConnection->Execute(strSQLRestore,NULL,0);
            pConnection->Close();
        }
};

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////
void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;

        // Collection ranges from 0 to nCount -1.
        for(long i = 0;i < nCount;i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////
void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print COM errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndOriginalValueCpp

OriginalValueX.h

// BeginOriginalValueH
#include "icrsint.h"

//This class extracts title_id and type from titles table
class CTitleRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CTitleRs)
        // Column title_id is the 1st field in the Recordset
        ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_szau_Title_id,
            sizeof(m_szau_Title_id), lau_Title_idStatus, FALSE)

        // Column type is the 3rd field in the Recordset
        ADO_VARIABLE_LENGTH_ENTRY2(3, adVarChar, m_szau_Type,
            sizeof(m_szau_Type), lau_TypeStatus, TRUE)
END_ADO_BINDING()

public:
    CHAR m_szau_Title_id[7];
    ULONG lau_Title_idStatus;
    CHAR m_szau_Type[13];
    ULONG lau_TypeStatus;
};
// EndOriginalValueH

请参阅

OriginalValue 属性 | Recordset 对象 | UnderlyingValue 属性


Prepared 属性范例 (VC++)

本范例打开两个 Command 对象（一个已准备好，另一个未准备好），来演示 Prepared 属性。

// BeginPreparedCpp
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>
#include <winbase.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void PreparedX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////////////////
//                                                       //
//      Main Function                                    //
//                                                       //
///////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    PreparedX();

    ::CoUninitialize();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PreparedX Function                               //
//                                                       //
///////////////////////////////////////////////////////////

void PreparedX(void)
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _ConnectionPtr   pConnection    =NULL;
    _CommandPtr      pCmd1    =NULL;
    _CommandPtr      pCmd2    =NULL;

    // Define string variables.
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    //Define Other Variables
    HRESULT   hr = S_OK;

    try
    {
        // Open a connection.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        pConnection->Open (strCnn, "", "", adConnectUnspecified);

        _bstr_t strCmd ("SELECT title,type FROM titles ORDER BY type");

        // Create two command objects for the same
        // command - one prepared and one not prepared.
        TESTHR(pCmd1.CreateInstance(__uuidof(Command)));
        pCmd1->ActiveConnection = pConnection;
        pCmd1->CommandText = strCmd;

        TESTHR(pCmd2.CreateInstance(__uuidof(Command)));
        pCmd2->ActiveConnection = pConnection;
        pCmd2->CommandText = strCmd;
        pCmd2->PutPrepared(true);

        // Set a timer,then execute the unprepared command 20 times.
        DWORD sngStart=GetTickCount();

        for(int intLoop=1;intLoop<=20;intLoop++)
        {
            pCmd1->Execute(NULL,NULL,adCmdText);
        }
        DWORD sngEnd=GetTickCount();

        float sngNotPrepared = (float)(sngEnd - sngStart)/(float)1000;

        // Reset the timer,then execute the prepared command 20 times
        sngStart=GetTickCount();
        for(intLoop=1;intLoop<=20;intLoop++)
        {
            pCmd2->Execute(NULL,NULL,adCmdText);
        }
        sngEnd=GetTickCount();

        float sngPrepared = (float)(sngEnd - sngStart)/(float)1000;

        // Display performance results
        printf("\n\nPerformance Results:");
        printf("\n\nNot Prepared: %6.3f seconds",sngNotPrepared);
        printf("\n\nPrepared:     %6.3f seconds\n\n",sngPrepared);
    }
    catch (_com_error &e)
    {
        // Notify the user of errors if any.
        // Pass a connection pointer accessed from the Connection.
        PrintProviderError(pConnection);
        PrintComError(e);
    }

    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////
void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;

        // Collection ranges from 0 to nCount -1.
        for(long i = 0;i < nCount;i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////
void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print COM errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndPreparedCpp

请参阅

Command 对象 | Prepared 属性


Provider 和 DefaultDatabase 属性范例 (VC++)

本范例通过打开三个使用不同提供者的 Connection 对象来演示 Provider 属性。范例中还使用 DefaultDatabase 属性设置 Microsoft ODBC Provider 的默认数据库。

// BeginProviderCpp
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void ProviderX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////
//                           //
//    Main Function          //
//                           //
///////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    ProviderX();

    ::CoUninitialize();
}

/////////////////////////////////
//                             //
//    ProviderX Function       //
//                             //
/////////////////////////////////

void ProviderX(void)
{
    HRESULT    hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _ConnectionPtr    pConnection1    = NULL;
    _ConnectionPtr    pConnection2     = NULL;
    _ConnectionPtr    pConnection3     = NULL;

    try
    {
        // Open a Connection using the Microsoft ODBC provider.
        TESTHR(pConnection1.CreateInstance(__uuidof(Connection)));
        pConnection1->ConnectionString = "driver={SQL Server};"
            "server='MySqlServer';user id='MyUserId';password='MyPassword';";
        pConnection1->Open("","","",adConnectUnspecified);
        pConnection1->DefaultDatabase = "pubs";

        // Display the provider
        printf("\n\nConnection1 provider: %s \n\n",
            (LPCSTR)pConnection1->Provider);

        // Open a connection using the OLE DB Provider for Microsoft Jet.
        TESTHR(pConnection2.CreateInstance(__uuidof(Connection)));
        pConnection2->Provider = "Microsoft.Jet.OLEDB.4.0";

        char *sConn = "c:\\Program Files\\Microsoft Office\\Office\\"
            "Samples\\Northwind.mdb";

        pConnection2->Open(sConn,"admin","",NULL);

        // Display the provider
        printf("Connection2 provider: %s \n\n",(LPCSTR)pConnection2->
            Provider);

        // Open a Connection using the Microsoft SQL Server provider.
        TESTHR(pConnection3.CreateInstance(__uuidof(Connection)));
        pConnection3->Provider = "sqloledb";
        pConnection3->Open("Data Source='MySqlServer';Initial Catalog='pubs';",
            "MyUserId","MyPassword",NULL);

        // Display the provider.
        printf("Connection3 provider: %s\n\n",(LPCSTR)pConnection3->
            Provider);
    }

    catch (_com_error &e)
    {
        // Notify the user of errors if any.
        PrintProviderError(pConnection1);
        if(pConnection2) PrintProviderError(pConnection2);
        if(pConnection3) PrintProviderError(pConnection3);
        PrintComError(e);
    }

    if (pConnection1)
        if (pConnection1->State == adStateOpen)
            pConnection1->Close();
    if (pConnection2)
        if (pConnection2->State == adStateOpen)
            pConnection2->Close();
    if (pConnection3)
        if (pConnection3->State == adStateOpen)
            pConnection3->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////
void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;

        // Collection ranges from 0 to nCount -1.
        for(long i = 0;i < nCount;i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////
void PrintComError(_com_error &e)
{
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

    // Print COM errors.
    printf("Error\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    printf("\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndProviderCpp

请参阅

Connection 对象 | DefaultDatabase 属性 | Provider 属性


Refresh 方法范例 (VC++)

本范例演示使用 Refresh 方法来刷新存储过程 Command 对象的 Parameters 集合。

// BeginRefreshCpp
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>
#include "RefreshX.h"

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void RefreshX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);
inline char* mygets(char* strDest, int n)
{
    char strExBuff[10];
    char* pstrRet = fgets(strDest, n, stdin);

    if (pstrRet == NULL)
        return NULL;

    if (!strrchr(strDest, '\n'))
        // Exhaust the input buffer.
        do
        {
            fgets(strExBuff, sizeof(strExBuff), stdin);
        }while (!strrchr(strExBuff, '\n'));
    else
        // Replace '\n' with '\0'
        strDest[strrchr(strDest, '\n') - strDest] = '\0';

    return pstrRet;
}

//////////////////////////////
//                          //
//    Main Function         //
//                          //
//////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    RefreshX();

    ::CoUninitialize();
}

////////////////////////////////////////////
//                                        //
//             RefreshX Function          //
//                                        //
////////////////////////////////////////////

void RefreshX(void)
{
    HRESULT  hr = S_OK;

    // Define string variables.
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _ConnectionPtr    pConnection      = NULL;
    _CommandPtr     pCmdByRoyalty  = NULL;
    _RecordsetPtr  pRstByRoyalty  = NULL;
    _RecordsetPtr  pRstAuthors    = NULL;
    IADORecordBinding   *picRs    = NULL;  //Interface Pointer declared.
    CAuthorsRs authorsrs;            //C++ class object

    try
    {
        // Open connection.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        pConnection->Open (strCnn, "", "", adConnectUnspecified);

        // Open a command object for a stored procedure,
        // with one parameter.
        TESTHR(pCmdByRoyalty.CreateInstance(__uuidof(Command)));
        pCmdByRoyalty->ActiveConnection = pConnection;
        pCmdByRoyalty->CommandText = "byroyalty";
        pCmdByRoyalty->CommandType = adCmdStoredProc;
        pCmdByRoyalty->Parameters->Refresh();

        // Get parameter value and execute the command,
        // storing the results in a recordset.
        char *strRoyalty;
        char strTemp[5];
        do
        {
            printf("\n\nEnter royalty : ");
            mygets(strTemp, 5);

            strRoyalty = strtok(strTemp," \t");
            if(strRoyalty == NULL)
            {
                exit(1);
            }

            // if the input is not numeric then notify the user.
            if(!atoi(strRoyalty))
            {
                printf("\nExpecting numeric value...");
                continue;
            }
        }while(!atoi(strRoyalty));

        _variant_t vtroyal;
        vtroyal.vt = VT_I2;
        vtroyal.iVal = atoi(strRoyalty);
        _variant_t Index;
        Index.vt = VT_I2;
        Index.iVal = 1;
        pCmdByRoyalty->GetParameters()->GetItem(Index)->
            PutValue(vtroyal);
        pRstByRoyalty = pCmdByRoyalty->
            Execute(NULL,NULL,adCmdStoredProc);

        // Open the Authors table to get author names for display.
        TESTHR(pRstAuthors.CreateInstance(__uuidof(Recordset)));
        pRstAuthors->Open ("authors",
            _variant_t((IDispatch *) pConnection, true),
            adOpenForwardOnly, adLockReadOnly, adCmdTable);

        //Open an IADORecordBinding interface pointer which we'll use for
        //Binding Recordset to a class.
        TESTHR(pRstAuthors->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        //Bind the Recordset to a C++ Class here.
        TESTHR(picRs->BindToRecordset(&authorsrs));

        // Print current data in the recordset,adding
        // author names from Authors table.
        printf("\n\nAuthors with %s percent royalty\n\n",strRoyalty);
        while(!(pRstByRoyalty->EndOfFile))
        {
            _bstr_t strAuthorID = pRstByRoyalty->Fields->GetItem(
                "au_id")->Value;

            printf("  %s",(LPCSTR) (_bstr_t) pRstByRoyalty->Fields->
                GetItem("au_id")->Value);

            pRstAuthors->Filter = "au_id ='"+strAuthorID+"'";
            printf(", %s %s\n\n",authorsrs.lau_fnameStatus == adFldOK ?
                authorsrs.m_szau_fname : "<NULL>",
                authorsrs.lau_lnameStatus == adFldOK ?
                authorsrs.m_szau_lname : "<NULL>");
            pRstByRoyalty->MoveNext();
        }
    }
    catch (_com_error &e)
    {
        PrintProviderError(pConnection);
        PrintComError(e);
    }

    if (pRstByRoyalty)
        if (pRstByRoyalty->State == adStateOpen)
            pRstByRoyalty->Close();
    if (pRstAuthors)
        if (pRstAuthors->State == adStateOpen)
            pRstAuthors->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////
void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;

        // Collection ranges from 0 to nCount -1.
        for(long i = 0;i < nCount;i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////
void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print COM errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndRefreshCpp

RefreshX.h

// BeginRefreshH
#include "icrsint.h"

//This Class extracts  lname,fname from authors table.
class CAuthorsRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CAuthorsRs)
    // Column lname is the 2nd field in the recordset
     ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_szau_lname,
         sizeof(m_szau_lname), lau_lnameStatus, TRUE)
    // Column fname is the 3rd field in the recordset.
   ADO_VARIABLE_LENGTH_ENTRY2(3, adVarChar, m_szau_fname,
         sizeof(m_szau_fname), lau_fnameStatus, TRUE)

END_ADO_BINDING()

public:
    CHAR m_szau_fname[21];
    ULONG lau_fnameStatus;
    CHAR   m_szau_lname[41];
    ULONG  lau_lnameStatus;
};
// EndRefreshH

请参阅

Command 对象 | Parameters 集合 | Refresh 方法


Resync 方法范例 (VC++)

本范例演示使用 Resync 方法来刷新静态记录集中的数据。

// BeginResyncCpp
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void ResyncX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

/////////////////////////////
//                         //
//    Main Function        //
//                         //
/////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    ResyncX();

    ::CoUninitialize();
}

/////////////////////////////////
//                             //
//     ResyncX Function        //
//                             //
/////////////////////////////////

void ResyncX(void)
{
    HRESULT  hr = S_OK;

    // Define string variables.
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr  pRstTitles  = NULL;

    try
    {
        // Open recordset for titles table.
        TESTHR(pRstTitles.CreateInstance(__uuidof(Recordset)));
        pRstTitles->CursorLocation = adUseClient;
        pRstTitles->CursorType = adOpenStatic;
        pRstTitles->LockType = adLockBatchOptimistic;
        pRstTitles->Open ("titles",strCnn,
            adOpenStatic, adLockBatchOptimistic, adCmdTable);

        // Change the type of the first title in the recordset.
        pRstTitles->Fields->GetItem("type")->Value =
            (_bstr_t) ("database");

        // Display the results of the change.
        printf("\nBefore resync: \n\n");

        printf("Title - %s\n\n",(LPSTR) (_bstr_t) pRstTitles->
            Fields->GetItem("title")->Value);

        printf("Type - %s\n\n",(LPSTR) (_bstr_t) pRstTitles->
            Fields->GetItem("type")->Value);

        // Resync with database.
        pRstTitles->Resync(adAffectAll,adResyncAllValues);

        // Display the results of the resynch.
        printf("\n\nAfter resync: \n\n");

        printf("Title - %s\n\n",(LPSTR) (_bstr_t) pRstTitles->
            Fields->GetItem("title")->Value);

        printf("Type - %s\n\n",(LPSTR) (_bstr_t) pRstTitles->
            Fields->GetItem("type")->Value);
    }
    catch (_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstTitles->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    if (pRstTitles)
        if (pRstTitles->State == adStateOpen)
        {
            pRstTitles->CancelBatch(adAffectAll);
            pRstTitles->Close();
        }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////
void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;

        // Collection ranges from 0 to nCount -1.
        for(long i = 0;i < nCount;i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s\n", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////
void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print COM errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndResyncCpp

请参阅

Resync 方法


Save 和 Open 方法范例 (VC++)

这三个范例演示如何配合使用 Save 和 Open 方法。

假设用户在出差时要携带数据库中的一个表。在出发前，用户以 Recordset 访问数据，并将其保存为便携格式。在到达目的地后，用户以本地、断开连接的 Recordset 访问 Recordset，在修改 Recordset 后将其保存。最后，当用户回家后，再次连接数据库并用旅途中所做的更改对其进行更新。

// BeginSaveCpp
#import "c:\Program Files\Common Files\system\ado\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>
#include <io.h>

//Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
bool FileExists(void);
void SaveX1(void);
void SaveX2(void);
void SaveX3(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

//////////////////////////////////////////////////////////
//                                                      //
//        Main Function                                 //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    //If File exists in the specified directory, then display error
    if (!FileExists())
    {
        SaveX1();
        SaveX2();
        SaveX3();
    }

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//     SaveX1 Function                                  //
//                                                      //
//////////////////////////////////////////////////////////

//First, access and save the authors table.
void SaveX1()
{
    HRESULT hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr pRstAuthors = NULL;

    //Definitions of other variables
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        TESTHR(pRstAuthors.CreateInstance(__uuidof(Recordset)));

        pRstAuthors->Open("SELECT * FROM authors",strCnn,
            adOpenDynamic,adLockBatchOptimistic,adCmdText);

        // For sake of illustration, save the Recordset to a diskette
        // in XML format.
        pRstAuthors->Save("c:\\pubs.xml",adPersistXML);
    }
    catch(_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstAuthors->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    if (pRstAuthors)
        if (pRstAuthors->State == adStateOpen)
            pRstAuthors->Close();
}

//////////////////////////////////////////////////////////
//                                                      //
//       SaveX2 Function                                //
//                                                      //
//////////////////////////////////////////////////////////
//At this point, you have arrived at your destination.
//You will access the authors table as a local, disconnected Recordset.
//Don't forget you must have the MSPersist provider on the machine you
//are using in order to access the saved file, c:\pubs.xml.
void SaveX2()
{
    HRESULT hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr pRstAuthors = NULL;

    try
    {
        TESTHR(pRstAuthors.CreateInstance(__uuidof(Recordset)));

        //For sake of illustration, we specify all parameters.
        pRstAuthors->Open("c:\\pubs.xml","Provider='MSPersist';",
            adOpenForwardOnly,adLockBatchOptimistic,adCmdFile);

        //Now you have a local, disconnected Recordset.
        //Edit it as you desire.
        //(In this example, the change makes no difference).
        pRstAuthors->Find("au_lname = 'Carson'",NULL,adSearchForward);
        if (pRstAuthors->EndOfFile)
        {
            printf("Name not found ...\n");
            pRstAuthors->Close();
            return;
        }
        pRstAuthors->GetFields()->GetItem("City")->PutValue("Chicago");
        pRstAuthors->Update();

        // Save changes in ADTG format this time, purely for sake of
        // illustration. Note that the previous version is still on the
        // diskette as c:\pubs.xml.
        pRstAuthors->Save("c:\\pubs.adtg",adPersistADTG);
    }
    catch(_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstAuthors->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    if (pRstAuthors)
        if (pRstAuthors->State == adStateOpen)
            pRstAuthors->Close();
}

//////////////////////////////////////////////////////////
//                                                      //
//   SaveX3 Function                                    //
//                                                      //
//////////////////////////////////////////////////////////
//Finally, you return home. Now update the database with
//your changes.
void SaveX3()
{
    HRESULT hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr pRstAuthors = NULL;
    _ConnectionPtr pCnn = NULL;

    //Definitions of other variables
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        TESTHR(pCnn.CreateInstance(__uuidof(Connection)));

        TESTHR(pRstAuthors.CreateInstance(__uuidof(Recordset)));

        //If there is no ActiveConnection, you can open with defaults.
        pRstAuthors->Open("c:\\pubs.adtg","Provider=MSPersist;",
            adOpenForwardOnly,adLockBatchOptimistic,adCmdFile);

        //Connect to the database, associate the Recordset with
        //the connection, then update the database table with the
        //changed Recordset.
        pCnn->Open(strCnn,"","",NULL);

        pRstAuthors->PutActiveConnection(_variant_t((IDispatch *) pCnn));
        pRstAuthors->UpdateBatch(adAffectAll);
    }
    catch(_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstAuthors->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    if (pRstAuthors)
        if (pRstAuthors->State == adStateOpen)
            pRstAuthors->Close();
    if (pCnn)
        if (pCnn->State == adStateOpen)
            pCnn->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////
void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;

        // Collection ranges from 0 to nCount -1.
        for(long i = 0;i < nCount;i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print COM errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}

bool FileExists()
{
    struct _finddata_t xml_file;
    long hFile;

    if( (hFile = _findfirst("c:\\pubs.xml", &xml_file )) != -1L)
    {
       printf( "File already exists!\n" );
       return(true);
    }
    else
        return (false);
}
// EndSaveCpp

请参阅

Open 方法 (ADO Recordset) | Recordset 对象 | Save 方法


Seek 方法和 Index 属性范例 (VC++)

本范例使用 Recordset 对象的 Seek 方法和 Index 属性，以及给定的 Employee ID，共同定位 Nwind.mdb 数据库 Employees 表中的雇员名。

// BeginSeekCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <stdio.h>
#include <ole2.h>
#include <conio.h>
#include <string.h>
#include "SeekX.h"

//Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void SeekX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);
inline char* mygets(char* strDest, int n)
{
    char strExBuff[10];
    char* pstrRet = fgets(strDest, n, stdin);

    if (pstrRet == NULL)
        return NULL;

    if (!strrchr(strDest, '\n'))
        // Exhaust the input buffer.
        do
        {
            fgets(strExBuff, sizeof(strExBuff), stdin);
        }while (!strrchr(strExBuff, '\n'));
    else
        // Replace '\n' with '\0'
        strDest[strrchr(strDest, '\n') - strDest] = '\0';

    return pstrRet;
}

//////////////////////////////////////////////////////////
//                                                      //
//       Main Function                                  //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    SeekX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//     SeekX Function                                   //
//                                                      //
//////////////////////////////////////////////////////////
void SeekX()
{
    HRESULT hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.

    _RecordsetPtr pRstEmp = NULL;

    IADORecordBinding    *picRs = NULL;  // Interface Pointer declared
    CEmployeeRs EmpRs; //C++ class object

    //Definitions of other variables
    _bstr_t strPrompt("Enter an EmployeeID (e.g., 1 to 9)");
    char strEmpId[2];

    try
    {
        TESTHR(pRstEmp.CreateInstance(__uuidof(Recordset)));
        pRstEmp->CursorLocation = adUseServer;
        pRstEmp->Open("employees", "Provider='Microsoft.Jet.OLEDB.4.0';"
            "Data Source='C:\\Program Files\\Microsoft Office\\Office\\"
            "Samples\\Northwind.mdb';",
            adOpenKeyset,adLockReadOnly,adCmdTableDirect);

        //Open an IADORecordBinding interface pointer which
        //we'll use for binding Recordset to a Class
        TESTHR(pRstEmp->QueryInterface(
            __uuidof(IADORecordBinding), (LPVOID*)&picRs));

        //Bind the Recordset to a C++ Class
        TESTHR(picRs->BindToRecordset(&EmpRs));

        //Does this provider support Seek and Index?
        if (pRstEmp->Supports(adIndex) && pRstEmp->Supports(adSeek))
        {
            pRstEmp->Index = "PrimaryKey";

            //Display all the employees.
            pRstEmp->MoveFirst();
            while (!pRstEmp->EndOfFile)
            {
                  printf("%d : %s %s\n",
                      EmpRs.le_empidStatus == adFldOK ?
                      EmpRs.m_ie_empid : 0,
                      EmpRs.le_fnameStatus == adFldOK ?
                      EmpRs.m_sze_fname : "<NULL>",
                      EmpRs.le_lnameStatus == adFldOK ?
                      EmpRs.m_sze_lname : "<NULL>");

                  pRstEmp->MoveNext();
            }
            //Prompt the user for an EmployeeID between 1 and 9.
            do
            {
                pRstEmp->MoveFirst();
                printf("\n\n%s\t",(LPCSTR) strPrompt);
                mygets(strEmpId, 2);

                //Quit if strEmpID is a zero-length string
                //(CANCEL, null, etc.)
                char *strTemp = strtok(strEmpId," \t");
                if (strTemp == NULL) break;
                if (strlen(strTemp) == 1 && atoi(strTemp) >= 1 &&
                    atoi(strTemp) <= 9)
                {
                    _variant_t strEmployeeId(strTemp);
                    pRstEmp->Seek(strEmployeeId, adSeekAfterEQ);
                    if (pRstEmp->EndOfFile)
                    {
                        printf("Employee not found.\n");
                    }
                    else
                    {
                        printf("%d : Employee='%s %s'\n",
                            EmpRs.le_empidStatus == adFldOK ?
                            EmpRs.m_ie_empid : 0,
                            EmpRs.le_fnameStatus == adFldOK ?
                            EmpRs.m_sze_fname : "<NULL>",
                            EmpRs.le_lnameStatus == adFldOK ?
                            EmpRs.m_sze_lname : "<NULL>");
                    }
                }
            }
            while(true);
        }
    }
    catch(_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstEmp->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (pRstEmp)
        if (pRstEmp->State == adStateOpen)
            pRstEmp->Close();
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintProviderError Function                      //
//                                                       //
///////////////////////////////////////////////////////////
void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;

        // Collection ranges from 0 to nCount -1.
        for(long i = 0;i < nCount;i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("\t Error number: %x\t%s", pErr->Number,
                pErr->Description);
        }
    }
}

///////////////////////////////////////////////////////////
//                                                       //
//      PrintComError Function                           //
//                                                       //
///////////////////////////////////////////////////////////
void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print COM errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndSeekCpp

SeekX.h

// BeginSeekH
#include "icrsint.h"

// This Class extracts only EmployeeId,FirstName and LastName
// from employees table
class CEmployeeRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CEmployeeRs)

   // Column hiredate is the 1st field in the table.
   ADO_VARIABLE_LENGTH_ENTRY2(1, adInteger,m_ie_empid,
        sizeof(m_ie_empid), le_empidStatus, FALSE)

    // Column LastName is the 2nd field in the table.
   ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_sze_lname,
         sizeof(m_sze_lname), le_lnameStatus, FALSE)

    // Column FirstName is the 3rd field in the table.
   ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_sze_fname,
         sizeof(m_sze_fname), le_fnameStatus, FALSE)
END_ADO_BINDING()

public:
   INT    m_ie_empid;
   ULONG  le_empidStatus;
   CHAR    m_sze_fname[11];
   ULONG  le_fnameStatus;
   CHAR    m_sze_lname[21];
   ULONG  le_lnameStatus;
};
// EndSeekH

请参阅

Index 属性 | Recordset 对象 | Seek 方法


Sort 属性范例 (VC++)

本范例使用 Recordset 对象的 Sort 属性来调整 Recordset 中行的顺序，该 Recordset 来自 Pubs 数据库的 Authors 表。辅助实用程序例程将打印每一行。

// BeginSortCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void SortX(void);
void SortXprint(_bstr_t title, _RecordsetPtr rstp);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

//////////////////////////////////////////////////////////
//                                                      //
//    Main Function                                     //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    SortX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//        SortX Function                                //
//                                                      //
//////////////////////////////////////////////////////////
void SortX(void)
{
    HRESULT  hr = S_OK;

    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _ConnectionPtr  pConnection      = NULL;
    _RecordsetPtr  pRstAuthors    = NULL;

    // Define string variables.
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));

        TESTHR(pRstAuthors.CreateInstance(__uuidof(Recordset)));

        pRstAuthors->CursorLocation = adUseClient;
        pConnection->Open (strCnn, "", "", adConnectUnspecified);
        pRstAuthors->Open("SELECT * FROM authors",
            _variant_t((IDispatch *) pConnection),
             adOpenStatic, adLockReadOnly, adCmdText);

        SortXprint("    Initial Order    ", pRstAuthors);

        //Clear the screen for the next display.
        printf("\nPress any key to continue...");
        getch();
        system("cls");

        pRstAuthors->Sort = "au_lname ASC, au_fname ASC";
        SortXprint("Last Name Ascending", pRstAuthors);

        //Clear the screen for the next display.
        printf("\nPress any key to continue...");
        getch();
        system("cls");

        pRstAuthors->Sort = "au_lname DESC, au_fname ASC";
        SortXprint("Last Name Descending", pRstAuthors);
    }
    catch(_com_error &e)
    {
        PrintProviderError(pConnection);
        PrintComError(e);
    }

    // Clean up objects before exit.
    if (pRstAuthors)
        if (pRstAuthors->State == adStateOpen)
            pRstAuthors->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

//////////////////////////////////////////////////////////
//                                                      //
//        SortXprint Function                           //
//                                                      //
//////////////////////////////////////////////////////////
//This is the secondary utility routine that prints
//the given title, and the contents of the specified Recordset.
void SortXprint(_bstr_t title, _RecordsetPtr rstp)
{
    printf("---------------%s---------------\n", (LPCSTR)title);
    printf("First Name  Last Name\n"
        "---------------------------------------------------\n");
    rstp->MoveFirst();
    int intLineCnt = 4;
    while (!(rstp->EndOfFile))
    {
        _bstr_t aufname;
        _bstr_t aulname;
        aufname = rstp->GetFields()->GetItem("au_fname")->Value;
        aulname = rstp->GetFields()->GetItem("au_lname")->Value,
        printf("%s    %s\n",(LPCSTR) aufname, (LPCSTR) aulname);
        rstp->MoveNext();
        intLineCnt++;
        if (intLineCnt % 20 ==0)
            {
                printf("\nPress any key to continue...\n");
                getch();
            }
    }
}

//////////////////////////////////////////////////////////
//                                                      //
//     PrintProviderError Function                      //
//                                                      //
//////////////////////////////////////////////////////////
void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

//////////////////////////////////////////////////////////
//                                                      //
//  PrintComError Function                              //
//                                                      //
//////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);

}

// EndSortCpp

请参阅

Recordset 对象 | Sort 属性


Source 属性范例 (VC++)

本范例通过打开三个基于不同数据源的 Recordset 对象来演示 Source 属性。

// BeginSourceCpp
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void SourceX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////
//                       //
//    Main Function      //
//                       //
///////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    SourceX();

    ::CoUninitialize();
}

///////////////////////////////////////////////
//                                           //
//    SourceX Function                       //
//                                           //
///////////////////////////////////////////////
void SourceX(void)
{
    HRESULT  hr = S_OK;

    // Define string variables.
    _bstr_t strCmdSQL("Select title,type,pubdate "
        "FROM titles ORDER BY title");
    _bstr_t strSQL("SELECT title_ID AS TitleID, title AS Title, "
        "publishers.pub_id AS PubID, pub_name AS PubName "
        "FROM publishers INNER JOIN titles "
        "ON publishers.pub_id = titles.pub_id "
        "ORDER BY Title");
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
        "Initial Catalog='pubs';Integrated Security='SSPI';");

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _ConnectionPtr  pConnection          = NULL;
    _RecordsetPtr  pRstTitles        = NULL;
    _RecordsetPtr  pRstPublishers      = NULL;
    _RecordsetPtr  pRstPublishersDirect    = NULL;
    _RecordsetPtr  pRstTitlesPublishers    = NULL;
    _CommandPtr     pCmdSQL          = NULL;

    try
    {
        // Open a connection.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        pConnection->Open (strCnn, "", "", adConnectUnspecified);

        // Open a recordset based on a command object.
        TESTHR(pCmdSQL.CreateInstance(__uuidof(Command)));
        pCmdSQL->ActiveConnection = pConnection;
        pCmdSQL->CommandText = strCmdSQL;
        pRstTitles = pCmdSQL->Execute(NULL,NULL,adCmdText);

        // Open a recordset based on a a table
        TESTHR(pRstPublishers.CreateInstance(__uuidof(Recordset)));
        pRstPublishers->Open ("publishers",
            _variant_t((IDispatch *) pConnection, true),
            adOpenForwardOnly, adLockReadOnly, adCmdTable);

        // Open a recordset based on a table
        TESTHR(pRstPublishersDirect.CreateInstance(
            __uuidof(Recordset)));
        pRstPublishersDirect->Open ("publishers",
            _variant_t((IDispatch *) pConnection, true),
            adOpenForwardOnly, adLockReadOnly, adCmdTableDirect);

        // Open a recordset based on a SQL string.
        TESTHR(pRstTitlesPublishers.CreateInstance(
            __uuidof(Recordset)));
        pRstTitlesPublishers->Open(strSQL,
            _variant_t((IDispatch *) pConnection, true),
            adOpenForwardOnly, adLockReadOnly, adCmdText);

        // Use the Source property to display the source of
        // each recordset.
        printf("rstTitles source: \n%s\n\n",
            (LPCSTR)(_bstr_t) pRstTitles->GetSource().bstrVal);
        printf("rstPublishers source: \n%s\n\n",
            (LPCSTR)(_bstr_t) pRstPublishers->GetSource().bstrVal);
        printf("rstPublishersDirect source: \n%s\n\n",
            (LPCSTR)(_bstr_t) pRstPublishersDirect->GetSource().bstrVal);
        printf("rstTitlesPublishers source: \n%s\n\n",
            (LPCSTR)(_bstr_t) pRstTitlesPublishers->GetSource().bstrVal);
    }
    catch (_com_error &e)
    {
        // Notify the user of errors if any.
        PrintProviderError(pConnection);
        PrintComError(e);
    }

    if (pRstTitles)
        if (pRstTitles->State == adStateOpen)
            pRstTitles->Close();
    if (pRstPublishers)
        if (pRstPublishers->State == adStateOpen)
            pRstPublishers->Close();
    if (pRstPublishersDirect)
        if (pRstPublishersDirect->State == adStateOpen)
            pRstPublishersDirect->Close();
    if (pRstTitlesPublishers)
        if (pRstTitlesPublishers->State == adStateOpen)
            pRstTitlesPublishers->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

///////////////////////////////////////////////
//                                           //
//    PrintProviderError Function            //
//                                           //
///////////////////////////////////////////////
void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

///////////////////////////////////////////////
//                                           //
//    PrintComError Function                 //
//                                           //
///////////////////////////////////////////////
void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);

}
// EndSourceCpp

请参阅

Recordset 对象 | Source 属性 (ADO Recordset)


State 属性范例 (VC++)

本范例使用 State 属性，在异步连接为开且异步命令正在执行时显示消息。

// BeginStateCpp
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void StateX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////
//                                           //
//    Main Function                          //
//                                           //
///////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    StateX();

    ::CoUninitialize();
}

///////////////////////////////////////////////
//                                           //
//        StateX Function                    //
//                                           //
///////////////////////////////////////////////
void StateX(void)
{
    HRESULT  hr = S_OK;

    // Define string variables.
    _bstr_t strSQLChange("UPDATE Titles SET Type = "
            "'self_help' WHERE Type = 'psychology'");
    _bstr_t strSQLRestore("UPDATE Titles SET Type = "
            "'psychology' WHERE Type = 'self_help'");
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _ConnectionPtr    pConnection        = NULL;
    _ConnectionPtr    pConnection2        = NULL;
    _CommandPtr         pCmdChange    = NULL;
    _CommandPtr         pCmdRestore    = NULL;

    try
    {
        // Open two asynchronous connections,displaying
        // a message while connecting.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        TESTHR(pConnection2.CreateInstance(__uuidof(Connection)));

        pConnection->Open (strCnn, "", "", adAsyncConnect);
        while(pConnection->State == adStateConnecting)
        {
            printf("Opening first connection....\n\n");
        }

        pConnection2->Open (strCnn, "", "", adAsyncConnect);
        while(pConnection2->State == adStateConnecting)
        {
            printf("Opening second connection....\n\n");
        }

        // Create two command objects.
        TESTHR(pCmdChange.CreateInstance(__uuidof(Command)));
        pCmdChange->ActiveConnection = pConnection;
        pCmdChange->CommandText = strSQLChange;

        TESTHR(pCmdRestore.CreateInstance(__uuidof(Command)));
        pCmdRestore->ActiveConnection = pConnection2;
        pCmdRestore->CommandText = strSQLRestore;

        // Executing the commands,displaying a message
        // while they are executing.
        pCmdChange->Execute(NULL,NULL,adAsyncExecute);
        while(pCmdChange->State == adStateExecuting)
        {
            printf("Change command executing...\n\n");
        }

        pCmdRestore->Execute(NULL,NULL,adAsyncExecute);
        while(pCmdRestore->State == adStateExecuting)
        {
            printf("Restore command executing...\n\n");
        }
    }
    catch (_com_error &e)
    {
        // Notify the user of errors if any.
        PrintProviderError(pConnection);
        PrintComError(e);
    }

    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
    if (pConnection2)
        if (pConnection2->State == adStateOpen)
            pConnection2->Close();
}

///////////////////////////////////////////////
//                                           //
//    PrintProviderError Function            //
//                                           //
///////////////////////////////////////////////
void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

///////////////////////////////////////////////
//                                           //
//    PrintComError Function                 //
//                                           //
///////////////////////////////////////////////
void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndStateCpp

请参阅

State 属性


Status 属性范例 (VC++)

本范例使用 Status 属性来显示在批更新发生前被批操作修改的记录。

// BeginStatusCpp
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>
#include "StatusX.h"

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void StatusX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////
//                                           //
//    Main Function                          //
//                                           //
///////////////////////////////////////////////

void main()
{
    if(FAILED(CoInitialize(NULL)))
        return;

    StatusX();

    ::CoUninitialize();
}

///////////////////////////////////////////////
//                                           //
//    StatusX Function                       //
//                                           //
///////////////////////////////////////////////
void StatusX(void)
{
    HRESULT  hr = S_OK;

    // Define string variables.
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
     IADORecordBinding *picRs    = NULL;  // Interface Pointer Declared
     CTitleRs titlers;           // C++ Class Object
    _RecordsetPtr  pRstTitles    = NULL;
    LPSTR p_TempStr        = NULL;

    try
    {
        // Open recordset for batch update
        TESTHR(hr = pRstTitles.CreateInstance(__uuidof(Recordset)));
        pRstTitles->CursorType = adOpenKeyset;
        pRstTitles->LockType = adLockBatchOptimistic;
        pRstTitles->Open ("titles", strCnn,
            adOpenKeyset, adLockBatchOptimistic, adCmdTable);

        // Open an IADORecordBinding interface pointer which
        // we will use for binding Recordset to a class.
        TESTHR(hr = pRstTitles->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        // Bind the Recordset to a C++ class here
        TESTHR(hr = picRs->BindToRecordset(&titlers));

        p_TempStr = (LPSTR) malloc(sizeof(titlers.m_szt_Type));

        // Change the type of psychology titles.
        while(!(pRstTitles->EndOfFile))
        {
            // Set the final character of the destination string to NULL.
            p_TempStr[sizeof(titlers.m_szt_Type)-1] = '\0';
            // The source string will get truncated if its length is
            // longer than the length of the destination string minus one.
            strncpy(p_TempStr,strtok(titlers.m_szt_Type," "),
                sizeof(titlers.m_szt_Type)-1);

            // Compare the type of psychology titles
            if (!strcmp(p_TempStr,"psychology"))
            {
                    // Copy "self_help" title field
                    pRstTitles->Fields->GetItem("type")->Value =
                        (_bstr_t) ("self_help");
            }
            pRstTitles->MoveNext();
        }

        // Display Title ID and status
        pRstTitles->MoveFirst();
        while(!(pRstTitles->EndOfFile))
        {
            if(pRstTitles->Status == adRecModified)
            {
                printf("%s - Modified\n",titlers.lt_Title_idStatus ==
                    adFldOK ? titlers.m_szt_Title_id : "<NULL>");
            }
            else
            {
                printf("%s\n",titlers.lt_Title_idStatus == adFldOK ?
                    titlers.m_szt_Title_id : "<NULL>");
            }
            pRstTitles->MoveNext();
        }
    }
    catch (_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstTitles->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Deallocate the memory
    if (p_TempStr)
        free(p_TempStr);

    if (pRstTitles)
        if (pRstTitles->State == adStateOpen)
        {
            // Cancel the update because this is a demonstration.
            pRstTitles->CancelBatch(adAffectAll);
            pRstTitles->Close();
        }
}

///////////////////////////////////////////////
//                                           //
//    PrintProviderError Function            //
//                                           //
///////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

///////////////////////////////////////////////
//                                           //
//    PrintComError Function                 //
//                                           //
///////////////////////////////////////////////
void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndStatusCpp

StatusX.h

// BeginStatusH
#include "icrsint.h"

//This class extracts title_id and type from titles table.
class CTitleRs : public CADORecordBinding
{
    BEGIN_ADO_BINDING(CTitleRs)
        // Column title_id is the 1st field in the table
        ADO_VARIABLE_LENGTH_ENTRY2(1,adVarChar,m_szt_Title_id,
            sizeof(m_szt_Title_id),lt_Title_idStatus,FALSE)
        // Column type is the 3rd field in the table
        ADO_VARIABLE_LENGTH_ENTRY2(3,adVarChar,m_szt_Type,
            sizeof(m_szt_Type),lt_TypeStatus,TRUE)
END_ADO_BINDING()

public:
    CHAR m_szt_Title_id[7];
    ULONG lt_Title_idStatus;
    CHAR m_szt_Type[13];
    ULONG lt_TypeStatus;
};
// EndStatusH

请参阅

Status 属性 (ADO Recordset)


StayInSync 属性范例 (VC++)

本范例演示 StayInSync 属性如何方便地访问分级 Recordset 的行。

外循环显示每个作者的姓名、州/省别和标识。每行追加的 Recordset 都从 Fields 集合进行检索，一旦父 Recordset 移至新行，StayInSync 属性即自动将其分配给 rstTitleAuthor。内循环显示追加的记录集中每行的四个字段。

// BeginStayInSyncCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void StayInSyncX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

//////////////////////////////////////////////////////////
//                                                      //
//        Main Function                                 //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    StayInSyncX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//       StayInSyncX Function                           //
//                                                      //
//////////////////////////////////////////////////////////
void StayInSyncX(void)
{
    HRESULT  hr = S_OK;

    // Define string variables.
    _bstr_t strCnn("Provider='MSDataShape';"
        "Data Provider='sqloledb';Data Source='MySqlServer';"
        "Initial Catalog='pubs';Integrated Security='SSPI';");

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _ConnectionPtr  pConnection      = NULL;
    _RecordsetPtr  pRst      = NULL;
    _RecordsetPtr  pRstTitleAuthor    = NULL;

    try
    {
        TESTHR(pRstTitleAuthor.CreateInstance(__uuidof(Recordset)));

        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));

        TESTHR(pRst.CreateInstance(__uuidof(Recordset)));

        // Open connection.
        pConnection->Open (strCnn, "", "", adConnectUnspecified);
        pRst->PutStayInSync(true);

        // Open recordset with names from Author & titleauthor table.
        pRst->Open("SHAPE  {select * from authors} "
              "APPEND ({select * from titleauthor}"
              "RELATE au_id TO au_id) AS chapTitleAuthor",
              _variant_t((IDispatch*)pConnection,true),
            adOpenStatic, adLockReadOnly, adCmdText);

        pRstTitleAuthor = pRst->GetFields()->GetItem("chapTitleAuthor")->
            Value;
        int intLineCnt=0;
        while(!(pRst->EndOfFile))
        {
            printf("\n%s  %s  %s    %s\n", (LPCSTR)(_bstr_t)pRst->
               Fields->GetItem("au_fname")->Value,
               (LPCSTR)(_bstr_t)pRst->Fields->GetItem("au_lname")->Value,
               (LPCSTR)(_bstr_t)pRst->Fields->GetItem("state")->Value,
               (LPCSTR)(_bstr_t)pRst->Fields->GetItem("au_id")->Value);
            intLineCnt++;

            if (intLineCnt%15 == 0)
            {
                printf("\nPress any key to continue...\n");
                getch();
            }

            _variant_t vIndex;
            while(!(pRstTitleAuthor->EndOfFile))
            {
                vIndex = (short) 0;
                printf("%s    ",(LPCSTR)(_bstr_t)pRstTitleAuthor->
                    Fields->Item[&vIndex]->Value);
                vIndex = (short) 1;
                printf("%s    ",(LPCSTR)(_bstr_t)pRstTitleAuthor->
                    Fields->Item[&vIndex]->Value);
                vIndex = (short) 2;
                printf("%s    ",(LPCSTR)(_bstr_t)pRstTitleAuthor->
                    Fields->Item[&vIndex]->Value);
                vIndex = (short) 3;
                printf("%s\n",(LPCSTR)(_bstr_t)pRstTitleAuthor->
                    Fields->Item[&vIndex]->Value);
                intLineCnt++;

                if (intLineCnt%15 == 0)
                {
                    printf("\nPress any key to continue...\n");
                    getch();
                }
                pRstTitleAuthor->MoveNext();
            }
            pRst->MoveNext();
        }
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        // Pass a connection pointer accessed from the Recordset.
        PrintProviderError(pConnection);
        PrintComError(e);
    }

    // Clean up objects before exit.
    if (pRst)
        if (pRst->State == adStateOpen)
            pRst->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

//////////////////////////////////////////////////////////
//                                                      //
//        PrintProviderError Function                   //
//                                                      //
//////////////////////////////////////////////////////////
void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

//////////////////////////////////////////////////////////
//                                                      //
//     PrintComError Function                           //
//                                                      //
//////////////////////////////////////////////////////////
void PrintComError(_com_error &e)
{

    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

    // Print Com errors.
    printf("Error\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    printf("\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCSTR) bstrDescription);

}
// EndStayInSyncCpp

请参阅

Fields 集合 | Recordset 对象 | StayInSync 属性


Supports 方法范例 (VC++)

本范例使用 Supports 方法来显示用不同游标类型打开的记录集所支持的选项。运行本范例需要 DisplaySupport 函数。

// BeginSupportsCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <stdio.h>
#include <ole2.h>
#include <conio.h>

//Function Declarations.
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void SupportsX(void);
void DisplaySupport(_RecordsetPtr pRstTemp);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////
//                                           //
//    Main Function                          //
//                                           //
///////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    SupportsX();

    ::CoUninitialize();
}

///////////////////////////////////////////////
//                                           //
//    SupportsX Function                     //
//                                           //
///////////////////////////////////////////////
void SupportsX(void)
{
    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr  pRstTitles  = NULL;

    // Define Other Variables
    HRESULT hr = S_OK;

    // Assign connection string to a variable
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    try
    {
        // Open a recordset from Titles table
        TESTHR(pRstTitles.CreateInstance(__uuidof(Recordset)));

        // Fill array with CursorType constants.
        int  aintCursorType[4];
        aintCursorType[0] = adOpenForwardOnly;
        aintCursorType[1] = adOpenKeyset;
        aintCursorType[2] = adOpenDynamic;
        aintCursorType[3] = adOpenStatic;

        // Open recordset using each CursorType and optimistic locking.
        // Then call the DisplaySupport procedure to display the
        // supported options.
        for (int intIndex=0; intIndex <= 3; intIndex++)
        {
            pRstTitles->CursorType =
               (enum CursorTypeEnum)aintCursorType[intIndex];
            pRstTitles->LockType = adLockOptimistic;

            // Pass the Cursor type and LockType to the Recordset.
            pRstTitles->Open ("titles", strCnn,
                (enum CursorTypeEnum)aintCursorType[intIndex],
                adLockOptimistic, adCmdTable);

            switch(aintCursorType[intIndex])
            {
                case adOpenForwardOnly:
                    printf("\nForwardOnly cursor supports:\n");
                    break;

                case adOpenKeyset:
                    printf("\nKeyset cursor supports:\n");
                    break;

                case adOpenDynamic:
                    printf("\nDynamic cursor supports:\n");
                    break;

                case adOpenStatic:
                    printf("\nStatic cursor supports:\n");
                    break;

                default :
                    break;
            }

            DisplaySupport(pRstTitles);

            printf("\n\nPress any key to continue...");
            getch();

            //Clear the screen for the next display.
            system("cls");
        }
    }
    catch(_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstTitles->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    if (pRstTitles)
        if (pRstTitles->State == adStateOpen)
            pRstTitles->Close();
}

///////////////////////////////////////////////
//                                           //
//    DisplaySupport Function                //
//                                           //
///////////////////////////////////////////////
void DisplaySupport (_RecordsetPtr  pRstTemp)
{
    // Fill array with cursor option constants.
    long  alngConstants[11];
    alngConstants[0] = adAddNew;
    alngConstants[1] = adApproxPosition;
    alngConstants[2] = adBookmark;
    alngConstants[3] = adDelete;
    alngConstants[4] = adFind;
    alngConstants[5] = adHoldRecords;
    alngConstants[6] = adMovePrevious;
    alngConstants[7] = adNotify;
    alngConstants[8] = adResync;
    alngConstants[9] = adUpdate;
    alngConstants[10] = adUpdateBatch;

    for(int intIndex=0; intIndex <= 10; intIndex++)
    {
        bool booSupports = pRstTemp->
            Supports( (enum CursorOptionEnum)alngConstants[intIndex] );

        if(booSupports)
        {
            switch(alngConstants[intIndex])
            {
                case adAddNew :
                    printf("\n  AddNew");
                    break;

                case adApproxPosition :
                    printf("\n  AbsolutePosition and AbsolutePage");
                    break;

                case adBookmark :
                    printf("\n  Bookmark");
                    break;

                case adDelete :
                    printf("\n  Delete");
                    break;

                case adFind :
                    printf("\n  Find");
                    break;

                case adHoldRecords :
                    printf("\n  Holding Records");
                    break;

                case adMovePrevious :
                    printf("\n  MovePrevious and Move");
                    break;

                case adNotify :
                    printf("\n  Notifications");
                    break;

                case adResync :
                    printf("\n  Resyncing data");
                    break;

                case adUpdate :
                    printf("\n  Update");
                    break;

                case adUpdateBatch :
                    printf("\n  Batch updating");
                    break;

                default :
                    break;
            }
        }
    }
}

///////////////////////////////////////////////
//                                           //
//    PrintProviderError Function            //
//                                           //
///////////////////////////////////////////////
void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

///////////////////////////////////////////////
//                                           //
//    PrintComError Function                 //
//                                           //
///////////////////////////////////////////////
void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndSupportsCpp

请参阅

Recordset 对象 | Supports 方法


Type 属性范例 (Field) (VC++)

本范例通过显示与 Employees 表中所有 Field 对象的 Type 属性值对应的常量名，来演示 Type 属性。运行此过程需要 FieldType 函数。

// BeginTypeFieldCpp
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void TypeX(void);
_bstr_t FieldType(int intType);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

///////////////////////////////////////////////
//                                           //
//    Main Function                          //
//                                           //
///////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    TypeX();

    ::CoUninitialize();
}

///////////////////////////////////////////////
//                                           //
//             TypeX Function                //
//                                           //
///////////////////////////////////////////////
void TypeX(void)
{
    HRESULT  hr = S_OK;

    // Define string variables.
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
        "Initial Catalog='pubs';Integrated Security='SSPI';");

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr  pRstEmployees  = NULL;
    FieldsPtr  pFldLoop      = NULL;

    try
    {
        // Open recordset with data from Employee table.
        TESTHR(pRstEmployees.CreateInstance(__uuidof(Recordset)));
        pRstEmployees->Open ("employee",strCnn,
            adOpenForwardOnly, adLockReadOnly, adCmdTable);

        printf("Fields in Employee Table:\n\n");

        // Enumerate the Fields collection of the Employees table.
        pFldLoop = pRstEmployees->GetFields();
        int intLine = 0;
        for (int intFields = 0; intFields < (int)pFldLoop->
            GetCount(); intFields++)
        {
            _variant_t Index;
            Index.vt = VT_I2;
            Index.iVal = intFields;
            printf("  Name: %s\n" ,
                (LPCSTR) pFldLoop->GetItem(Index)->GetName());
            printf("  Type: %s\n\n",
                (LPCTSTR)FieldType(pFldLoop->GetItem(Index)->Type));
            intLine++;
            if(intLine % 5 == 0)
            {
                printf("Press any key to continue...");
                getch();
                system("cls");
            }
        }
    }
    catch (_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstEmployees->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    if (pRstEmployees)
        if (pRstEmployees->State == adStateOpen)
            pRstEmployees->Close();
}

///////////////////////////////////////////////
//                                           //
//             FieldType Function            //
//                                           //
///////////////////////////////////////////////
_bstr_t FieldType(int intType)
{
        _bstr_t strType;
        switch(intType)
        {
            case adChar:
                 strType = "adChar";
                break;
            case adVarChar:
                strType = "adVarChar";
                break;
            case adSmallInt:
                strType = "adSmallInt";
                break;
            case adUnsignedTinyInt:
                strType = "adUnsignedTinyInt";
                break;
            case adDBTimeStamp:
                strType = "adDBTimeStamp";
                break;
            default:
                break;
        }
        return strType;
}

///////////////////////////////////////////////
//                                           //
//    PrintProviderError Function            //
//                                           //
///////////////////////////////////////////////
void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

///////////////////////////////////////////////
//                                           //
//    PrintComError Function                 //
//                                           //
///////////////////////////////////////////////
void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndTypeFieldCpp

请参阅

Field 对象 | Type 属性


Type 属性范例 (Property) (VC++)

本范例演示 Type 属性。这是列出集合（如 Properties、Fields 等等）的名称和类型的实用程序模型。

不需要打开 Recordset 即可访问其 Properties 集合；在 Recordset 对象实例化时它们即已存在。但是，将 CursorLocation 属性设置为 adUseClient 会向 Recordset 对象的 Properties 集合添加若干个动态属性，这将给范例增添一些趣味。为了达到说明的效果，在此使用 Item 属性来访问每个 Property 对象。

// BeginTypePropertyCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include<conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void TypeX();
void PrintComError(_com_error &e);

//////////////////////////////////////////////////////////
//                                                      //
//     Main Function                                    //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    TypeX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//        TypeX Function                                //
//                                                      //
//////////////////////////////////////////////////////////
void TypeX()
{
    HRESULT  hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace
    _RecordsetPtr  pRst  = NULL;
    PropertyPtr pProperty = NULL;

    //Define Other Variables
    _bstr_t strMsg;
    _variant_t vIndex;
    int intLineCnt = 0;

    try
    {
        TESTHR(pRst.CreateInstance (__uuidof(Recordset)));

        // Set the Recordset Cursor Location
        pRst->CursorLocation = adUseClient;

        for (short iIndex = 0; iIndex <= (pRst->Properties->
            GetCount() - 1);iIndex++)
        {
            vIndex = iIndex;
            pProperty = pRst->Properties->GetItem(vIndex);

            int propType = (int)pProperty->GetType();
            switch(propType)
            {
                case adBigInt:
                    strMsg = "adBigInt";
                    break;
                case adBinary:
                    strMsg = "adBinary";
                    break;
                case adBoolean:
                    strMsg = "adBoolean";
                    break;
                case adBSTR:
                    strMsg = "adBSTR";
                    break;
                case adChapter:
                    strMsg = "adChapter";
                    break;
                case adChar:
                    strMsg = "adChar";
                    break;
                case adCurrency:
                    strMsg = "adCurrency";
                    break;
                case adDate:
                    strMsg = "adDate";
                    break;
                case adDBDate:
                    strMsg = "adDBDate";
                    break;
                case adDBTime:
                    strMsg = "adDBTime";
                    break;
                case adDBTimeStamp:
                    strMsg = "adDBTimeStamp";
                    break;
                case adDecimal:
                    strMsg = "adDecimal";
                    break;
                case adDouble:
                    strMsg = "adDouble";
                    break;
                case adEmpty:
                    strMsg = "adEmpty";
                    break;
                case adError:
                    strMsg = "adError";
                    break;
                case adFileTime:
                    strMsg = "adFileTime";
                    break;
                case adGUID:
                    strMsg = "adGUID";
                    break;
                case adIDispatch:
                    strMsg = "adIDispatch";
                    break;
                case adInteger:
                    strMsg = "adInteger";
                    break;
                case adIUnknown:
                    strMsg = "adIUnknown";
                    break;
                case adLongVarBinary:
                    strMsg = "adLongVarBinary";
                    break;
                case adLongVarChar:
                    strMsg = "adLongVarChar";
                    break;
                case adLongVarWChar:
                    strMsg = "adLongVarWChar";
                    break;
                case adNumeric:
                    strMsg = "adNumeric";
                    break;
                case adPropVariant:
                    strMsg = "adPropVariant";
                    break;
                case adSingle:
                    strMsg = "adSingle";
                    break;
                case adSmallInt:
                    strMsg = "adSmallInt";
                    break;
                case adTinyInt:
                    strMsg = "adTinyInt";
                    break;
                case adUnsignedBigInt:
                    strMsg = "adUnsignedBigInt";
                    break;
                case adUnsignedInt:
                    strMsg = "adUnsignedInt";
                    break;
                case adUnsignedSmallInt:
                    strMsg = "adUnsignedSmallInt";
                    break;
                case adUnsignedTinyInt:
                    strMsg = "adUnsignedTinyInt";
                    break;
                case adUserDefined:
                    strMsg = "adUserDefined";
                    break;
                case adVarBinary:
                    strMsg = "adVarBinary";
                    break;
                case adVarChar:
                    strMsg = "adVarChar";
                    break;
                case adVariant:
                    strMsg = "adVariant";
                    break;
                case adVarNumeric:
                    strMsg = "adVarNumeric";
                    break;
                case adVarWChar:
                    strMsg = "adVarWChar";
                    break;
                case adWChar:
                    strMsg = "adWChar";
                    break;
                default:
                    strMsg = "*UNKNOWN*";
                    break;
            }

            intLineCnt++;
            if (intLineCnt%20 == 0)
            {
                printf("\nPress any key to continue...\n");
                getch();
            }
            printf ("Property %d : %s,Type = %s\n",iIndex,
                (LPCSTR)pProperty->GetName(),(LPCSTR)strMsg);
        }
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        PrintComError(e);
    }
}

//////////////////////////////////////////////////////////
//                                                      //
//      PrintComError Function                          //
//                                                      //
//////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{

    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

    // Print Com errors.
    printf("Error\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    printf("\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndTypePropertyCpp

请参阅

Property 对象 | Type 属性


Update 和 CancelUpdate 方法范例 (VC++)

本范例演示 Update 和 CancelUpdate 方法。

// BeginUpdateCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <stdio.h>
#include <ole2.h>
#include <malloc.h>
#include <conio.h>
#include "UpdateX.h"

// Function Declartion.
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void UpdateX(void);
void UpdateX2(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

     UpdateX();

     //Wait here for user to see the output..
     printf("\nPress any key to continue...");
     getch();

     //Clear the screen for the next display
     system("cls");

     UpdateX2();

     ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//      UpdateX Function                                //
//                                                      //
//////////////////////////////////////////////////////////
void UpdateX(void)
{
    HRESULT hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr pRstEmployees  = NULL;

    // Define string variables.
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    IADORecordBinding   *picRs   = NULL;  // Interface Pointer declared
    CEmployeeRs emprs;             // C++ Class object.

    try
    {
        // Open recordset with names from Employee table.
        TESTHR(pRstEmployees.CreateInstance(__uuidof(Recordset)));
        pRstEmployees->CursorType = adOpenKeyset;
        pRstEmployees->LockType = adLockOptimistic;
        pRstEmployees->Open("SELECT fname, lname FROM Employee "
            "ORDER BY lname",strCnn,adOpenKeyset,adLockOptimistic,
            adCmdText);

        // Store original data.
        _bstr_t strOldFirst = pRstEmployees->Fields->
            GetItem("fname")->Value;
        _bstr_t strOldLast  = pRstEmployees->Fields->
            GetItem("lname")->Value;

        //Change data in edit buffer.
        pRstEmployees->Fields->GetItem("fname")->Value =
            (_bstr_t)("Linda");
        pRstEmployees->Fields->GetItem("lname")->Value =
            (_bstr_t)("Kobara");

        // Show contents of buffer and get user input.
        printf("\n\nEdit in progress:\n\n");

        printf("Original data =  %s %s \n",
            (LPSTR)strOldFirst,(LPSTR)strOldLast);

        printf("Data in buffer =  %s %s",
            (LPSTR)(_bstr_t) pRstEmployees->Fields->
            GetItem("fname")->Value,\
            (LPSTR) (_bstr_t) pRstEmployees->Fields->
            GetItem("lname")->Value);

        // Ask if the User wants to Update
        printf("\n\nUse Update to replace the original data with the"
               " buffered data in the Recordset? (y/n): ");
        char chKey = getch();

        if(toupper(chKey) == 'Y')
            pRstEmployees->Update();
        else
            pRstEmployees->CancelUpdate();

        //Open an IADORecordBinding interface pointer which
        //we'll use for binding Recordset to a class.
        TESTHR(pRstEmployees->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        //Bind the Recordset to a C++ Class here.
        TESTHR(picRs->BindToRecordset(&emprs));

        pRstEmployees->MoveFirst();

        // Show the resulting data.
        printf("\nData in recordset =  %s %s", emprs.le_fnameStatus ==
            adFldOK ? emprs.m_sze_fname : "<NULL>",
            emprs.le_lnameStatus == adFldOK ?
            emprs.m_sze_lname : "<NULL>");

        // Restore original data because this is a demonstration.
        if ((strcmp((char *)strOldFirst,emprs.m_sze_fname) &&
             strcmp((char *)strOldLast,emprs.m_sze_lname)))
        {
            pRstEmployees->Fields->GetItem("fname")->Value = strOldFirst;
            pRstEmployees->Fields->GetItem("lname")->Value = strOldLast;
            pRstEmployees->Update();
        }
    }
    catch(_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstEmployees->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (pRstEmployees)
        if (pRstEmployees->State == adStateOpen)
            pRstEmployees->Close();
}

// The next example demonstrates the Update method
// in conjunction with the AddNew method.

//////////////////////////////////////////////////////////
//                                                      //
//           UpdateX2 Function                          //
//                                                      //
//////////////////////////////////////////////////////////
void UpdateX2(void)
{
    HRESULT hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _ConnectionPtr pConnection        = NULL;
    _RecordsetPtr pRstEmployees = NULL;

    // Define string variables.
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    IADORecordBinding   *picRs  = NULL;  // Interface Pointer declared
    CEmployeeRs1 emprs;            // C++ Class object.

    try
    {
        // Open a connection.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
         pConnection->Open(strCnn,"","",NULL);

        // Open recordset with data from Employee table.
        TESTHR(pRstEmployees.CreateInstance(__uuidof(Recordset)));
        pRstEmployees->CursorType = adOpenKeyset;
        pRstEmployees->LockType = adLockOptimistic;
        pRstEmployees->Open("employee",
            _variant_t((IDispatch*)pConnection,true),
            adOpenKeyset, adLockOptimistic,adCmdTable);

        pRstEmployees->AddNew();
        _bstr_t strEmpID = "B-S55555M";
        pRstEmployees->Fields->GetItem("emp_id")->Value = strEmpID;
        pRstEmployees->Fields->GetItem("fname")->Value =
            (_bstr_t) ("Bill");
        pRstEmployees->Fields->GetItem("lname")->Value =
            (_bstr_t) ("Sornsin");

        // Show contents of buffer and get user input.
        printf("\n\nAddNew in progress:\n\n");

        printf("Data in buffer = %s ,  %s %s",
            (LPSTR) (_bstr_t) pRstEmployees->Fields->
            GetItem("emp_id")->Value,
            (LPSTR) (_bstr_t) pRstEmployees->Fields->
            GetItem("fname")->Value,
            (LPSTR) (_bstr_t) pRstEmployees->Fields->
            GetItem("lname")->Value);

        printf("\n\nUse Update to save buffer to recordset?(y/n):");
        char chKey = getch();

        if(toupper(chKey) == 'Y')
        {
            pRstEmployees->Update();

            //Open an IADORecordBinding interface pointer which
            //we'll use for binding Recordset to a class.
            TESTHR(pRstEmployees->QueryInterface(
                __uuidof(IADORecordBinding),(LPVOID*)&picRs));

            //Bind the Recordset to a C++ Class here
            TESTHR(picRs->BindToRecordset(&emprs));

            // Go to the new record and show the resulting data.
            printf ("\n\nData in recordset =  %s ,  %s %s",
                emprs.le_empidStatus == adFldOK ?
                emprs.m_sze_empid : "<NULL>",
                emprs.le_fnameStatus == adFldOK ?
                emprs.m_sze_fname : "<NULL>",
                emprs.le_lnameStatus == adFldOK ?
                emprs.m_sze_lname : "<NULL>");
        }
        else
        {
            pRstEmployees->CancelUpdate();
            printf("\n\nNo new record added.\n");
        }
        // Delete new data because this is a demonstration.
        _bstr_t strSQLDelete("DELETE FROM employee WHERE emp_id = '" +
            strEmpID + "'");
        pConnection->Execute(strSQLDelete ,NULL,adExecuteNoRecords);
    }

    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        // Pass a connection pointer accessed from the Connection.
        PrintProviderError(pConnection);
        PrintComError(e);
    }

    // Clean up objects before exit.
    //Release the IADORecordset Interface here
    if (picRs)
        picRs->Release();

    if (pRstEmployees)
        if (pRstEmployees->State == adStateOpen)
            pRstEmployees->Close();
    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

//////////////////////////////////////////////////////////
//                                                      //
//       PrintProviderError Function                    //
//                                                      //
//////////////////////////////////////////////////////////
void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

//////////////////////////////////////////////////////////
//                                                      //
//      PrintComError Function                          //
//                                                      //
//////////////////////////////////////////////////////////
void PrintComError(_com_error &e)
{

    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

    // Print Com errors.
    printf("Error\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    printf("\tSource = %s\n", (LPCSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndUpdateCpp

UpdateX.h

// BeginUpdateH
#include "icrsint.h"

//This Class extracts only fname,lname from employee table.
class CEmployeeRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CEmployeeRs)
    // fname is the 1st field in the recordset
    ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_sze_fname,
         sizeof(m_sze_fname), le_fnameStatus, FALSE)
    // lname is the 2nd field in the recordset.
    ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_sze_lname,
         sizeof(m_sze_lname), le_lnameStatus, FALSE)

END_ADO_BINDING()

public:
   CHAR   m_sze_lname[31];
   ULONG  le_lnameStatus;
   CHAR   m_sze_fname[21];
   ULONG  le_fnameStatus;
};

//This Class extracts only empid,fname,lname,from employee table.
class CEmployeeRs1 : public CADORecordBinding
{
BEGIN_ADO_BINDING(CEmployeeRs1)
    // emp_id is the 1st field in the table.
    ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_sze_empid,
        sizeof(m_sze_empid), le_empidStatus, FALSE)
    // fname is the 2nd field in the table.
   ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_sze_fname,
         sizeof(m_sze_fname), le_fnameStatus, FALSE)
    // lname is the 4rt field in the table.
   ADO_VARIABLE_LENGTH_ENTRY2(4, adVarChar, m_sze_lname,
         sizeof(m_sze_lname), le_lnameStatus, FALSE)

END_ADO_BINDING()

public:
   CHAR   m_sze_empid[10];
   ULONG  le_empidStatus;
   CHAR   m_sze_lname[31];
   ULONG  le_lnameStatus;
   CHAR   m_sze_fname[21];
   ULONG  le_fnameStatus;
};
// EndUpdateH

请参阅

CancelUpdate 方法 | Update 方法


UpdateBatch 和 CancelBatch 方法范例 (VC++)

本范例演示 UpdateBatch 和 CancelBatch 方法。

// BeginUpdateBatchCpp
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>
#include "UpdateBatchX.h"

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void UpdateBatchX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

//////////////////////////////////////////////////////////
//                                                      //
//       Main Function                                  //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    UpdateBatchX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//      UpdateBatchX Function                           //
//                                                      //
//////////////////////////////////////////////////////////
void UpdateBatchX(void)
{
   HRESULT  hr = S_OK;

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr  pRstTitles   = NULL;

    // Define string variables.
    _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    IADORecordBinding *picRs    = NULL;    // Interface Pointer Declared
    CTitleRs titlers;             // C++ Class Object

    try
    {
        // Open titles table.
        TESTHR(pRstTitles.CreateInstance(__uuidof(Recordset)));
        pRstTitles->CursorType = adOpenKeyset;
        pRstTitles->LockType = adLockBatchOptimistic;
        pRstTitles->Open ("titles", strCnn,
            adOpenKeyset, adLockBatchOptimistic, adCmdTable);

        // Open IADORecordBinding interface pointer for binding
        // Recordset to a class
        TESTHR(pRstTitles->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        // Binding the Recordset to a C++ Class
        TESTHR(picRs->BindToRecordset(&titlers));
        pRstTitles->MoveFirst();

        // Loop through recordset and ask user if she wants,
        // to change the type for a specified title.
        while (!(pRstTitles->EndOfFile))
        {
            // Compare type with psychology
            if (!strcmp( (char *)strtok(titlers.m_szt_Type," "),
                "psychology" ))
            {
                printf("\n\nTitle: %s \nChange type to self_help?(y/n):",
                    titlers.m_szt_Title);
                char chKey;
                chKey = getch();
                if(toupper(chKey) == 'Y')
                {
                    // Change type to self_help.
                    pRstTitles->Fields->GetItem("type")->Value =
                        (_bstr_t)("self_help");
                }
            }
            pRstTitles->MoveNext();
        }

        // Ask the user if she wants to commit to all the
        // changes made above.
        printf("\n\nSave all changes?");
        char chKey;
        chKey = getch();
        if(toupper(chKey) == 'Y')
        {
            pRstTitles->UpdateBatch(adAffectAll);
        }
        else
        {
            pRstTitles->CancelBatch(adAffectAll);
        }

        // Print current data in recordset.
        pRstTitles->Requery(adOptionUnspecified);

        // Open IADORecordBinding interface pointer for Binding Recordset to a class
        TESTHR(pRstTitles->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        // ReBinding the Recordset to a C++ Class.
        TESTHR(picRs->BindToRecordset(&titlers));

        // Move to the first record of the title table
        pRstTitles->MoveFirst();

        //Clear the screen for the next display.
        system("cls");

        while (!pRstTitles->EndOfFile)
        {
            printf("%s -  %s\n",
                titlers.lt_TitleStatus == adFldOK ?
                titlers.m_szt_Title :"<NULL>",
                titlers.lt_TypeStatus == adFldOK ?
                titlers.m_szt_Type :"<NULL>");
            pRstTitles->MoveNext();
        }

        pRstTitles->MoveFirst();

        // Restore original data because this is demonstration.
        while (!(pRstTitles->EndOfFile))
        {
            // Compare type with psychology
            if(!strcmp( (char *)strtok(titlers.m_szt_Type," "),
                "self_help" ))
            {
                // Change type to psychology.
                pRstTitles->Fields->GetItem("type")->Value =
                    (_bstr_t)("psychology");
            }
            pRstTitles->MoveNext();
        }
    }
    catch (_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstTitles->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    if (pRstTitles)
        if (pRstTitles->State == adStateOpen)
        {
            pRstTitles->UpdateBatch(adAffectAll);
            pRstTitles->Close();
        }
}

//////////////////////////////////////////////////////////
//                                                      //
//    PrintProviderError Function                       //
//                                                      //
//////////////////////////////////////////////////////////
void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

//////////////////////////////////////////////////////////
//                                                      //
//      PrintComError Function                          //
//                                                      //
//////////////////////////////////////////////////////////

void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndUpdateBatchCpp

UpdateBatchX.h

// BeginUpdateBatchH
#include "icrsint.h"

//This class extracts titles and type from Titles table
class CTitleRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CTitleRs)
        // Column title is the 2nd field in the table
        ADO_VARIABLE_LENGTH_ENTRY2(2,adVarChar,m_szt_Title,
            sizeof(m_szt_Title),lt_TitleStatus,FALSE)
        // Column type is the 3rd field in the table
        ADO_VARIABLE_LENGTH_ENTRY2(3,adVarChar,m_szt_Type,
            sizeof(m_szt_Type),lt_TypeStatus,TRUE)
END_ADO_BINDING()

public:
    CHAR m_szt_Title[81];
    ULONG lt_TitleStatus;
    CHAR m_szt_Type[13];
    ULONG lt_TypeStatus;
};
// EndUpdateBatchH

请参阅

CancelBatch 方法 | UpdateBatch 方法


Value 属性范例 (VC++)

本范例通过显示 Employees 表的字段和属性值来演示 Field 和 Property 对象的 Value 属性。

// BeginValueCpp
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void ValueX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

//////////////////////////////////////////////////////////
//                                                      //
//    Main Function                                     //
//                                                      //
//////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    ValueX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//              ValueX Function                         //
//                                                      //
//////////////////////////////////////////////////////////
void ValueX(void)
{
   HRESULT  hr = S_OK;

    // Define string variables.
   _bstr_t strCnn("Provider='sqloledb';Data Source='MySqlServer';"
            "Initial Catalog='pubs';Integrated Security='SSPI';");

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _RecordsetPtr  pRstEmployees  = NULL;
    FieldsPtr    pFldLoop    = NULL;
    PropertiesPtr  pPrpLoop    = NULL;
    _variant_t vtIndex;
    vtIndex.vt = VT_I2;

    try
    {
        // Open recordset with data from Employee table.
        TESTHR(pRstEmployees.CreateInstance(__uuidof(Recordset)));
        pRstEmployees->Open ("employee",strCnn ,
            adOpenForwardOnly, adLockReadOnly, adCmdTable);

        printf("Field values in rstEmployees\n\n");

        // Enumerate the Fields collection of the Employees table.
        pFldLoop = pRstEmployees->GetFields();

        for (int intFields = 0; intFields < (int)pFldLoop->GetCount(); intFields++)
        {
            vtIndex.iVal = intFields;

            // Because Value is the default property of a
            // Field object,the use of the actual keyword
            // here is optional.
            printf(" %s = %s\n\n" ,
                (LPCSTR) pFldLoop->GetItem(vtIndex)->GetName(),
                (LPCSTR) (_bstr_t) pFldLoop->GetItem(vtIndex)->Value);
        }

        printf("Press any key to continue...\n\n");
        getch();
        printf("Property values in rstEmployees\n\n");

        // Enumerate the Properties collection of the Recordset object.
        pPrpLoop = pRstEmployees->GetProperties();
        int intLine = 0;

        for (int intProperties = 0; intProperties < (int)pPrpLoop->
            GetCount(); intProperties++)
        {
            vtIndex.iVal = intProperties;

            // Because Value is the default property of a
            // Property object,the use of the actual keyword
            // here is optional.
            _variant_t propValue = pPrpLoop->GetItem(vtIndex)->Value;
            switch(propValue.vt)
            {

            case (VT_BOOL):
                     if(propValue.boolVal)
                     {
                        printf(" %s = True\n\n",(LPCSTR) pPrpLoop->
                            GetItem(vtIndex)->GetName());
                     }
                     else
                     {
                         printf(" %s = False\n\n",(LPCSTR) pPrpLoop->
                            GetItem(vtIndex)->GetName());
                     }
                break;

            case (VT_I4):
                printf(" %s = %d\n\n",(LPCSTR) pPrpLoop->
                    GetItem(vtIndex)->GetName(),
                    pPrpLoop->GetItem(vtIndex)->Value.lVal);
                break;

            case (VT_EMPTY):
                printf(" %s = \n\n",(LPCSTR) pPrpLoop->
                    GetItem(vtIndex)->GetName());
                break;

            default:
                break;
            }

            intLine++;
                if (intLine % 10 == 0)
                {
                    printf("\nPress any key to continue...");
                     getch();

                    //Clear the screen for the next display
                    system("cls");
                }
        }
    }
    catch (_com_error &e)
    {
       // Notify the user of errors if any.
       // Pass a connection pointer accessed from the Recordset.
        _variant_t vtConnect = pRstEmployees->GetActiveConnection();

        // GetActiveConnection returns connect string if connection
        // is not open, else returns Connection object.
        switch(vtConnect.vt)
        {
            case VT_BSTR:
                PrintComError(e);
                break;
            case VT_DISPATCH:
                PrintProviderError(vtConnect);
                break;
            default:
                printf("Errors occured.");
                break;
        }
    }

    if (pRstEmployees)
        if (pRstEmployees->State == adStateOpen)
            pRstEmployees->Close();
}

//////////////////////////////////////////////////////////
//                                                      //
//    PrintProviderError Function                       //
//                                                      //
//////////////////////////////////////////////////////////
void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

//////////////////////////////////////////////////////////
//                                                      //
//      PrintComError Function                          //
//                                                      //
//////////////////////////////////////////////////////////
void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndValueCpp

请参阅

Field 对象 | Property 对象 | Value 属性


Version 属性范例 (VC++)

本范例使用 Connection 对象的 Version 属性来显示当前 ADO 版本。范例中还使用若干动态属性来显示：

  • 当前 DBMS 名称和版本。
  • OLE DB 版本。
  • 提供者名称和版本。
  • ODBC 版本。
  • ODBC 驱动程序名称和版本。
// BeginVersionCpp
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
    no_namespace rename("EOF", "EndOfFile")

#include <ole2.h>
#include <stdio.h>
#include <conio.h>

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void VersionX(void);
void PrintProviderError(_ConnectionPtr pConnection);
void PrintComError(_com_error &e);

//////////////////////////////////////////////////////////
//                                                      //
//       Main Function                                  //
//                                                      //
//////////////////////////////////////////////////////////

void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    VersionX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//         VersionX Function                            //
//                                                      //
//////////////////////////////////////////////////////////
void VersionX(void)
{
    HRESULT   hr = S_OK;

    // Define string variables.
    _bstr_t strCnn("driver={SQL Server};server='MySqlServer';"
        "user id='MyUserId';password='MyPassword';database='pubs';");

    // Define ADO object pointers.
    // Initialize pointers on define.
    // These are in the ADODB::  namespace.
    _ConnectionPtr    pConnection     = NULL;

    try
    {
        // Open connection.
        TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
        pConnection->Open (strCnn, "", "", adConnectUnspecified);

        printf("ADO Version   : %s\n\n",(LPCSTR) pConnection->Version);
        printf("DBMS Name   : %s\n\n",(LPCSTR) (_bstr_t)
            pConnection->Properties->GetItem("DBMS Name")->Value);
        printf("DBMS Version   : %s\n\n",(LPCSTR) (_bstr_t)
            pConnection->Properties->GetItem("DBMS Version")->Value);
        printf("OLE DB Version   : %s\n\n",(LPCSTR) (_bstr_t)
            pConnection->Properties->GetItem("OLE DB Version")->Value);
        printf("Provider Name   : %s\n\n",(LPCSTR) (_bstr_t)
            pConnection->Properties->GetItem("Provider Name")->Value);
        printf("Provider Version   : %s\n\n",(LPCSTR) (_bstr_t)
            pConnection->Properties->GetItem("Provider Version")->Value);
        printf("Driver Name   : %s\n\n",(LPCSTR) (_bstr_t)
            pConnection->Properties->GetItem("Driver Name")->Value);
        printf("Driver Version   : %s\n\n",(LPCSTR) (_bstr_t)
            pConnection->Properties->GetItem("Driver Version")->Value);
        printf("Driver ODBC Version   : %s\n\n",(LPCSTR) (_bstr_t)
            pConnection->Properties->GetItem("Driver ODBC Version")->Value);

    }

    catch (_com_error &e)
    {
        // Notify the user of errors if any.
        PrintProviderError(pConnection);
        PrintComError(e);
    }

    if (pConnection)
        if (pConnection->State == adStateOpen)
            pConnection->Close();
}

//////////////////////////////////////////////////////////
//                                                      //
//     PrintProviderError Function                      //
//                                                      //
//////////////////////////////////////////////////////////
void PrintProviderError(_ConnectionPtr pConnection)
{
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr    pErr  = NULL;

    if( (pConnection->Errors->Count) > 0)
    {
        long nCount = pConnection->Errors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0; i < nCount; i++)
        {
            pErr = pConnection->Errors->GetItem(i);
            printf("Error number: %x\t%s\n", pErr->Number,
                (LPCSTR) pErr->Description);
        }
    }
}

//////////////////////////////////////////////////////////
//                                                      //
//      PrintComError Function                          //
//                                                      //
//////////////////////////////////////////////////////////
void PrintComError(_com_error &e)
{
   _bstr_t bstrSource(e.Source());
   _bstr_t bstrDescription(e.Description());

    // Print Com errors.
   printf("Error\n");
   printf("\tCode = %08lx\n", e.Error());
   printf("\tCode meaning = %s\n", e.ErrorMessage());
   printf("\tSource = %s\n", (LPCSTR) bstrSource);
   printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
}
// EndVersionCpp

请参阅

Connection 对象 | Version 属性


Microsoft Visual J++ 中的 ADO 代码范例

通过下列代码范例来学习用 Microsoft Visual J++ 编程时如何使用 ADO 方法和属性。

注意 请将整个代码范例（从开始到结束）粘贴到代码编辑器中。如果只使用部分范例或者丢失了段落格式，范例可能无法正确运行。

方法

  • AddNew 方法范例
  • Append 和 CreateParameter 方法范例
  • AppendChunk 和 GetChunk 方法范例
  • BeginTrans、CommitTrans 和 RollbackTrans 方法范例
  • Cancel 方法范例
  • Clone 方法范例
  • CompareBookmarks 方法范例
  • Delete 方法范例
  • Execute、Requery 和 Clear 方法范例
  • Find 方法范例
  • GetRows 方法范例
  • GetString 方法范例
  • MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法范例
  • NextRecordset 方法范例
  • Open 和 Close 方法范例
  • OpenSchema 方法范例
  • Refresh 方法范例
  • Resync 方法范例
  • Save 和 Open 方法范例
  • Supports 方法范例
  • Update 和 CancelUpdate 方法范例
  • UpdateBatch 和 CancelBatch 方法范例

Properties

  • AbsolutePage、PageCount 和 PageSize 属性范例
  • AbsolutePosition 和 CursorLocation 属性范例
  • ActiveCommand 属性范例
  • ActiveConnection、CommandText、CommandTimeout、CommandType、Size 和 Direction 属性范例
  • ActualSize 和 DefinedSize 属性范例
  • Attributes 和 Name 属性范例
  • BOF、EOF 和 Bookmark 属性范例
  • CacheSize 属性范例
  • ConnectionString、ConnectionTimeout 和 State 属性范例
  • Count 属性范例
  • CursorType、LockType 和 EditMode 属性范例
  • Description、HelpContext、HelpFile、NativeError、Number、Source 和 SQLState 属性范例
  • Filter 和 RecordCount 属性范例
  • IsolationLevel 和 Mode 属性范例
  • Item 属性范例
  • MarshalOptions 属性范例
  • MaxRecords 属性范例
  • NumericScale 和 Precision 属性范例
  • Optimize 属性范例
  • OriginalValue 和 UnderlyingValue 属性范例
  • Prepared 属性范例
  • Provider 和 DefaultDatabase 属性范例
  • Sort 属性范例
  • Source 属性范例
  • State 属性范例
  • Status 属性范例
  • StayInSync 属性范例
  • Type 属性范例 (Fields)
  • Type 属性范例 (Property)
  • Value 属性范例
  • Version 属性范例

请参阅

Microsoft Visual Basic 中的 ADO 代码范例 | Microsoft Visual Basic Scripting Edition 中的 ADO 代码范例 | Microsoft Visual C++ 中的 ADO 代码范例


AbsolutePage、PageCount 和 PageSize 属性范例 (VJ++)

本范例使用 AbsolutePage、PageCount 和 PageSize 属性显示 Employees 表中的姓名和受雇日期，每次显示五个记录。

// BeginAbsolutePageJ
// The WFC class includes the ADO objects.

import com.ms.wfc.data.*;
import java.io.* ;

public class AbsolutePageX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      AbsolutePageX();
      System.exit(0);
   }

   // AbsolutePageX function

   static void AbsolutePageX()
   {
      // Define ADO Objects.
      Recordset rstEmployees = null;

      // Declarations.
      BufferedReader in = new BufferedReader (new
         InputStreamReader(System.in));
      String line = null;
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
         + "Initial Catalog='Pubs';Integrated Security='SSPI';";

      String strName;
      String strFName;
      String strLName;
      String strHDate;
      int intPage;
      int intRecord;

      try
      {
         rstEmployees = new Recordset();

         // Use client cursor to enable AbsolutePosition property.
         rstEmployees.setCursorLocation( AdoEnums.CursorLocation.CLIENT);

         // Open a recordset using client cursor for the Employees table.
         rstEmployees.open("employee", strCnn,
            AdoEnums.CursorType.FORWARDONLY,
            AdoEnums.LockType.READONLY,
            AdoEnums.CommandType.TABLE);

         // Display names and hire dates, five records at a time.

         rstEmployees.setPageSize(5);
         int intPageCount = rstEmployees.getPageCount();
         for ( intPage = 1; intPage <= intPageCount; intPage++)
         {
            strName = "";
            rstEmployees.setAbsolutePage(intPage);
            for ( intRecord = 1; intRecord <= rstEmployees.getPageSize();
               intRecord++)
            {
               strFName = rstEmployees.getField("fname").getString();
               strLName = rstEmployees.getField("lname").getString();
               strHDate = rstEmployees.getField("hire_date").getString();

               strHDate = strHDate.substring(5,7) + "/" +
                  strHDate.substring(8,10) +
                  "/" + strHDate.substring(2,4);

               strName = strName + "\n" + strFName + " " + strLName +
                  "  " + strHDate;
               rstEmployees.moveNext();
               if ( rstEmployees.getEOF())
                  break;
            }
            System.out.println(strName);
            // Get user input to display next records.

            System.out.println("\n\nPress <Enter> key to Continue.");
            line = in.readLine();
         }
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // Check for null pointer for connection object.
         if (rstEmployees.getActiveConnection()==null)
            System.out.println("Exception: " + ae.getMessage());

         // As passing a Recordset, check for null pointer first.
         if (rstEmployees != null)
         {
            PrintProviderError(rstEmployees.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }
      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }
      finally
      {
         // Cleanup objects before exit.
         if (rstEmployees != null)
            if (rstEmployees.getState() == 1)
               rstEmployees.close();
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   //.PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndAbsolutePageJ

请参阅

AbsolutePage 属性 | PageCount 属性 | PageSize 属性 | Recordset 对象


AbsolutePosition 和 CursorLocation 属性范例 (VJ++)

本范例演示 AbsolutePosition 属性如何跟踪循环的进度。该循环用于枚举 Recordset 中的所有记录。范例中使用了 CursorLocation 属性，通过将游标设置为客户端游标来启用 AbsolutePosition 属性。

// BeginAboslutePositionJ
import com.ms.wfc.data.*;
import java.io.*;

public class AbsolutePositionX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      AbsolutePositionX();
      System.exit(0);
   }

   //.AbsolutePositionX function

   static void AbsolutePositionX()
   {

      // define ADO Objects.
      Recordset rstEmployees = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader(new InputStreamReader(System.in));
      String line = null;
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';" +
         "Initial Catalog='Pubs';Integrated Security='SSPI';";

      String strLName;
      String strMessage;
      String strAbsolutePosition,strRecordCount;
      int intAbsolutePosition;
      int intRecordCount;
      int intChoice;

      try
      {

         rstEmployees = new Recordset();

         // Use client cursor to enable AbsolutePosition property.
         rstEmployees.setCursorLocation( AdoEnums.CursorLocation.CLIENT);

         // Open a recordset for Employees table using a client cursor.
         rstEmployees.open("employee", strCnn,
            AdoEnums.CursorType.FORWARDONLY ,
            AdoEnums.LockType.READONLY,
            AdoEnums.CommandType.TABLE);

         // Enumerate Recordset.
         while ( !rstEmployees.getEOF()) // continuous loop
         {
            intRecordCount = rstEmployees.getRecordCount();
            strRecordCount = Integer.toString(intRecordCount);

            // Read data field in the variables.
            strLName = rstEmployees.getField("lname").getString();
            intAbsolutePosition = rstEmployees.getAbsolutePosition();
            strAbsolutePosition = Integer.toString(intAbsolutePosition);

            // Display current record information.
            strMessage = "\nEmployee: " + strLName + "\n" + "(Record " +
               strAbsolutePosition + " of " +strRecordCount + " )";
            System.out.println(strMessage);
            System.out.println(
               "\nDo you want to continue (1 -> Yes / 2 -> No)?");
            //user types a number followed by enter (cr-lf).
            line = in.readLine().trim();
            intChoice = Integer.parseInt(line);
            if ( intChoice != 1)
               break;
            rstEmployees.moveNext();
         }
      }

      catch( NumberFormatException ne)
      {
         System.out.println("\nException : Integer Input required.");
         System.exit(0);
      }

      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // Check for null pointer for connection object.
         if (rstEmployees.getActiveConnection()== null)
            System.out.println("Exception: " + ae.getMessage());
         // As passing a Recordset, check for null pointer first.
         if (rstEmployees != null)
         {
            PrintProviderError(rstEmployees.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstEmployees != null)
            if (rstEmployees.getState() == 1)
               rstEmployees.close();
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   //.PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}

// EndAbsolutePositionJ

请参阅

AbsolutePosition 属性 | CursorLocation 属性 | Recordset 对象


ActiveCommand 属性范例 (VJ++)

本范例演示 ActiveCommand 属性。

向子例程提供一个 Recordset 对象，该对象的 ActiveCommand 属性用于显示创建 Recordset 的命令文本和参数。

// BeginActiveCommandJ
import com.ms.wfc.data.*;
import java.io.* ;

public class ActiveCommandX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      ActiveCommandX();
      System.exit(0);
   }

   // ActiveCommandX function

   static void ActiveCommandX()
   {
      // Define ADO Objects.
      Connection cnConn1 = null;
      Command cmd = null;
      Recordset rstAuthors = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
         + "Initial Catalog='Pubs';Integrated Security='SSPI';";
      String strName;

      try
      {
         System.out.println("Enter an author's name (e.g., Ringer): ");
         strName = in.readLine().trim();
         cmd = new Command();
         cmd.setCommandText("SELECT * FROM authors WHERE au_lname = ?");
         cmd.getParameters().append(cmd.createParameter("LastName",
            AdoEnums.DataType.CHAR,
            AdoEnums.ParameterDirection.INPUT, 20, strName));
         cnConn1 = new Connection();
         cnConn1.open(strCnn);
         cmd.setActiveConnection(cnConn1);
         rstAuthors = cmd.execute(null,AdoEnums.CommandType.TEXT);
         ActiveCommandXprint(rstAuthors);
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstAuthors != null)
         {
            PrintProviderError(rstAuthors.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstAuthors != null)
            if (rstAuthors.getState() == 1)
               rstAuthors.close();
         // Cleanup objects before exit.
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
      }
   }

   // ActiveCommandXprint function
   static void ActiveCommandXprint(Recordset rstp)
   {
      // Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String strName;

      try
      {
         strName = rstp.getActiveCommand().getParameters().
            getItem("LastName").getValue().toString();
         System.out.println("\nCommand text = '" +
            rstp.getActiveCommand().getCommandText() + "'");
         System.out.println("Parameter = '" + strName + "'");
         if(rstp.getBOF())
         {
            System.out.println("Name = '" + strName + "', not found.");
         }
         else
         {
            System.out.println("Name = '" +
               rstp.getField("au_fname").getString() + " " +
               rstp.getField("au_lname").getString() +
               "', author ID = '" +
               rstp.getField("au_id").getString() + "'");
         }
         System.out.println("\nPress <Enter> to continue..");
         in.readLine();
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstp != null)
         {
            PrintProviderError(rstp.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   //.PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}

// EndActiveCommandJ

请参阅

ActiveCommand 属性 | Recordset 对象


ActiveConnection、CommandText、CommandTimeout、CommandType、Size 和 Direction 属性范例 (VJ++)

本范例使用 ActiveConnection、CommandText、CommandTimeout、CommandType、Size 和 Direction 属性来执行存储过程。

// BeginActiveConnectionJ
import com.ms.wfc.data.*;
import java.io.*;

public class ActiveConnectionX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      ActiveConnectionX();
      System.exit(0);
   }

   //.ActiveConnectionX function

   static void ActiveConnectionX()
   {
      // Define ADO Objects.
      Connection cnConn1 = null;
      Command cmdByRoyalty = null;
      Parameter prmByRoyalty = null;
      Recordset rstByRoyalty = null;
      Recordset rstAuthors = null;

      //Declarations.
      String strCnn;
      String strAuthorID;
      String strFName;
      String strLName;
      int intRoyalty ;
      BufferedReader in = new BufferedReader
         (new InputStreamReader (System.in));
      String line = null;

      try
      {
         // Open a connection.

         strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
            + "Initial Catalog='Pubs';Integrated Security='SSPI';";
         cnConn1 = new Connection();
         cnConn1.open(strCnn,"","",AdoEnums.CommandType.UNSPECIFIED);

         // Define a command object for stored procedure.
         cmdByRoyalty = new Command();
         cmdByRoyalty.setActiveConnection(cnConn1);
         cmdByRoyalty.setCommandText("byRoyalty");
         cmdByRoyalty.setCommandType(AdoEnums.CommandType.STOREDPROC);
         cmdByRoyalty.setCommandTimeout(15);

         //Define the stored procedure's input parameter.
         System.out.println ("\nEnter Royalty : ");
         line = in.readLine().trim();
         intRoyalty = Integer.parseInt(line);
         prmByRoyalty = new Parameter ();
         prmByRoyalty.setType(AdoEnums.DataType.INTEGER);
         prmByRoyalty.setSize(3);
         prmByRoyalty.setDirection(AdoEnums.ParameterDirection.INPUT);
         prmByRoyalty.setValue(new Integer(intRoyalty));
         cmdByRoyalty.getParameters().append(prmByRoyalty);

         // Create a recordset by executing the command.

         rstByRoyalty = cmdByRoyalty.execute();

         // Open the Authors table to get author names for display.
         rstAuthors = new Recordset ();
         rstAuthors.open("authors",strCnn,
            AdoEnums.CursorType.FORWARDONLY,
            AdoEnums.LockType.READONLY ,AdoEnums.CommandType.TABLE );

         // Print current data in the recordset,
         // adding author names from Authors table.
         System.out.println("\nAuthors with " + intRoyalty +
            " percent royalty");
         while (!rstByRoyalty.getEOF())
         {
            strAuthorID =  rstByRoyalty.getField("au_id").getString();
            rstAuthors.setFilter("au_id ='" +  strAuthorID + "'");
            strFName = rstAuthors.getField("au_fname").getString();
            strLName = rstAuthors.getField("au_lname").getString();
            System.out.println("\t" + strAuthorID + ", " + strFName
               + " " + strLName);
            rstByRoyalty.moveNext();
         }
         System.out.println("\n\nPress <Enter> key to continue.");
         line = in.readLine();

         //Cleanup objects before exit.
         rstByRoyalty.close();
         rstAuthors.close();
         cnConn1.close();

      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // Check for null pointer for connection object
         if(rstByRoyalty.getActiveConnection()==null)
            System.out.println("Exception: " + ae.getMessage());
         if(rstAuthors.getActiveConnection()==null)
            System.out.println("Exception: " + ae.getMessage());
         // As passing a Recordset, check for null pointer first.
         if (rstByRoyalty != null)
         {
            PrintProviderError(rstByRoyalty.getActiveConnection());
         }
         if (rstAuthors != null)
         {
            PrintProviderError(rstAuthors.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // This catch is required if input string cannot be converted to
      // Integer data type.
      catch ( java.lang.NumberFormatException ne)
      {
         System.out.println("\nException: Integer Input required.");
      }
      // System Read requires this catch.
      catch( java.io.IOException je )
      {
         PrintIOError(je);
      }
      finally
      {
         // Cleanup objects before exit.
         if (rstByRoyalty != null)
            if (rstByRoyalty.getState() == 1)
               rstByRoyalty.close();
         if (rstAuthors != null)
            if (rstAuthors.getState() == 1)
               rstAuthors.close();
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   //.PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}

// EndActiveConnectionJ

请参阅

ActiveConnection 属性 | CommandText 属性 | CommandTimeout 属性 | CommandType 属性 | Direction 属性 | Size 属性


ActualSize 和 DefinedSize 属性范例 (VJ++)

本范例使用 ActualSize 和 DefinedSize 属性显示字段的定义大小和实际大小。

// BeginActualSizeJ
import com.ms.wfc.data.*;
import java.io.*;

public class ActualSizeX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      ActualSizeX();
      System.exit(0);
   }

   // ActualSizeX function

   static void ActualSizeX()
   {

      // Define ADO Objects.
      Recordset rstStores = null;

      // Declarations.
      BufferedReader in = new
         BufferedReader(new InputStreamReader(System.in));
      String line = null;
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
         + "Initial Catalog='Pubs';Integrated Security='SSPI';";

      String strStoreName;
      String strMessage;
      String strDSize,strASize;
      int intDefinedSize;
      int intActualSize;
      int intChoice = 0;

      try
      {
         // Open recordset with Stores table.
         rstStores = new Recordset();
         rstStores.open("stores", strCnn,
            AdoEnums.CursorType.FORWARDONLY ,
            AdoEnums.LockType.READONLY ,
            AdoEnums.CommandType.TABLE);

         // Loop through the Recordset displaying the contents
         // of the stor_name field, the field's defined size
         // and it's actual size.

         while ( !(rstStores.getEOF( ))) // continuous loop
         {
            // Read data field in the variables.
            strStoreName = rstStores.getField("stor_name").getString();
            intDefinedSize =
               rstStores.getField("stor_name").getDefinedSize();
            strDSize = Integer.toString(intDefinedSize);
            intActualSize = rstStores.getField
               ("stor_name").getActualSize ();
            strASize = Integer.toString(intActualSize);

            // Display current record information.
            strMessage = "\nStore name: " + strStoreName + "\n"
                + "Defined Size : " + strDSize + "\n"
                + "Actual Size : " + strASize;

            System.out.println(strMessage);
            System.out.println("\nPress <Enter> key to continue.");
            in.readLine();
            rstStores.moveNext();
         }
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // Check for null pointer for connection object.
         if (rstStores.getActiveConnection()==null)
            System.out.println("Exception: " + ae.getMessage());
         // As passing a Recordset, check for null pointer first.
         if (rstStores != null)
         {
            PrintProviderError(rstStores.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstStores != null)
            if (rstStores.getState() == 1)
               rstStores.close();
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   //.PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndActualSizeJ

请参阅

ActualSize 属性 | DefinedSize 属性


AddNew 方法范例 (VJ++)

本范例使用 AddNew 方法来创建具有指定名称的新记录。

// BeginAddNewJ
import com.ms.wfc.data.*;
import java.io.*;

public class AddNewX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      AddNewX();
      System.exit(0);
   }

   // AddNewX function

   static void AddNewX()
   {
      // Define ADO Objects.
      Connection cnConn1 = null;
      Recordset rstEmployees = null;

      //Declarations.
      String strCnn;
      String strID;
      String strFirstName;
      String strLastName;
      boolean booRecordAdded ;
      BufferedReader in =
         new BufferedReader (new InputStreamReader (System.in));
      String line = null;

      try
      {
         // Open a connection.
         strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
            + "Initial Catalog='Pubs';Integrated Security='SSPI';";
         cnConn1 = new Connection();
         cnConn1.open(strCnn);//,"","",AdoEnums.CommandType.UNSPECIFIED);

         // Open Employees table.
         rstEmployees = new Recordset ();
         rstEmployees.open("employee", cnConn1,
            AdoEnums.CursorType.KEYSET , AdoEnums.LockType.OPTIMISTIC ,
            AdoEnums.CommandType.TABLE );

         /* Get data from the user. The employee ID must be formatted as
         first,middle, and last initial, five numbers, then M or F to
         signify the gender. For example, the employee id for Bill
         Sornsin would be "B-S55555M". */
         System.out.println("\nEnter employee ID :");
         strID = in.readLine().trim();
         System.out.println("\nEnter first name :");
         strFirstName = in.readLine().trim();
         System.out.println("\nEnter last name :");
         strLastName = in.readLine().trim();

         // Proceed only if the user actually entered something
         // for both the first and last names.

         if ( !(strID.compareTo("") == 0) &
            !(strFirstName.compareTo("") == 0) &
            !(strLastName.compareTo("")== 0))
         {
            // Add new record.
            rstEmployees.addNew();
            rstEmployees.getField("emp_id").setString(strID);
            rstEmployees.getField("fname").setString(strFirstName);
            rstEmployees.getField("lname").setString(strLastName);

            // update the record with the new data.
            rstEmployees.update();
            booRecordAdded = true;

            // Show the newly added data.
            System.out.println("\nNew record : "
               + rstEmployees.getField("emp_id").getString()+ " "
               + rstEmployees.getField("fname").getString()+ " "
               + rstEmployees.getField("lname").getString());
         }
         else
         {
            System.out.println("\nPlease enter an employee ID," +
               "first name, and last name.");
         }

         System.out.println("\n\nPress <Enter> key to continue.");
         line = in.readLine();

         // Delete the new record because this is a demonstration.
         cnConn1.execute("DELETE FROM employee WHERE "
            + "emp_id = '" + strID + "'");
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         //Check for null pointer for connection object.
         if(rstEmployees.getActiveConnection()==null)
            System.out.println("Exception: " + ae.getMessage());
         // As passing a Recordset, check for null pointer first.
         if (rstEmployees != null)
         {
            PrintProviderError(rstEmployees.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
         System.exit(0);
      }
      // System Read requires this catch.
      catch( java.io.IOException je )
      {
         PrintIOError(je);
      }
      finally
      {
         // Cleanup objects before exit.
         if (rstEmployees != null)
            if (rstEmployees.getState() == 1)
               rstEmployees.close();
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
         System.exit(0);
      }

   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   //.PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}

// EndAddNewJ

请参阅

AddNew 方法 | Recordset 对象


Append 和 CreateParameter 方法范例 (VJ++)

本范例使用 Append 和 CreateParameter 方法执行具有输入参数的存储过程。

// BeginAppendJ
import com.ms.wfc.data.*;
import java.io.*;
import com.ms.com.*;

public class AppendX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      AppendX();
   }

   // AppendX function

   static void AppendX()
   {
      // Define ADO Objects.
      Connection cnConn1 = null;
      Command cmdByRoyalty = null;
      Parameter prmByRoyalty = null;
      Recordset rstByRoyalty = null;
      Recordset rstAuthors = null;

      //Declarations.
      String strCnn;
      String strAuthorID;
      String strFName;
      String strLName;
      int intRoyalty ;
      BufferedReader in =
         new BufferedReader (new InputStreamReader (System.in));
      String line = null;
      Variant varRoyalty;

      try
      {
         // Open a connection.

         strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
            + "Initial Catalog='Pubs';Integrated Security='SSPI';";
         cnConn1 = new Connection();
         cnConn1.open(strCnn);
         cnConn1.setCursorLocation(AdoEnums.CursorLocation.CLIENT);

         // Open command object with one parameter.
         cmdByRoyalty = new Command();
         cmdByRoyalty.setCommandText("byRoyalty");
         cmdByRoyalty.setCommandType(AdoEnums.CommandType.STOREDPROC);

         //Get parameter value and append parameter.
         System.out.println ("\nEnter Royalty : ");
         line = in.readLine().trim();
         intRoyalty = Integer.parseInt(line);
         varRoyalty = new Variant(intRoyalty);
         prmByRoyalty = cmdByRoyalty.createParameter ("percentage",
            AdoEnums.DataType.INTEGER,
            AdoEnums.ParameterDirection.INPUT,4,varRoyalty);

         cmdByRoyalty.getParameters().append(prmByRoyalty);
         prmByRoyalty.setValue(varRoyalty);

         // Create a recordset by executing the command.
         cmdByRoyalty.setActiveConnection(cnConn1);
         rstByRoyalty = cmdByRoyalty.execute();

         // Open the Authors table to get author names for display.
         rstAuthors = new Recordset ();
         rstAuthors.open("authors", cnConn1,
            AdoEnums.CursorType.FORWARDONLY,
            AdoEnums.LockType.READONLY,
            AdoEnums.CommandType.TABLE );

         // Print current data in the recordset,
         // adding author names from Authors table.
         System.out.println("\nAuthors with " + intRoyalty +
            " percent royalty");
         while (!rstByRoyalty.getEOF())
         {
            strAuthorID =  rstByRoyalty.getField("au_id").getString();
            rstAuthors.setFilter("au_id ='" +  strAuthorID + "'");
            strFName = rstAuthors.getField("au_fname").getString();
            strLName = rstAuthors.getField("au_lname").getString();
            System.out.println("\t" + strAuthorID + ", " + strFName
               + " " + strLName);
            rstByRoyalty.moveNext();
         }
         System.out.println("\n\nPress <Enter> key to continue.");
         line = in.readLine();

      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // Check for null pointer for connection object.
         if(rstByRoyalty.getActiveConnection()==null)
            System.out.println("Exception: " + ae.getMessage());
         // As passing a Recordset, check for null pointer first.
         if (rstByRoyalty != null)
         {
            PrintProviderError(rstByRoyalty.getActiveConnection());
         }
         if (rstAuthors != null)
         {
            if (rstAuthors.getActiveConnection()==null)
               System.out.println("Exception: " + ae.getMessage());
            else
               PrintProviderError(rstAuthors.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // This catch is required if input string cannot be converted to
      // Integer data type.
      catch( java.lang.NumberFormatException ne)
      {
         System.out.println("\nException: Integer Number required.");
         System.exit(0);
      }
      // System Read requires this catch.
      catch( java.io.IOException je )
      {
         PrintIOError(je);
      }
      finally
      {
         // Cleanup objects before exit.
         if (rstByRoyalty != null)
            if (rstByRoyalty.getState() == 1)
               rstByRoyalty.close();
         if (rstAuthors != null)
            if (rstAuthors.getState() == 1)
               rstAuthors.close();
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
         System.exit(0);//required here only.
      }

   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   //.PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}

// EndAppendJ

请参阅

Append 方法 | CreateParameter 方法


AppendChunk 和 GetChunk 方法范例 (VJ++)

本范例使用 AppendChunk 和 GetChunk 方法用其他记录中的数据填充图像字段。

// BeginAppendChunkJ
import com.ms.wfc.data.*;
import java.io.*;
import com.ms.com.*;
import java.util.*;

public class AppendChunkX
{

   // The main entry point for the application.

   public static void main (String[] args)
   {
      AppendChunkX();
      System.exit(0);
   }

   // AppendChunkX function

   static void AppendChunkX()
   {
      // Define ADO Objects.
      Connection cnConn1 = null;
      Recordset rstPubInfo = null;

      //Declarations.
      String strCnn;
      String strPubID;
      String strPRInfo;
      String strMessage = "";
      long lngOffset = 0;
      long lngLogoSize;
      final  int conChunkSize = 100;
      byte[] varChunk = new byte[conChunkSize];
      int intCommand = 0 ;
      int intMulChunkSize,intLastChunkSize;
      Vector varLogo = new Vector();
      BufferedReader in =
         new BufferedReader(new InputStreamReader(System.in));
      String line = null;
      int noOfRecords;
      int noOfRecordesDisplayed = 5;
      int recordCount = 0;
      String info;
      int indexOfComma ;

      try
      {
         // Open a connection.
         strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
            + "Initial Catalog='Pubs';Integrated Security='SSPI';";
         cnConn1 = new Connection();
         cnConn1.open(strCnn,"","",AdoEnums.CommandType.UNSPECIFIED);

         // Open the pub_info Table.
         rstPubInfo = new Recordset();
         rstPubInfo.setCursorType(AdoEnums.CursorType.KEYSET );
         rstPubInfo.setLockType(AdoEnums.LockType.OPTIMISTIC );

         rstPubInfo.open("pub_info", cnConn1,AdoEnums.CursorType.KEYSET ,
            AdoEnums.LockType.OPTIMISTIC, AdoEnums.CommandType.TABLE );
         System.out.println ("Available logos are : \n");

         noOfRecords = rstPubInfo.getRecordCount();

         // Prompt for the Logo to copy.
         for ( int i = 0; i < noOfRecords; i++)
         {
            recordCount++;
            strMessage = strMessage +
               rstPubInfo.getField("pub_id").getString() + "\n";
            indexOfComma =
               rstPubInfo.getField("pr_info").getString().indexOf(",");
            info =
               rstPubInfo.getField("pr_info").getString().substring(0,
               indexOfComma );
            strMessage = strMessage + info + "\n\n";
            // Display five records at a time.
            if ( recordCount == noOfRecordesDisplayed)
            {
               System.out.println(strMessage);
               System.out.println("\n\nPress <Enter> to continue..");
               line = in.readLine();
               strMessage = "";
               recordCount = 0;
            }
            rstPubInfo.moveNext();
            // Display last records and exit if last record.
            if(rstPubInfo.getEOF())
            {
               System.out.println(strMessage);
               break;
            }
         }
         System.out.println ("\nEnter the ID of a logo to copy :\n"  );
         strPubID = in.readLine();

         // Copy the logo to a variable in chunks.
         rstPubInfo.setFilter("pub_id = '" + strPubID + "'");
         lngLogoSize = rstPubInfo.getField("logo").getActualSize();
         while (lngOffset < lngLogoSize)
         {
            varChunk = rstPubInfo.getField("logo")
               .getByteChunk(conChunkSize);
            int i = 0;
            while (i < conChunkSize && varLogo.size() < (int)lngLogoSize)
            {
               varLogo.addElement(new Byte(varChunk[i]));
               i++;
            }
            lngOffset =  lngOffset + conChunkSize ;
         }
            //Get the data for New ID from the user.
            System.out.println
               ("\nEnter a new pub ID [must be > 9899 & < 9999]:");
            strPubID =  in.readLine().trim();

            System.out.println ("\nEnter descriptive text :");
            strPRInfo =  in.readLine().trim();

            //Temporarily add new publisher to publishers table to
            //avoid getting error foreign key constraint.
            cnConn1.execute("INSERT publishers(pub_id) VALUES('" +
               strPubID + "')");

            //Add a new record.
            rstPubInfo.addNew();
            rstPubInfo.getField("pub_id").setString(strPubID);
            rstPubInfo.getField("pr_info").setString(strPRInfo);

            //Copy the selected logo to the new logo in chunks.
            lngOffset = 0;

            //Divide logosize in multiples of constant chunk size.
            intMulChunkSize =
               (varLogo.size()/conChunkSize) * conChunkSize;
            intLastChunkSize = varLogo.size()- intMulChunkSize ;
            byte[] arrChunk  = new byte[conChunkSize];
            byte[] lastChunk = new byte[intLastChunkSize];

            while ( lngOffset < varLogo.size () )
            {
               int ii = 0 ;
               // Copy the logo in constant chunk size.
               if ( (int)lngOffset < intMulChunkSize)
               {
                  while (ii < conChunkSize &&
                     (int)lngOffset < varLogo.size () )
                  {
                     arrChunk[ii] =
                        ((Byte)varLogo.elementAt
                        ((int)lngOffset)).byteValue();
                     ii++;
                     lngOffset++;
                  }
                  rstPubInfo.getField("logo").appendChunk(arrChunk);
               }
               // Copy the last remaining chunk.
               else
               {
                  while (ii < intLastChunkSize &&
                     (int)lngOffset < varLogo.size () )
                  {
                     lastChunk[ii] =
                        ((Byte)varLogo.elementAt
                        ((int)lngOffset)).byteValue();
                     ii++;
                     lngOffset++;

                  }
                  rstPubInfo.getField("logo").appendChunk(lastChunk);
               }

            }

            // Update the new recordset with new logo.

            rstPubInfo.update();

            //Show the newly added data.
            System.out.println ("\nNew Record : " +
               rstPubInfo.getField("pub_id").getString() + "\n");
            System.out.println ("Description : " +
               rstPubInfo.getField("pr_info").getString() + "\n");
            System.out.println ("Logo Size : " +
               rstPubInfo.getField("logo").getActualSize() );

            System.out.println ("\n\nPress <Enter> key to continue.");
            in.readLine();

            //Delete new records because this is a demonstration.
            rstPubInfo.requery();
            cnConn1.execute("DELETE FROM pub_info WHERE  pub_id = '" +
               strPubID + "'");
            cnConn1.execute("DELETE FROM publishers WHERE  pub_id = '" +
               strPubID + "'");
      }
      catch( AdoException ae )
         {
            // Notify user of any errors that result from ADO.

            // Check for null pointer for connection object.
            if(rstPubInfo.getActiveConnection()==null)
                  System.out.println("Exception: " + ae.getMessage());
            // As passing a Recordset, check for null pointer first.
            if (rstPubInfo != null)
            {
               PrintProviderError(rstPubInfo.getActiveConnection());
               PrintADOError(ae);
            }
            else
            {
               System.out.println("Exception: " + ae.getMessage());
            }
      }
      // System Read requires this catch.
      catch( java.io.IOException je )
      {
         PrintIOError(je);
      }
      finally
      {
         // Cleanup objects before exit.
         if (rstPubInfo != null)
            if (rstPubInfo.getState() == 1)
               rstPubInfo.close();
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }

   // PrintADOError Function

   static void PrintADOError(AdoException ae)
   {
      System.out.println("\t Error Source = " + ae.getSource() + "\n");
      System.out.println("\t Description = " + ae.getMessage() + "\n");
   }
}
// EndAppendChunkJ

请参阅

AppendChunk 方法 | Field 对象 | GetChunk 方法


Attributes 和 Name 属性范例 (VJ++)

本范例显示 Connection、Field 和 Property 对象的 Attributes 属性的值。该范例使用 Name 属性显示每个 Field 和 Property 对象的名称。

// BeginAttributesJ
import com.ms.wfc.data.*;
import java.io.*;

public class AttributesX
{
   // The main entry point for the application
   public static void main (String[] args)
   {
      AttributesX();
      System.exit(0);
   }

   // AttributeX Function

   static void AttributesX()
   {
      // Define ADO Objects.
      Connection cnConn1 = null;
      Recordset rstEmployees = null;
      Fields listOfFields = null;
      AdoProperties listOfProperties = null;

      //Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String line = null;
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
         + "Initial Catalog='Pubs';Integrated Security='SSPI';";
      int recordDisplaySize = 15;
      int propertyCount = 0;
      try
      {
         // Open connection and recordset.
         cnConn1 = new Connection();
         cnConn1.open(strCnn);

         rstEmployees = new Recordset ();
         rstEmployees.open("employee",
            cnConn1,AdoEnums.CursorType.FORWARDONLY,
            AdoEnums.LockType.READONLY, AdoEnums.CommandType.TABLE);

         // Display the attributes of the connection.
         System.out.println("Connection attributes = "
            + cnConn1.getAttributes());
         // Display the attributes of the Employees table's fields.
         System.out.println("\n\nField attributes : " + "\n");

         listOfFields = rstEmployees.getFields();

         for ( int i=0; i < listOfFields.getCount();i++)
         {
            System.out.println("\t\t" + listOfFields.getItem(i).getName()
               + " = " + listOfFields.getItem(i).getAttributes());
         }

         // Display fields of the Employees table which are NULLABLE.
         System.out.println("\n\nNULLABLE Fields : " + "\n");
         for ( int i=0; i < listOfFields.getCount();i++)
         {
            if ((listOfFields.getItem(i).getAttributes() &
               AdoEnums.FieldAttribute.ISNULLABLE) > 0)
               System.out.println("\t\t" +
               listOfFields.getItem(i).getName());

         }

         System.out.println ("\n\nPress <Enter> key to continue..");
         line = in.readLine();

         // Display the attributes of the Employees table's properties.
         System.out.println("\n\nProperty attributes : " );
         listOfProperties = rstEmployees.getProperties();
         for ( int i=0; i < listOfProperties.getCount() ;i++)
         {
            System.out.println("\t\t" +
               listOfProperties.getItem(i).getName()
               + " = " + listOfProperties.getItem(i).getAttributes());

            if (propertyCount == recordDisplaySize)
            {
               System.out.println ("\n\nPress <Enter> key to continue.");
               line = in.readLine();
               propertyCount = 0;
            }
            propertyCount++;
         }

         System.out.println ("\n\nPress <Enter> key to continue.");
         line = in.readLine();
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // Check for null pointer for connection object.
         if (rstEmployees.getActiveConnection()==null)
            System.out.println("Exception: " + ae.getMessage());

         // As passing a Recordset, check for null pointer first.

         if (rstEmployees != null)
         {
            PrintProviderError(rstEmployees.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstEmployees != null)
            if (rstEmployees.getState() == 1)
               rstEmployees.close();
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   //.PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}

// EndAttributesJ

请参阅

Attributes 属性 | Connection 对象 | Field 对象 | Name 属性 | Property 对象


BeginTrans、CommitTrans 和 RollbackTrans 方法范例 (VJ++)

本范例更改数据库的 Titles 表中所有心理学书籍的类型。在 BeginTrans 方法启动事务来隔离 Titles 表的所有更改后，使用 CommitTrans 方法保存更改。可以使用 RollbackTrans 方法撤消用 Update 方法保存的更改。

// BeginBeginTransJ
import com.ms.wfc.data.*;
import java.io.*;

public class BeginTransX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      BeginTransX();
      System.exit(0);
   }

   // BeginTransX function
   static void BeginTransX()
   {
      // Define ADO Objects.
      Connection cnConn1 = null;
      Recordset rstTitles = null;

      //Declarations.
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
         + "Initial Catalog='Pubs';Integrated Security='SSPI';";
      String strTitle;
      String strType;
      BufferedReader in =
         new BufferedReader (new InputStreamReader (System.in));
      String line = null;
      String strMessage="";
      int intChoice = 0;
      int recordDisplaySize = 15;
      int recordCount = 0;

      try
      {
         // Open a connection.

         cnConn1 = new Connection();
         cnConn1.open(strCnn,"","",AdoEnums.CommandType.UNSPECIFIED);

         // Open the Titles table.
         rstTitles = new Recordset ();
         rstTitles.setCursorType(AdoEnums.CursorType.DYNAMIC);
         rstTitles.setLockType(AdoEnums.LockType.PESSIMISTIC);
         rstTitles.open("titles",cnConn1,AdoEnums.CursorType.DYNAMIC ,
            AdoEnums.LockType.PESSIMISTIC ,AdoEnums.CommandType.TABLE );

         rstTitles.moveFirst();
         cnConn1.beginTrans();

         // Loop through recordset and ask user if he/she wants
         // to change the type for a specified title.

         while (!rstTitles.getEOF())
         {
            strType = rstTitles.getField("type").getString().trim();
            if ((rstTitles.getField("type").getString().
               trim()).compareTo("psychology")== 0)
            {
               strTitle = rstTitles.getField("title").getString().trim();
               System.out.println("\nTitle : " + strTitle + "\n\n"
                  +  "Change type to self help (1 -> Yes / 2 -> No) ?");
               // Change the title for the specified book.
               line = in.readLine().trim();
               intChoice = Integer.parseInt(line);
               if ( intChoice == 1)
               {
                  rstTitles.getField("type").setString("self_help");
                  rstTitles.update();
               }
            }
            rstTitles.moveNext();
         }

         // Ask if the user wants to commit to all the
         // changes made above.
         System.out.println
            ("\n\nSave all changes (1 -> Yes / 2 -> No) ?");
         line = in.readLine().trim();
         intChoice = Integer.parseInt(line);
         if ( intChoice == 1)
            cnConn1.commitTrans();
         else
            cnConn1.rollbackTrans();

         // Print current data in recordset.
         rstTitles.requery();
         rstTitles.moveFirst();

         while(true)
         {
            strMessage = strMessage +"\n " +
               rstTitles.getField("title").getString()+" - "
               + rstTitles.getField("type").getString() ;

            if ( recordCount == recordDisplaySize)
            {
               System.out.println(strMessage);
               System.out.println("\n\nPress <Enter> key to continue..");
               line = in.readLine();
               strMessage = "";
               recordCount = 0;
            }
            recordCount++;
            rstTitles.moveNext();
            if(rstTitles.getEOF())
            {
               System.out.println(strMessage);
               break;
            }
         }
         System.out.println("\n\nPress <Enter> key to continue..");
         line = in.readLine();

         // Restore original data because this
         // is a demonstration.
         rstTitles.moveFirst();
         while (!rstTitles.getEOF())
         {
            if ((rstTitles.getField("type").getString().
               trim().compareTo("self_help"))== 0)
            {
               rstTitles.getField("type").setString("psychology");
               rstTitles.update();
            }
            rstTitles.moveNext();
         }
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // Check for null pointer for connection object.
         if(rstTitles.getActiveConnection()==null)
            System.out.println("Exception: " + ae.getMessage());

         // As passing a Recordset, check for null pointer first.
         if (rstTitles != null)
         {
            PrintProviderError(rstTitles.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }
      // System Read requires this catch.
      catch( java.io.IOException je )
      {
         PrintIOError(je);
      }
      finally
      {
         // Cleanup objects before exit.
         if (rstTitles != null)
            if (rstTitles.getState() == 1)
               rstTitles.close();
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   //.PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}

// EndBeginTransJ

请参阅

BeginTrans、CommitTrans 和 RollbackTrans 方法 | Update 方法


BOF、EOF 和 Bookmark 属性范例 (VJ++)

本范例使用 BOF 和 EOF 属性，在用户试图移过 Recordset 的第一个或最后一个记录时显示一条消息。Bookmark 属性的使用使得用户可以标记 Recordset 中的记录，稍后再返回该记录。

// BeginBOFEOFJ
import com.ms.wfc.data.*;
import java.io.*;
import com.ms.com.*;

public class BOFEOFBookmark
{
   Variant varBookmark;
   BufferedReader in =
      new BufferedReader(new InputStreamReader(System.in));
   String line = null;

   // The main entry point for the application.

   public static void main (String[] args)
   {
      BOFEOFBookmark b1 = new BOFEOFBookmark ();
      b1.BOFX();
      b1.BOFX2();
      System.exit(0);
      try
      {
         b1.finalize();
      }
      catch(Throwable te)
      {
         System.out.println("Exception: " + te.getMessage());
      }
   }

   // The main entry point for the application.

   public void BOFX()
   {
      // Declarations.
      Recordset rstPublishers = null;
      String strCnn;
      String strMessage;
      int intCommand = 0;

      strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
         + "Initial Catalog='Pubs';Integrated Security='SSPI';";
      try
      {
         // Open a recordset with data from Publishers table.
         rstPublishers = new Recordset();
         rstPublishers.setCursorType(AdoEnums.CursorType.STATIC );
         rstPublishers.setCursorLocation(
            AdoEnums.CursorLocation.CLIENT);

         // Use client cursor to enable AbsolutePosition property.

         rstPublishers.open(new String(
            "SELECT pub_id,pub_name FROM Publishers ORDER BY pub_name"),
            strCnn, AdoEnums.CursorType.STATIC ,
            AdoEnums.LockType.BATCHOPTIMISTIC,
            AdoEnums.CommandType.TEXT );
         rstPublishers.moveFirst();

         //Display information about current record and get user input.
         while ( true)
         {
            strMessage = "\nPublisher :" +
               rstPublishers.getField("pub_name").getString() + "\n"
               + " (Record " + rstPublishers.getAbsolutePosition()
               + " of " + rstPublishers.getRecordCount() + ")" + "\n\n"
               + "Enter command : " + "\n"
               + "[1 - next / 2 - previous /" + "\n"
               + "3 - set bookmark / 4 - go to bookmark] / 5 - quit]" ;
            System.out.println (strMessage);
            line = in.readLine();
            //No entry exits loop.
            if (line.length() == 0)
               break;
            //convert string entry to int.
            intCommand = Integer.parseInt(line);
            //out of range entry exits loop.
            if ((intCommand < 1) || (intCommand > 4)) break ;

            //Call method based on user's validated selection.
            MoveAny(intCommand, rstPublishers);
         }
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstPublishers != null)
         {
            PrintProviderError(rstPublishers.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // This catch is required if input string cannot be converted to
      // Integer data type. "TCS[VSD]"

      catch ( java.lang.NumberFormatException ne)
      {
         System.out.println("\nException: Integer Input required." );
      }

      // System Read requires this catch.
      catch( java.io.IOException je )
      {
         PrintIOError(je);
      }
      finally
      {
         // Cleanup objects before exit.
         if (rstPublishers != null)
            if (rstPublishers.getState() == 1)
               rstPublishers.close();
      }
   }

   // MoveAny Function

   public void MoveAny(int intChoice, Recordset rsTemp)
   {
      // Move Forward or backword per selection from user,
      // trapping for BOF and EOF.
      try
      {
         switch(intChoice)
         {
            case 1:   // Equals char of 1.
               rsTemp.moveNext();
               if (rsTemp.getEOF())
               {
                  System.out.println (
                     "\nMoving past the last record \nTry again." );
                  rsTemp.moveLast();
               }
               break;
            case 2:   // Equals char of 2.
               rsTemp.movePrevious();
               if (rsTemp.getBOF())
               {
                  System.out.println (
                     "\nMoving past the first record \nTry again." );
                  rsTemp.moveFirst();
               }
               break;
            case 3:   // Equals char of 3.
               // Store the bookmark of the current record.
               varBookmark = (Variant)rsTemp.getBookmark();
               break;
            case 4:   // Equals char of 4.
               // Go to the record indicated by the stored bookmark.
               if (varBookmark == null)
                  System.out.println ("\nNo bookmark set!");
               else
                  rsTemp.setBookmark((Object)varBookmark);
               break;
            default:
               break;
         }
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rsTemp != null)
         {
            PrintProviderError(rsTemp.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   //.PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }

   ////////////////////////////////////////////
   //            BOFX2() Function.           //
   ////////////////////////////////////////////

   public void BOFX2()
   {
      Recordset rs = null ;

      try
      {
         // Declarations.
         rs = new Recordset();
         Variant[] arrbmk = new Variant[11];
         rs.setCursorLocation( AdoEnums.CursorLocation.CLIENT);
            String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
            + "Initial Catalog='Pubs';Integrated Security='SSPI';";
         rs.setActiveConnection (strCnn);
         // Open recorset with data from authors table.
         rs.open((new  String("SELECT * FROM authors")),strCnn,AdoEnums.CursorType.STATIC ,AdoEnums.LockType.BATCHOPTIMISTIC,AdoEnums.CommandType.TEXT );
         System.out.println ("\nNumber of records before filtering : " + rs.getRecordCount() );
         int ii = 0;

         // Create array of bookmarks.
         while (rs.getEOF() != true && ii < 11)
         {
            arrbmk[ii] = (Variant)rs.getBookmark();
            ii++;
            rs.move (2);
         }

         // set Filter to recordset.
         Variant bmk=new Variant();
         bmk.putVariantArray(arrbmk);
         rs.setFilter(bmk);
         System.out.println ("\nNumber of records after filtering : " + rs.getRecordCount() );

         // Dislay the records after filtering.
         rs.moveFirst();
         while (!rs.getEOF())
         {
            System.out.println ("\t" +rs.getAbsolutePosition() + "  " +rs.getField("au_lname").getString());
            rs.moveNext();
         }
         rs.close();
         System.out.println ("\n\nPress <Enter> key to continue.");
         in.readLine();

      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rs != null)
         {
            PrintProviderError(rs.getActiveConnection());
            System.out.println("Exception: " + ae.getMessage());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }
      // System Read requires this catch.
      catch( java.io.IOException je )
      {
         PrintIOError(je);
      }
   }
}

// EndBOFEOFJ

请参阅

BOF 和 EOF 属性 | Bookmark 属性 | Recordset 对象


CacheSize 属性范例 (VJ++)

本范例使用 CacheSize 属性显示使用和不使用缓存（大小为 30 条记录）时执行的操作在性能上的差别。

// BeginCacheSizeJ
import com.ms.wfc.data.*;
import java.io.* ;

public class CacheSizeX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      CacheSizeX();
      System.exit(0);
   }

   // CacheSizeX function

   static void CacheSizeX()
   {

      // Define ADO Objects.
      Recordset rstRoySched = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String line = null;
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
         + "Initial Catalog='Pubs';Integrated Security='SSPI';";

      long timeStart;
      long timeEnd;
      float timeNoCache;
      float timeCache;
      int   intLoop;
      String strTemp;

      try
      {
         // Open the RoySched table.
         rstRoySched = new Recordset();
         rstRoySched.open("roysched", strCnn,
            AdoEnums.CursorType.FORWARDONLY,
            AdoEnums.LockType.READONLY,
            AdoEnums.CommandType.TABLE);

         // Enumerate the Recordset object twice and record
         // the elapsed time.

         timeStart = System.currentTimeMillis();
         for ( intLoop = 0; intLoop < 2; intLoop++)
         {
            rstRoySched.moveFirst();
            while (!rstRoySched.getEOF())
            {
               // Execute a simple operation for the
               // performance test.
               strTemp = rstRoySched.getField("title_id").getString();
               rstRoySched.moveNext();
            }

         }

         timeEnd = System.currentTimeMillis();
         timeNoCache =(float)(timeEnd - timeStart)/1000f;

         // Cache records in groups of 30 records.
         rstRoySched.moveFirst();
         rstRoySched.setCacheSize(30);
         timeStart = System.currentTimeMillis();

         // Enumerate the Recordset object twice and record
         // the elapsed time.
         for ( intLoop = 0; intLoop < 2; intLoop++)
         {
            rstRoySched.moveFirst();
            while (!rstRoySched.getEOF())
            {
               // Execute a simple operation for the
               // performance test.

               strTemp = rstRoySched.getField("title_id").getString();
               rstRoySched.moveNext();
            }

         }

         timeEnd = System.currentTimeMillis();
         timeCache = (float)(timeEnd - timeStart)/1000f;

         // Display performance results.
         System.out.println("\nCaching Performance Results:");
         System.out.println("\n\tNo Cache: " + timeNoCache + " seconds");
         System.out.println("\n\t30-record cache: " + timeCache +
            " seconds");
         System.out.println("\n\nPress <Enter> to continue..");
         in.readLine();

      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // Check for null pointer for connection object.
         if (rstRoySched.getActiveConnection()==null)
            System.out.println("Exception: " + ae.getMessage());

         // As passing a Recordset, check for null pointer first.
         if (rstRoySched != null)
         {
            PrintProviderError(rstRoySched.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }
      finally
      {
         // Cleanup objects before exit.
         if (rstRoySched != null)
            if (rstRoySched.getState() == 1)
               rstRoySched.close();
      }

   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}

// EndCacheSizeJ

请参阅

CacheSize 属性 | Recordset 对象


Cancel 方法范例 (VJ++)

本范例使用 Cancel 方法，在连接繁忙时取消在 Connection 对象上执行的命令。

// BeginCancelJ
import com.ms.wfc.data.*;
import java.io.* ;

public class CancelX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      CancelX();
      System.exit(0);
   }

   // CancelX function

   static void CancelX()
   {
      // Define command strings.
      String strCmdChange = "UPDATE titles SET type = 'self_help' "
         + "WHERE type = 'psychology'";
      String strCmdRestore = "UPDATE titles SET type = 'psychology' "
         + "WHERE type = 'self_help'";
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
         + "Initial Catalog='Pubs';Integrated Security='SSPI';";

      // Define ADO Objects.
      Connection cnConn1 = null;

      //Declarations.
      boolean booChanged = false;
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String line = null;

      try
      {
         // Open a connection.
         cnConn1 = new Connection();
         cnConn1.open(strCnn);

         // Begin a transaction, then execute a command asynchronously.
         cnConn1.beginTrans();
         cnConn1.execute(strCmdChange,
            AdoEnums.ExecuteOption.ASYNCEXECUTE);

         // do something else for a little while - this could be changed.

         for (int intLoop = 0; intLoop < 10; intLoop++)
         {
            System.out.println(intLoop);
         }

         // If the command has NOT completed, cancel the execute
         // and roll back the transaction. Otherwise, commit the
         // transaction.

         if ((cnConn1.getState() & AdoEnums.ObjectState.EXECUTING) > 0)
         {
            cnConn1.cancel();
            cnConn1.rollbackTrans();
            booChanged = false;
            System.out.println("\nUpdate canceled.");
         }
         else
         {
            cnConn1.commitTrans();
            booChanged = true;
            System.out.println("\nUpdate complete.");
         }

         //If the change was made, restore the data
         // because this is a demonstration.

         if(booChanged )
         {
            cnConn1.execute(strCmdRestore);
            System.out.println("\nData restored.");
         }

         System.out.println("\n\nPress <Enter> to continue..");
         in.readLine();
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a connection, check for null pointer first.
         if (cnConn1 != null)
         {
            PrintProviderError(cnConn1);
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }
      finally
      {
         // Cleanup objects before exit.
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}

// EndCancelJ

请参阅

Cancel 方法 | Connection 对象


Clone 方法范例 (VJ++)

本范例使用 Clone 方法来创建 Recordset 的副本，然后让用户单独定位每个副本的记录指针。

// BeginCloneJ
import com.ms.wfc.data.*;
import java.io.* ;

public class CloneX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      CloneX();
      System.exit(0);
   }

   // CloneX function

   static void CloneX()
   {
      // Assign SQL statement and connection string to variables.
      String strSQL = "SELECT stor_name FROM Stores "
         + "ORDER BY stor_name";

      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
         + "Initial Catalog='Pubs';Integrated Security='SSPI';";

      // Define ADO Objects.
      Recordset[] arstStores = null;

      //Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String line = null;
      String strMessage;
      String strFind;
      int  intLoop;
      boolean booExit = true;

      try
      {
         // Open recordset as a static cursor type recordset.
         arstStores = new Recordset[3];
         arstStores[0] = new Recordset();
         arstStores[0].setCursorType(AdoEnums.CursorType.STATIC);
         arstStores[0].setLockType(AdoEnums.LockType.BATCHOPTIMISTIC);
         arstStores[0].open(strSQL,strCnn,AdoEnums.CursorType.STATIC,
            AdoEnums.LockType.BATCHOPTIMISTIC,AdoEnums.CommandType.TEXT);

         // Create two clones of the original Recordset.
         arstStores[1] = (Recordset)arstStores[0].clone
            (AdoEnums.LockType.BATCHOPTIMISTIC);
         arstStores[2] = (Recordset)arstStores[0].clone
            (AdoEnums.LockType.BATCHOPTIMISTIC);

         while(booExit)
         {
            // Loop through the array so that on each pass,
            // the user is searching a different copy of the
            // same Recordset.
            for (intLoop = 0; intLoop < 3; intLoop++)
            {
               // Ask for search string while showing where
               // the current record pointer is for each Recordset
               strMessage = "\nRecordsets from stores table:" + "\n"
                  +  "  1 - Original - Record pointer at "
                  + arstStores[0].getField("stor_name").getString()
                  + "\n" + "  2 - Clone - Record pointer at "
                  + arstStores[1].getField("stor_name").getString()
                  + "\n" + "  3 - Clone - Record pointer at "
                  + arstStores[2].getField("stor_name").getString()
                  + "\n";
               System.out.println(strMessage);
               System.out.println("Enter search string for #"
                  + (intLoop+1) + "(Press <Enter> to Exit.)");

               strFind = in.readLine().trim();
               if(strFind.length() == 0)
               {
                  booExit = false;
                  break;
               }

               // Find the search string; if there's no
               // match, jump to the last record.
               arstStores[intLoop].setFilter("stor_name >= '" +
                  strFind + "'");
               if (arstStores[intLoop].getEOF())
               {
                  arstStores[intLoop].setFilter
                     (new Integer(AdoEnums.FilterGroup.NONE));
                  arstStores[intLoop].moveLast();
               }
            }
         }
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a connection, check for null pointer first.
         if (arstStores[0] != null)
         {
            PrintProviderError(arstStores[0].getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (arstStores[0] != null)
            if (arstStores[0].getState() == 1)
               arstStores[0].close();
         if (arstStores[1] != null)
            if (arstStores[1].getState() == 1)
               arstStores[1].close();
         if (arstStores[2] != null)
            if (arstStores[2].getState() == 1)
               arstStores[2].close();
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndCloneJ

请参阅

Clone 方法 | Recordset 对象


CompareBookmarks 方法范例 (VJ++)

本范例演示 CompareBookmarks 方法。除了特殊的书签以外，不需要书签的相对值。

将源于 Authors 表的 Recordset 的随机行指定为搜索目标。然后显示每一行相对于该目标的位置。

// BeginCompareBookmarksJ
import com.ms.wfc.data.*;
import java.io.* ;
import com.ms.com.*;

public class CompareBookmarksX //
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      CompareBookmarksX();
      System.exit(0);
   }

   // CompareBookmarksX function

   static void CompareBookmarksX()
   {
      // Define ADO Objects.
      Recordset rstAuthors = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';" +
        "Initial Catalog='Pubs';Integrated Security='SSPI';";
      int intCount;
      Variant varTarget = null;
      int intResult;
      String strAns;
      int intDisplaySize = 15;

      try
      {
         rstAuthors = new Recordset();
         rstAuthors.open("SELECT * FROM authors",
            strCnn,
            AdoEnums.CursorType.STATIC,
            AdoEnums.LockType.READONLY,
            AdoEnums.CommandType.TEXT);
         intCount = rstAuthors.getRecordCount();
         System.out.println("Rows in the Recordset = " +
            Integer.toString(intCount));

         // Exit if an empty recordset.
         if(intCount == 0)
            System.exit(0);

         // Randomize.
         intCount = (int)(intCount * Math.random());
         // Get position between 0 and count-1.
         System.out.println("\nRandomly chosen row position = " +
            Integer.toString(intCount)+ "\n");
         rstAuthors.move(intCount,new Integer(AdoEnums.Bookmark.FIRST));          // Move row to random position.
         varTarget = (Variant)rstAuthors.getBookmark();
         // Remember the mystery row.
         intCount = 0;
         rstAuthors.moveFirst();

         // Loop through recordset.
         while(!rstAuthors.getEOF())
         {
            intResult = rstAuthors.compareBookmarks
               ((Variant)rstAuthors.getBookmark(), varTarget);
            if(intResult == AdoEnums.Compare.NOTEQUAL)
               System.out.println("Row " +
                  Integer.toString(intCount) +
                  ": Bookmarks are not equal.");
            else if(intResult == AdoEnums.Compare.NOTCOMPARABLE)
               System.out.println("Row " +
                  Integer.toString(intCount) +
                  ": Bookmarks are not comparable.");
            else
            {
               switch(intResult)
               {
               case AdoEnums.Compare.LESSTHAN :
                  strAns = "less than";
                  break;
               case AdoEnums.Compare.EQUAL :
                  strAns = "equal to";
                  break;
               case AdoEnums.Compare.GREATERTHAN :
                  strAns = "greater than";
                  break;
               default :
                  strAns = "in error comparing to";
                  break;
               }
               System.out.println("Row position " +
                  Integer.toString(intCount) +
                  " is " + strAns + " the target.");
            }
            if(intCount % intDisplaySize == 0 && intCount > 0)
            {
               System.out.println("\nPress <Enter> to continue..");
               in.readLine();
            }
            intCount++;
            rstAuthors.moveNext();
         }

         System.out.println("\nPress <Enter> to continue..");
         in.readLine();
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstAuthors != null)
         {
            PrintProviderError(rstAuthors.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstAuthors != null)
            if (rstAuthors.getState() == 1)
               rstAuthors.close();
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}

// EndCompareBookmarksJ

请参阅

CompareBookmarks 方法 | Recordset 对象


ConnectionString、ConnectionTimeout 和 State 属性范例 (VJ++)

本范例演示使用 ConnectionString 属性打开 Connection 对象的不同方式。范例中还使用 ConnectionTimeout 属性来设置连接超时的时间段，并使用 State 属性来检查连接的状态。运行此过程需要 GetState 函数。

// BeginConnectionStringJ
import com.ms.wfc.data.*;
import java.io.* ;

public class ConnectionStringX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      ConnectionStringX();
      System.exit(0);
   }

   // ConnectionStringX function

   static void ConnectionStringX()
   {
      // Define ADO Objects.
      Connection cnConn1 = null;
      Connection cnConn2 = null;
      Connection cnConn3 = null;
      Connection cnConn4 = null;

      //Declarations.

      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String line = null;
      String strTemp;

      try
      {
         // Open a connection using OLE DB syntax.
         cnConn1 = new Connection();
         cnConn1.setConnectionString(
            "Provider='sqloledb';Data Source='MySqlServer';" +
            "Initial Catalog='Pubs';Integrated Security='SSPI';");
         cnConn1.setCommandTimeout(30);
         cnConn1.open();
         strTemp = getState(cnConn1.getState());
         System.out.println("CnConn1 state: " + strTemp);

         // Open a connection using a DSN and ODBC tags.
         // It is assumed that you have create DSN 'Pubs' with a user name as
         // 'MyUserId' and password as 'MyPassword'.
         cnConn2 = new Connection();
         cnConn2.setConnectionString("DSN='Pubs';UID='MyUserId';PWD='MyPassword';");
         cnConn2.open();
         strTemp = getState(cnConn2.getState());
         System.out.println("CnConn2 state: " + strTemp);

         // Open a connection using a DSN and OLE DB tags.
         cnConn3 = new Connection();
         cnConn3.setConnectionString
            ("Data Source='Pubs';");
         cnConn3.open();
         strTemp = getState(cnConn3.getState());
         System.out.println("CnConn3 state: " + strTemp);

         // Open a connection using a DSN and individual
         // arguments instead of a connection string.
         // It is assumed that you have create DSN 'Pubs' with a user name as
         // 'MyUserId' and password as 'MyPassword'.
         cnConn4 = new Connection();
         cnConn4.open("Pubs", "MyUserId", "MyPassword");
         strTemp = getState(cnConn4.getState());
         System.out.println("CnConn4 state: " + strTemp);

         System.out.println("\n\nPress <Enter> to continue..");
         in.readLine();

      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         System.out.println("Exception: " + ae.getMessage());

      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
         if (cnConn2 != null)
            if (cnConn2.getState() == 1)
               cnConn2.close();
         if (cnConn3 != null)
            if (cnConn3.getState() == 1)
               cnConn3.close();
         if (cnConn4 != null)
            if (cnConn4.getState() == 1)
               cnConn4.close();
      }

   }

   // getState Function

   static String getState(int intState)
   {
      // Returns current state of the connection object.
      String strState=null;

      switch(intState)
      {
      case AdoEnums.ObjectState.CLOSED :
         strState = new String("adStateClosed");
         break;
      case AdoEnums.ObjectState.OPEN  :
         strState = new String("adStateOpen");
         break;
      default :
         break;
      }
      return strState;
   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}

// EndConnectionStringJ

请参阅

Connection 对象 | ConnectionString 属性 | ConnectionTimeout 属性 | State 属性


Count 属性范例 (VJ++)

本范例使用 Employees 数据库中的两个集合演示 Count 属性。该属性获取每个集合的对象数，并设置枚举这些集合的循环上限。枚举这些集合的另一种方法不使用 Count 属性，而是使用 For Each...Next 语句。

// BeginCountJ
import com.ms.wfc.data.*;
import java.io.* ;

public class CountX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      CountX();
      System.exit(0);
   }

   // CountX function

   static void CountX()
   {

      // Define ADO Objects.
      Recordset rstEmployees = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String line = null;
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
         + "Initial Catalog='Pubs';Integrated Security='SSPI';";

      int intLoop;
      int intDisplaySize = 20;
      int recCount=0;

      try
      {
         rstEmployees = new Recordset();

         // Open recordset with data from Employees table.
         rstEmployees.open("employee", strCnn,
            AdoEnums.CursorType.FORWARDONLY,
            AdoEnums.LockType.READONLY,
            AdoEnums.CommandType.TABLE);

         // Print information about Fields collection.
         System.out.println(rstEmployees.getFields().getCount() +
            " Fields in Employees");
         for ( intLoop = 0; intLoop <
            rstEmployees.getFields().getCount(); intLoop++)
         {
            System.out.println("\t" +
               rstEmployees.getFields().getItem(intLoop).getName());
         }
         System.out.println("\n\nPress <Enter> to continue..");
         in.readLine();

         // Print information about Properties collection.
         System.out.println(rstEmployees.getProperties().getCount() +
            " Properties in Employees");
         for ( intLoop = 0; intLoop <
            rstEmployees.getProperties().getCount(); intLoop++)
         {
            System.out.println("\t" +
               rstEmployees.getProperties().getItem(intLoop).getName());
            recCount++;
            if ( recCount >= intDisplaySize)
            {
               System.out.println("\n\nPress <Enter> to continue..");
               in.readLine();
               recCount = 0;
            }
         }
         System.out.println("\n\nPress <Enter> to continue..");
         in.readLine();

      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // Check for null pointer for connection object.
         if (rstEmployees.getActiveConnection()==null)
         {
            System.out.println("Exception: " + ae.getMessage());
         }
         else
         {
            // As passing a Recordset, check for null pointer first.
            if (rstEmployees != null)
            {
               PrintProviderError(rstEmployees.getActiveConnection());
            }
            else
            {
               System.out.println("Exception: " + ae.getMessage());
            }
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstEmployees != null)
            if (rstEmployees.getState() == 1)
               rstEmployees.close();
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}

// EndCountJ

请参阅

Count 属性


CursorType、LockType 和 EditMode 属性范例 (VJ++)

本范例演示在打开 Recordset 前设置 CursorType 和 LockType 属性。范例还显示不同条件下 EditMode 属性的值。运行此过程需要 EditModeOutput 函数。

// BeginEditModeJ
import com.ms.wfc.data.*;
import java.io.* ;

public class EditModeX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      EditModeX ();
      System.exit(0);
   }

   // EditModeX function

   static void EditModeX ()
   {

      // Define ADO Objects.
      Connection cnConn1 = null;
      Recordset rstEmployees = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String line = null;
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
            + "Initial Catalog='Pubs';Integrated Security='SSPI';";

      try
      {
         // Open recordset with data from Employees table.

         cnConn1 = new Connection();
         cnConn1.open(strCnn);
         rstEmployees = new Recordset();
         rstEmployees.setActiveConnection(cnConn1);
         rstEmployees.setCursorLocation(AdoEnums.CursorLocation.CLIENT);
         rstEmployees.setCursorType(AdoEnums.CursorType.STATIC);
         rstEmployees.setLockType(AdoEnums.LockType.BATCHOPTIMISTIC);
         rstEmployees.open("employee", cnConn1,
            AdoEnums.CursorType.STATIC,
            AdoEnums.LockType.BATCHOPTIMISTIC,
            AdoEnums.CommandType.TABLE);

         // Show the EditMode property under different editing states.

         rstEmployees.addNew();
         rstEmployees.getField("emp_id").setString("T-T55555M");
         rstEmployees.getField("fname").setString("temp_fname");
         rstEmployees.getField("lname").setString("temp_lname");
         EditModeOutput("After AddNew:", rstEmployees.getEditMode());
         rstEmployees.updateBatch();
         EditModeOutput("After Update:", rstEmployees.getEditMode());
         rstEmployees.getField("fname").setString("test");
         EditModeOutput("After Edit:", rstEmployees.getEditMode());

         System.out.println("\n\nPress <Enter> to continue..");
         in.readLine();

         // Delete new record because this is a demonstration.
         cnConn1.execute(
            "DELETE FROM employee WHERE emp_id = 'T-T55555M'");

         // Cleanup objects before exit.
         rstEmployees.close();
         cnConn1.close();

      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // Check for null pointer for connection object.
         if (cnConn1==null)
            System.out.println("Exception: " + ae.getMessage());

         // As passing a Recordset, check for null pointer first.
         if (rstEmployees != null)
         {
            PrintProviderError(rstEmployees.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstEmployees != null)
            if (rstEmployees.getState() == 1)
               rstEmployees.close();
      }
   }

   // EditModeOutput Function

   static void EditModeOutput(String strTemp, int intEditMode)
   {
      String strMessage="";
      // Print report based on the value of the EditMode
      // property.

      System.out.println("\n" + strTemp);
      strMessage ="\n\tEditMode = ";
      switch(intEditMode)
      {
      case AdoEnums.EditMode.NONE :
         strMessage+="adEditNone";
         break;
      case AdoEnums.EditMode.INPROGRESS :
         strMessage+="adEditInProgress";
         break;
      case AdoEnums.EditMode.ADD :
         strMessage+="adEditAdd";
         break;
      default :
         break;
      }
      System.out.println(strMessage);
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndEditModeJ

请参阅

CursorType 属性 | EditMode 属性 | LockType 属性 | Recordset 对象


Delete 方法范例 (VJ++)

本范例使用 Delete 方法从 Recordset 中删除指定的记录。

// BeginDeleteJ
// The WFC class includes the ADO objects.

import com.ms.wfc.data.*;
import java.io.* ;

public class DeleteX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      DeleteX();
      System.exit(0);
   }

   // DeleteX function

   static void DeleteX()
   {

      // Define ADO Objects.
      Recordset rstRoySched = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String line = null;
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
         + "Initial Catalog='Pubs';Integrated Security='SSPI';";

      String  strMessage="";
      String  strTitleID;
      int intLoRange =0;
      int intHiRange =0;
      int intRoyalty =0;
      boolean bolFound;

      try
      {
         rstRoySched = new Recordset();
         rstRoySched.setCursorLocation(AdoEnums.CursorLocation.CLIENT);
         rstRoySched.setCursorType(AdoEnums.CursorType.STATIC);
         rstRoySched.setLockType(AdoEnums.LockType.BATCHOPTIMISTIC);

         // Open RoySched table.
         rstRoySched.open("SELECT * FROM roysched " +
            "WHERE royalty = 20", strCnn,
            AdoEnums.CursorType.STATIC,
            AdoEnums.LockType.BATCHOPTIMISTIC,
            AdoEnums.CommandType.TEXT);

         // Prompt for a record to delete.
         strMessage = "Before delete there are "
            + rstRoySched.getRecordCount()
            + " titles with 20 percent royalty:" + "\n\n";
         while(!rstRoySched.getEOF())
         {
            strMessage += rstRoySched.getField("title_id").getString() +
               "\n\n";
            rstRoySched.moveNext();
         }
         strMessage += "Enter the ID of a record to delete:" + "\n";
         System.out.println(strMessage);
         strTitleID = in.readLine().trim().toUpperCase();

         // Move to the record and save data so it can be restored.
         rstRoySched.setFilter("title_id = '" + strTitleID + "'");
         if(!(rstRoySched.getRecordCount()==0))
         {
            intLoRange = rstRoySched.getField("lorange").getInt();
            intHiRange = rstRoySched.getField("hirange").getInt();
            intRoyalty = rstRoySched.getField("royalty").getInt();
            bolFound = true;
         }
         else
         {
            System.out.println("\nIncorrect ID. No Record deleted." );
            bolFound = false;
         }

         // Delete the record.
         if(bolFound)
         {
            rstRoySched.delete();
            rstRoySched.updateBatch();
         }
         // Show the results.
         rstRoySched.setFilter(new Integer(AdoEnums.FilterGroup.NONE));
         rstRoySched.requery();
         strMessage ="";
         strMessage = "\n\nAfter delete there are "
            + rstRoySched.getRecordCount()
            + " titles with 20 percent royalty:" + "\n\n";
         while(!rstRoySched.getEOF())
         {
            strMessage += rstRoySched.getField("title_id").getString() +
               "\n\n";
            rstRoySched.moveNext();
         }
         System.out.println(strMessage);
         System.out.println("\nPress <Enter> to continue..");
         in.readLine();

         // Restore the data because this is a demonstration.
         if(bolFound)
         {
            rstRoySched.addNew();
            rstRoySched.getField("title_id").setString(strTitleID);
            rstRoySched.getField("lorange").setInt(intLoRange);
            rstRoySched.getField("hirange").setInt(intHiRange);
            rstRoySched.getField("royalty").setInt(intRoyalty);
            rstRoySched.updateBatch();
         }
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
            if (rstRoySched != null)
            {
               PrintProviderError(rstRoySched.getActiveConnection());
               System.out.println("Exception: " + ae.getMessage());
            }
            else
            {
               System.out.println("Exception: " + ae.getMessage());
            }

      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstRoySched != null)
            if (rstRoySched.getState() == 1)
               rstRoySched.close();
      }

   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}

// EndDeleteJ

请参阅

Delete 方法 (ADO Recordset) | Recordset 对象


Description、HelpContext、HelpFile、NativeError、Number、Source 和 SQLState 属性范例 (VJ++)

本范例触发并捕获错误，同时显示产生的 Error 对象的 Description、HelpContext、HelpFile、NativeError、Number、Source 和 SQLState 属性。

// BeginDescriptionJ
// The WFC class includes the ADO objects.

import com.ms.wfc.data.*;
import java.io.* ;

public class DescriptionX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      DescriptionX();
      System.exit(0);
   }

   // DescriptionX function

   static void DescriptionX()
   {
      // Declarations.
      BufferedReader in = new
         BufferedReader(new InputStreamReader(System.in));

      // Define ADO Objects.
      Connection cnConn1 = null;

      try
      {
         // Intentionally trigger an error.
         cnConn1 = new Connection();
         cnConn1.open("nothing");
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.
         PrintProviderError(cnConn1);
      }

      try
      {
         System.out.println("\nPress <Enter> key to continue.");
         in.readLine();
      }
      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndDescriptionJ

请参阅

Description 属性 | Error 对象 | HelpContext 属性 | HelpFile 属性 | NativeError 属性 | Number 属性 | Source 属性 (ADO Error) | SQLState 属性


Execute、Requery 和 Clear 方法范例 (VJ++)

本范例演示从 Command 和 Connection 对象运行 Execute 方法。范例中还使用 Requery 方法检索记录集中的当前数据，并用 Clear 方法清除 Errors 集合的内容。运行此过程需要 ExecuteCommand 和 PrintOutput 过程。

// BeginExecuteJ
// The WFC class includes the ADO objects.
import com.ms.wfc.data.*;
import java.io.*;

public class ExecuteX
{
   // Main Function

   public static void main (String[] args)
   {
      ExecuteX();
   }

   // ExecuteX Function

   static void ExecuteX()
   {
      // Define string variables.
      String strSQLChange = "UPDATE Titles SET Type = "
            + "'self_help' WHERE Type = 'psychology'";
      String strSQLRestore = "UPDATE Titles SET Type = "
            + "'psychology' WHERE Type = 'self_help'";
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
            + "Initial Catalog='Pubs';Integrated Security='SSPI';";

      // Define ADO objects.
      Connection  cnConn1    = null;
      Command  cmdChange  = null;
      Recordset  rsTitles  = null;

      try
      {
         // Open connection.
         cnConn1 = new Connection ();
         cnConn1.open(strCnn, "", "", AdoEnums.CommandType.UNSPECIFIED);

         // Create command object.
         cmdChange = new Command();
         cmdChange.setActiveConnection (cnConn1);
         cmdChange.setCommandText (strSQLChange);

         // Open recordset with Titles table.
         rsTitles = new Recordset();
         rsTitles.open("Titles", cnConn1,
                    AdoEnums.CursorType.STATIC,
                    AdoEnums.LockType.OPTIMISTIC,
                    AdoEnums.CommandType.TABLE);

         // Print report of original data.
         System.out.println("\n\n\tData in Titles table "
                        + "before executing the query: \n");
         PrintOutput(rsTitles);

         // Clear extraneous errors from the Errors collection.
         cnConn1.getErrors().clear();

         // Call the ExecuteCommand subroutine to
         // execute cmdChange command.
         ExecuteCommand(cmdChange, rsTitles);

         // Print report of new data.
         System.out.println("\n\n\tData in Titles table after "
            + "executing the query: \n");
         PrintOutput(rsTitles);

         // Use the Connection object's execute method to
         // execute SQL statement to restore data.
         cnConn1.execute(strSQLRestore);

         // Print report of restored data.
         System.out.println("\n\n\tData after executing the query "
            + "to restore the original information: \n");
         PrintOutput(rsTitles);
      }  // End Try statement.
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rsTitles != null)
         {
            PrintProviderError(rsTitles.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      finally
      {
         // Cleanup objects before exit.
         if (rsTitles != null)
            if (rsTitles.getState() == 1)
               rsTitles.close();
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
      }
   }

   // ExecuteCommand Function

   static void ExecuteCommand(Command cmdTemp, Recordset rstTemp)
   {
      try
      {
         // CommandText property already set before function was called.
         cmdTemp.setCommandType(AdoEnums.CommandType.TEXT);
         cmdTemp.execute();

         // Retrieve the current data by requerying the recordset.
         rstTemp.requery(AdoEnums.CommandType.UNKNOWN);
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.
         PrintProviderError(rstTemp.getActiveConnection());
      }
   }

   //  PrintOutput Function

   static void PrintOutput(Recordset rstTemp)
   {
      // Declarations.
      BufferedReader in = new
         BufferedReader(new InputStreamReader(System.in));

      // Ensure at top of recordset.
      rstTemp.moveFirst();

      // If EOF is true, then no data and skip print loop.
      if( rstTemp.getEOF() )
      {
         System.out.println("\tRecordset empty\n");
      }
      else
      {
         // Enumerate Recordset and print data from each.
         while( !(rstTemp.getEOF()) )
         {
            // Convert variant string to convertable string type.
            System.out.println("\t"
               + rstTemp.getFields().getItem("Title").getValue() + " "
               + rstTemp.getFields().getItem("Type").getValue() + "\n");
            rstTemp.moveNext();
         }
      }
      try
      {
         System.out.println("\nPress <Enter> key to continue.");
         in.readLine();
      }
      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndExecuteJ

请参阅

Clear 方法 | Command 对象 | Connection 对象 | Errors 集合 | Execute 方法 (ADO Command) | Execute 方法 (ADO Connection) | Requery 方法


Filter 和 RecordCount 属性范例 (VJ++)

本范例基于应用在现有 Recordset 的特定条件，使用 Filter 属性打开新的 Recordset。范例中使用 RecordCount 属性显示两个 Recordset 中的记录数目。运行此过程需要 FilterField 函数。

// BeginFilterJ
// The WFC class includes the ADO objects.

import com.ms.wfc.data.*;
import java.io.* ;

public class FilterX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      FilterX();
      FilterX2();
      System.exit(0);
   }

   // FilterX function
   static void FilterX()
   {

      // Define ADO Objects.
      Recordset rstPublishers = null;
      Recordset rstPublishersCountry = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String line = null;
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
            + "Initial Catalog='Pubs';Integrated Security='SSPI';";

      int intPublisherCount;
      String strCountry;
      String strMessage;

      try
      {
         rstPublishers = new Recordset();

         // Open recordset with data from Publishers table.
         rstPublishers.setCursorType(AdoEnums.CursorType.STATIC);
         rstPublishers.open("publishers", strCnn,
                    AdoEnums.CursorType.STATIC,
                    AdoEnums.LockType.READONLY,
                    AdoEnums.CommandType.TABLE);

         // Populate the Recordset.
         intPublisherCount = rstPublishers.getRecordCount();

         // Get user input.
         System.out.println("Enter a country to filter on:");
         strCountry = in.readLine().trim();

         if(!strCountry.equals(""))
         {
            // Open a filtered Recordset object.
            rstPublishersCountry =
               FilterField(rstPublishers, "Country", strCountry);
            if(rstPublishersCountry.getRecordCount()==0)
               System.out.println("\nNo publishers from that country.");
            else
            {
               // Print number of records for the original
               // Recordset object and the filtered Recordset
               // object.
               strMessage = "\nOrders in original recordset: " + "\n"
                  + intPublisherCount + "\n"
                  + "Orders in filtered recordset (Country = '"
                  + strCountry + "'): \n"
                  + rstPublishersCountry.getRecordCount();
               System.out.println(strMessage);
            }
            rstPublishersCountry.close();
         }
         System.out.println("\n\nPress <Enter> to continue..");
         in.readLine();

      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstPublishers != null)
         {
            PrintProviderError(rstPublishers.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }

      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstPublishers != null)
            if (rstPublishers.getState() == 1)
               rstPublishers.close();
      }

   }

   // FilterField Function

   static Recordset FilterField(Recordset rstTemp,String strField,
                         String strFilter)
   {
      // Set a filter on the specified Recordset object and then
      // open a new Recordset object.
      rstTemp.setFilter(strField + " = '" + strFilter + "'");
      return rstTemp;
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }

   // FilterX2 function

   static void FilterX2()
   {

      // Define ADO Objects.
      Recordset rstPublishers = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String line = null;
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
            + "Initial Catalog='Pubs';Integrated Security='SSPI';";

      try
      {
         rstPublishers = new Recordset();

         // Open recordset with data from Publishers table.
         rstPublishers.setCursorType(AdoEnums.CursorType.STATIC);
         rstPublishers.open("SELECT * FROM publishers " +
                        "WHERE Country = 'USA'", strCnn,
                        AdoEnums.CursorType.STATIC,
                        AdoEnums.LockType.READONLY,
                        AdoEnums.CommandType.TEXT);

         // Print current data in recordset.
         rstPublishers.moveFirst();
         while(!rstPublishers.getEOF())
         {
            System.out.println(rstPublishers.getField("pub_name").getString()
                        +", "
                        + rstPublishers.getField("country").getString());
            rstPublishers.moveNext();
         }
         System.out.println("\n\nPress <Enter> to continue..");
         in.readLine();

         // Cleanup objects before exit.
         rstPublishers.close();

      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // Check for null pointer for connection object.
         if (rstPublishers.getActiveConnection()==null)
         {
               System.out.println("Exception: " + ae.getMessage());
         }
         else
         {
            // As passing a Recordset, check for null pointer first.
            if (rstPublishers != null)
            {
               PrintProviderError(rstPublishers.getActiveConnection());
            }
            else
            {
               System.out.println("Exception: " + ae.getMessage());
            }
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

   }
}
// EndFilterJ

请参阅

Filter 属性 | RecordCount 属性 | Recordset 对象


Find 方法范例 (VJ++)

本范例使用 Recordset 对象的 Find 方法对 Pubs 数据库中的业务标题数进行定位和计数。范例中假设基本提供者不支持相似的功能。

// BeginFindJ
// The WFC class includes the ADO objects.
import com.ms.wfc.data.*;
import java.io.* ;
import com.ms.com.*;

public class FindX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      FindX();
      System.exit(0);
   }

   // FindX function

   static void FindX()
   {

      // Define ADO Objects.
      Connection cnConn1 = null;
      Recordset rstTitles = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';" +
            "Initial Catalog='Pubs';Integrated Security='SSPI';";
      Variant varMark = null;
      int intCount = 0;

      try
      {
         cnConn1 = new Connection();
         cnConn1.open(strCnn);
         rstTitles = new Recordset();
         rstTitles.open("SELECT title_id FROM titles",
               cnConn1,
               AdoEnums.CursorType.STATIC,
               AdoEnums.LockType.READONLY,
               AdoEnums.CommandType.TEXT);

         //  The default parameters are sufficient to search forward
         //  through a Recordset.
         rstTitles.find("title_id LIKE 'BU%'");

         // Skip current record to avoid finding the same row repeatedly.
         // The bookmark is redundant because Find searches from current
         // position.
         while(!rstTitles.getEOF()) // Continue if last find succeeded.
         {
            System.out.println("Title ID: "
                           + rstTitles.getField("title_id").getString());
            intCount++; // Count the last title found.
            varMark = (Variant)rstTitles.getBookmark();
            // Note current position.
            rstTitles.find("title_id LIKE 'BU%'",
                   1,
                   AdoEnums.SearchDirection.FORWARD,
                   varMark);
         }

         System.out.println("\nThe number of business titles is " +
                        Integer.toString(intCount));
         System.out.println("\nPress <Enter> to continue..");
         in.readLine();
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstTitles != null)
         {
            PrintProviderError(rstTitles.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstTitles != null)
            if (rstTitles.getState() == 1)
               rstTitles.close();
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
      }

   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndFindJ

请参阅

Find 方法 | Recordset 对象


GetRows 方法范例 (VJ++)

本范例使用 GetRows 方法从 Recordset 中检索指定数目的行，并将结果数据填充到数组。在两种情况下 GetRows 方法返回的行数将少于所需的数目：一种情况是因为达到了 EOF，另一种情况是因为 GetRows 试图检索其他用户删除的记录。仅在发生第二种情况时，该函数才返回 False。运行此过程需要 GetRowsOK 函数。

// BeginGetRowsJ
// The WFC class includes the ADO objects.

import com.ms.wfc.data.*;
import java.io.* ;
import com.ms.com.*;

public class GetRowsX
{
    // The main entry point for the application.

   static Variant avarRecords = null;

   public static void main (String[] args)
   {
      GetRowsX();
      System.exit(0);
   }

   // GetRowsX  function

   static void GetRowsX()
   {

      // Define ADO Objects.
      Recordset rstEmployees = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String line = null;
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
            + "Initial Catalog='Pubs';Integrated Security='SSPI';";

      int intRows;
      int intRecord;
      int intUBound;
      int intDisplaysize = 15;

      try
      {
         // Open recordset with names and hire dates from Employees table.
         rstEmployees = new Recordset();
         rstEmployees.open("SELECT fName, lName, hire_date " +
                        "FROM Employee ORDER BY lName", strCnn,
                        AdoEnums.CursorType.FORWARDONLY,
                        AdoEnums.LockType.READONLY,
                        AdoEnums.CommandType.TEXT);

         while(true)
         {
            // Get user input for number of rows.
            System.out.println(
            "\nEnter number of rows to retrieve. (<= 0 to Exit)");
            line = in.readLine().trim();

            // Convert string entry to int.
            intRows = Integer.parseInt(line);

            // Exit the application if intRows is negative or zero.
            if(intRows <= 0)
               break;

            // If GetRowsOK is successful, print the results,
            // noting if the end of the file was reached.
            if(GetRowsOK(rstEmployees,intRows))
            {
               SafeArray sa = avarRecords.toSafeArray();
               intUBound = sa.getUBound(2);
               if ( intRows > (intUBound + 1))
                  System.out.println("\n(Not enough records in " +
                     "Recordset to retrieve " + intRows + " rows.)");
               System.out.println("\n" + (intUBound+ 1) +
                              " records found.\n");

               // Print the retrieved data.

               for ( intRecord = sa.getLBound();
                   intRecord  <= intUBound; intRecord++)
               {

                  System.out.println(
                     " " + sa.getString(0, intRecord) + " " +
                     sa.getString(1, intRecord) + ", " +
                     sa.getString(2, intRecord));
                  if ( ((intRecord +1) % intDisplaysize) == 0)
                  {
                     System.out.println("\nPress <Enter> to continue..");
                     in.readLine();
                  }

               }
            }
            else
            {
               // Assuming the GetRows error was due to data
               // changes by another user, use Requery to
               // refresh the Recordset and start over.
               System.out.println("\nGetRows failed--retry? (Y/N)");
               if(in.readLine().trim().toUpperCase().equals("Y"))
                  rstEmployees.requery();
               else
               {
                  System.out.println("GetRows failed!");
                  break;
               }
            }

            // Because using GetRows leaves the current
            // record pointer at the last record accessed,
            // move the pointer back to the beginning of the
            // Recordset before looping back for another search.
            rstEmployees.moveFirst();
         }

         // Cleanup objects before exit.
         rstEmployees.close();

      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstEmployees != null)
         {
            PrintProviderError(rstEmployees.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      // Display Error that the application has attempted to convert
      // a string of inappropriate format to one of the numeric types.
      catch(java.lang.NumberFormatException ne)
      {
         System.out.println(
            "Exception: Must specify an Integer value." );
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstEmployees != null)
            if (rstEmployees.getState() == 1)
               rstEmployees.close();
      }

   }

   // GetRowsOK Function

   static boolean GetRowsOK(Recordset rstTemp,int intNumber)
      {
      // Store results of GetRows method in array.
      avarRecords = rstTemp.getRows(intNumber);

      // Return False only if fewer than the desired
      // number of rows were returned, but not because the
      // end of the Recordset was reached.
      if ( intNumber > (avarRecords.toSafeArray().getUBound(2)+ 1)
               && !(rstTemp.getEOF()))
         return false;
      else
         return true;

   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndGetRowsJ

请参阅

BOF、EOF 属性 | GetRows 方法 | Recordset 对象


GetString 方法范例 (VJ++)

本范例演示 GetString 方法。

假设用户要调试数据访问问题，并且想用一种快速便捷的方式打印小型 Recordset 的当前内容。

// BeginGetStringJ
// The WFC class includes the ADO objects.
import com.ms.wfc.data.*;
import java.io.* ;

public class GetStringX
{
    // The main entry point for the application.

   public static void main (String[] args)
   {
      GetStringX ();
      System.exit(0);
   }

   // GetStringX  function
   static void GetStringX()
   {
      // Define ADO Objects.
      Connection cnConn1 = null;
      Recordset rstAuthors = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';" +
            "Initial Catalog='Pubs';Integrated Security='SSPI';";
      String strOutput;

      try
      {
         // Get the user input for state.
         System.out.println(
            "Enter a state (CA, IN, KS, MD, MI, OR, TN, UT): ");
         String strState = in.readLine().trim();
         String strQuery =
            "SELECT au_fname, au_lname, address, city FROM Authors " +
                    "WHERE state = '" + strState + "'";

         // Open recordset with data from Authors table.
         cnConn1 = new Connection();
         cnConn1.open(strCnn);
         rstAuthors = new Recordset();
         rstAuthors.open(strQuery,
                cnConn1,
                AdoEnums.CursorType.STATIC,
                AdoEnums.LockType.READONLY,
                AdoEnums.CommandType.TEXT);

         if (rstAuthors.getRecordCount() > 0)
         {
            // Use all defaults: get all rows, TAB column delimiter,
            // CARRIAGE RETURN
            // row delimiter, empty-string null delimiter.
            strOutput =
               rstAuthors.getString(AdoEnums.StringFormat.CLIPSTRING,
               rstAuthors.getRecordCount(),
               "\t ",
               "\n",
               "").trim();
            System.out.println("\nState = '" + strState + "'" +
               "\n\n" +
               "Name             Address             City" +
               "\n");
            System.out.println(strOutput);
         }
         else
            System.out.println("\nNo rows found for state = '" +
               strState + "'\n");

         System.out.println("\nPress <Enter> to continue..");
         in.readLine();
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstAuthors != null)
         {
            PrintProviderError(rstAuthors.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstAuthors != null)
            if (rstAuthors.getState() == 1)
               rstAuthors.close();
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
      }

   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndGetStringJ

请参阅

GetString 方法 | Recordset 对象


IsolationLevel 和 Mode 属性范例 (VJ++)

本范例使用 Mode 属性打开独占连接，使用 IsolationLevel 属性打开独立于其他事务执行的事务。

// BeginIsolationLevelJ
import com.ms.wfc.data.*;
import java.io.*;

public class IsolationLevelX
{
   // The main entry point for the application.
   public static void main (String[] args)
   {
      IsolationLevelX();
      System.exit(0);
   }

   // IsolationLevelX Function

   static void IsolationLevelX()
   {
      // Define ADO Objects
      Connection cnn1 = null;
      Recordset rstTitles = null;

      // Assign connection string to variable
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"+
                  "Initial Catalog='Pubs';Integrated Security='SSPI';";

      // Declarations
      BufferedReader in =
         new BufferedReader ( new InputStreamReader(System.in));
      String line = null;

      try
      {
         // Open connection and Titles table
         cnn1 = new Connection();

         cnn1.setMode(AdoEnums.ConnectMode.SHAREEXCLUSIVE);
         cnn1.setIsolationLevel(AdoEnums.IsolationLevel.ISOLATED);
         cnn1.open(strCnn);

         rstTitles = new Recordset();
         rstTitles.setCursorType(AdoEnums.CursorType.DYNAMIC);
         rstTitles.setLockType(AdoEnums.LockType.PESSIMISTIC);
         rstTitles.open("Titles", cnn1, AdoEnums.CursorType.DYNAMIC,
            AdoEnums.LockType.PESSIMISTIC);

         cnn1.beginTrans();

         // Display the connection mode
         if (cnn1.getMode() == AdoEnums.ConnectMode.SHAREEXCLUSIVE)
            System.out.println("\n\tConnection mode is exclusive");
         else
            System.out.println("\n\tConnection mode is not exclusive");
         System.out.println("\nPress <Enter> to continue..");
         in.readLine();

         // Display the Isolation level
         if ( cnn1.getIsolationLevel() == AdoEnums.IsolationLevel.ISOLATED)
            System.out.println("\tTransaction is Isolated\n");
         else
            System.out.println("\tTransaction is not Isolated\n");
         System.out.println("\nPress <Enter> to continue..");
         in.readLine();

         // Change the type of psychology titles
         while(!rstTitles.getEOF())
         {

            if(rstTitles.getField("Type").getString().trim().
               equals(new String("psychology")))
            {
               rstTitles.getField("Type").setString("self_help");
               rstTitles.update();
            }
            rstTitles.moveNext();

         }

         // Print current data in recordset
         rstTitles.requery();
         while(!rstTitles.getEOF())
         {
            System.out.println(rstTitles.getField("Title").getString() +
               " - " + rstTitles.getField("Type").getString() );
            rstTitles.moveNext();
         }
         System.out.println("\nPress <Enter> to continue..");
         in.readLine();

         // Restore original data
         cnn1.rollbackTrans();
      }
      catch(AdoException ae)
      {
         // Notify the user of any errors that result from ADO

         // As passing a connection, check for null pointer first
         if(cnn1 !=null)
         {
            PrintProviderError(cnn1);
         }
         else
         {
            System.out.println("Exception:" + ae.getLocalizedMessage());
         }
      }

      // System Read requires this catch
      catch(java.io.IOException je)
      {
         PrintIOError(je);

      }

      finally
      {
         // Cleanup objects before exit.
         if (rstTitles != null)
            if (rstTitles.getState() == 1)
               rstTitles.close();
         if (cnn1 != null)
            if (cnn1.getState() == 1)
               cnn1.close();
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndIsolationLevelJ

请参阅

IsolationLevel 属性 | Mode 属性


Item 属性范例 (VJ++)

本范例演示 Item 属性访问集合成员的方式。本范例使用参数化命令打开 Pubs 数据库的 Authors 表。

从 Command 对象的 Parameters 集合中，按索引和名称访问针对数据库发出的命令中的参数。然后按索引和名称从该对象的 Fields 集合访问返回的 Recordset 的字段。

// BeginItemJ
import com.ms.wfc.data.*;
import java.io.* ;
import com.ms.com.*;

public class ItemX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      ItemX();
      System.exit(0);
   }

   // ItemX  function

   static void ItemX()
   {

      // Define ADO Objects.
      Connection cnConn1 = null;
      Recordset rstAuthors = null;
      Command cmd = null;
      Parameter prm = null;
      Field fld = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';" +
            "Initial Catalog='Pubs';Integrated Security='SSPI';";
      Variant [] varColumn = null;
      int intIndex;
      int intLimit;

      try
      {
         cnConn1 = new Connection();
         rstAuthors = new Recordset();
         cmd = new Command();

         //  Set the array with the Authors table field (column) names.
         varColumn = new Variant[9];
         varColumn[0] = new Variant("au_id");
         varColumn[1] = new Variant("au_lname");
         varColumn[2] = new Variant("au_fname");
         varColumn[3] = new Variant("phone");
         varColumn[4] = new Variant("address");
         varColumn[5] = new Variant("city");
         varColumn[6] = new Variant("state");
         varColumn[7] = new Variant("zip");
         varColumn[8] = new Variant("contract");

         cmd.setCommandText("SELECT * FROM Authors WHERE state = ?");
         prm = cmd.createParameter("ItemXparm",
                             AdoEnums.DataType.CHAR,
                             AdoEnums.ParameterDirection.INPUT,
                             2,
                             "CA");
         cmd.getParameters().append(prm);

         cnConn1.open(strCnn);
         cmd.setActiveConnection(cnConn1);

         // Connection and CommandType are omitted
         // because a Command Object is provided.
         rstAuthors.open(cmd,
                null ,
                AdoEnums.CursorType.STATIC,
                AdoEnums.LockType.READONLY);

         System.out.println(
            "The Parameters collection accessed by index...");
         prm = cmd.getParameters().getItem(0);
         System.out.println("Parameter name = '" +
                        prm.getName() +
                        "', value = '" +
                        prm.getValue().toString() + "'\n");

         System.out.println(
            "The Parameters collection accessed by name...");
         prm = cmd.getParameters().getItem("ItemXparm");
         System.out.println("Parameters name = '" +
                        prm.getName() +
                        "', value = '" +
                        prm.getValue().toString() + "'\n");
         System.out.println("Press <Enter> to continue..");
         in.readLine();

         System.out.println(
            "The Fields collection accessed by index...");
         rstAuthors.moveFirst();
         intLimit = rstAuthors.getFields().getCount() - 1;
         for(intIndex = 0; intIndex <= intLimit; intIndex++)
         {
            fld = rstAuthors.getFields().getItem(intIndex);
            short intVtType = fld.getValue().getvt();
            String strFieldValue;
            switch(intVtType)
            {
            case Variant.VariantString :
               strFieldValue = fld.getValue().toString();
               break;
            case Variant.VariantBoolean :
               if(fld.getValue().getBoolean())
                  strFieldValue = "True";
               else
                  strFieldValue = "False";
               break;
            default :
               strFieldValue = fld.getValue().toString();
               break;
            }
            System.out.println("Field " +
                           Integer.toString(intIndex) +
                           " : Name = '" +
                           fld.getName() +
                           "', value = '" +
                           strFieldValue +
                           "'");
         }
         System.out.println("\nPress <Enter> to continue..");
         in.readLine();

         System.out.println("The Fields collection accessed by name...");
         rstAuthors.moveFirst();
         for(intIndex = 0; intIndex <= 8; intIndex++)
         {
            fld = rstAuthors.getFields().getItem
               (varColumn[intIndex].toString());
            short intVtType = fld.getValue().getvt();
            String strFieldValue;
            switch(intVtType)
            {
            case Variant.VariantString :
               strFieldValue = fld.getValue().toString();
               break;
            case Variant.VariantBoolean :
               if(fld.getValue().getBoolean())
                  strFieldValue = "True";
               else
                  strFieldValue = "False";
               break;
            default :
               strFieldValue = fld.getValue().toString();
               break;
            }
            System.out.println("Field " +
                           "name = '" +
                           fld.getName() +
                           "', value = '" +
                           strFieldValue +
                           "'");
         }
         System.out.println("\nPress <Enter> to continue..");
         in.readLine();
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstAuthors != null)
         {
            PrintProviderError(rstAuthors.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstAuthors != null)
            if (rstAuthors.getState() == 1)
               rstAuthors.close();
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndItemJ

请参阅

Command 对象 | Fields 集合 | Item 属性 | Parameters 集合 | Recordset 对象


MarshalOptions 属性范例 (VJ++)

本范例使用 MarshalOptions 属性指定发送回服务器的行（所有行或已修改的行）。

// BeginMarshalOptionsJ
import java.io.*;
import com.ms.wfc.data.*;

public class MarshalOptionsX
{
   // The main entry point for the application.
   public static void main (String[] args)
   {
      MarshalOptionsX();
      System.exit(0);
   }
   // MarshalX Function

   static void MarshalOptionsX()
   {
      // Define ADO Objects
      Recordset rstEmployees = null;

      // Declarations
      BufferedReader in =
         new BufferedReader(new InputStreamReader(System.in));
      String line = null;

      try
      {

         // Open Recordset with names from Employees Table.
         String strCnn = " Provider='sqloledb';Data Source='MySqlServer';" +
                "Initial Catalog='Pubs';Integrated Security='SSPI';";

         rstEmployees = new Recordset();
         rstEmployees.setCursorType(AdoEnums.CursorType.KEYSET);
         rstEmployees.setLockType(AdoEnums.LockType.OPTIMISTIC);
         rstEmployees.setCursorLocation(AdoEnums.CursorLocation.CLIENT);

         rstEmployees.open(
            "SELECT fname,lname from Employee ORDER BY lname",
            strCnn,AdoEnums.CursorType.KEYSET,
            AdoEnums.LockType.OPTIMISTIC, AdoEnums.CommandType.TEXT);

         // Store original data
         String strOldFirst = rstEmployees.getField("fname").getString();
         String strOldLast = rstEmployees.getField("lname").getString();

         // Change data in edit buffer
         rstEmployees.getField("fname").setString("Linda");
         rstEmployees.getField("lname").setString("Kobara");

         // Show contents of buffer and get user input
         String strMessage = "Edit in progress: "+ "\n"+
                   "Original Data  = \t"+ strOldFirst +" "+
                   strOldLast + "\n" + "Data in Buffer = \t"+
                   rstEmployees.getField("fname").getString()+ " " +
                   rstEmployees.getField("lname").getString()+"\n"+"\n"+
                   "Use Update to replace the original data with " +
                   "the buffered data in the recordset";
         String strMarshalAll = "Would you like to send all the rows" +
                     " in the recordset back to the server";
         String strMarshalModified = "Would you like to send only "+
                         " modified rows back to the server";

         System.out.println(strMessage + "\nEnter (Y/N)...");

         if (in.readLine().equalsIgnoreCase("Y"))
         {
            System.out.println(strMarshalAll);
            System.out.println("\nEnter (Y/N)...");

            if(in.readLine().equalsIgnoreCase("Y"))
            {
               rstEmployees.setMarshalOptions(AdoEnums.MarshalOptions.ALL);
               rstEmployees.update();
            }
            else
            {
               System.out.println(strMarshalModified);
               System.out.println("\nEnter (Y/N)...");

               if (in.readLine().equalsIgnoreCase("Y"))
               {
                  rstEmployees.setMarshalOptions(
                     AdoEnums.MarshalOptions.MODIFIEDONLY);
                  rstEmployees.update();
               }
            }

         }

         // Show the resulting data
         System.out.println("\nData in recordset = " +
            rstEmployees.getField("fname").getString() +
            " " + rstEmployees.getField("lname").getString());

         // Restore original data because this is a demonstration
         if (!((strOldFirst.equals(rstEmployees.getField("fname")))
            &&(strOldLast.equals(rstEmployees.getField("lname")))))
         {
            rstEmployees.getField("fname").setString(strOldFirst);
            rstEmployees.getField("lname").setString(strOldLast);
            rstEmployees.update();
         }

         System.out.println("\n\nPress <Enter> to continue..");
         in.readLine();
      }

      catch(AdoException ae)
      {
         // Notify the user of any errors that result from ADO

         // As passing a connection, check for null pointer first
         if(rstEmployees!= null)
         {
            PrintProviderError(rstEmployees.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getLocalizedMessage());
         }
      }

      // System Read requires this catch
      catch(java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstEmployees != null)
            if (rstEmployees.getState() == 1)
               rstEmployees.close();
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndMarshalOptionsJ

请参阅

MarshalOptions 属性


MaxRecords 属性范例 (VJ++)

本范例使用 MaxRecords 属性打开包含 Titles 表中 10 个最有价值标题的 Recordset。

// BeingMaxRecordsJ
import java.io.*;
import com.ms.wfc.data.*;

public class MaxRecordsX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      MaxRecordsX();
      System.exit(0);
   }
   // MaxRecordsX Function

   static void MaxRecordsX()
   {
      //  Define ADO Objects
      Recordset rstTemp = null;

      try
      {
         // Declarations
         BufferedReader in =
            new BufferedReader(new InputStreamReader(System.in));

         // Open recordset containing the 10 most expensive
         // titles in the Titles table.
         String strCnn = " Provider='sqloledb';Data Source='MySqlServer';"+
            " Initial Catalog='Pubs';Integrated Security='SSPI';";
         rstTemp = new Recordset();
         rstTemp.setMaxRecords(10);
         rstTemp.open("select title,price from Titles" +
            " order by price desc", strCnn,AdoEnums.CursorType.FORWARDONLY,
            AdoEnums.LockType.READONLY, AdoEnums.CommandType.TEXT);

         // Display the contents of the recordset.
         System.out.println("Top Ten Titles by Price:\n");
         while (!rstTemp.getEOF())
         {
            System.out.println(" "+ rstTemp.getField("title").getString() +
               " - " + rstTemp.getField("Price").getString());
            rstTemp.moveNext();
         }

         System.out.println("\n\nPress <Enter> to continue..");
         in.readLine();
      }

      catch(AdoException ae)
      {
         // Notify the user of any errors that result from ADO.

         // As passing a connection, check for null pointer first.
         if (rstTemp!=null)
         {
            PrintProviderError(rstTemp.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getLocalizedMessage());
         }
      }

      // System read requires this catch.
      catch(java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstTemp != null)
            if (rstTemp.getState() == 1)
               rstTemp.close();
      }
}
   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndMaxRecordsJ

请参阅

MaxRecords 属性 | Recordset 对象


Move 方法范例 (VJ++)

本范例使用 Move 方法按用户输入定位记录指针。

// BeginMoveJ
import java.io.*;
import com.ms.wfc.data.*;
import com.ms.com.*;

public class MoveX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      MoveX();
      System.exit(0);
   }
   // MoveX Function

   static void MoveX()
   {
      // Define ADO Objects
      Recordset rstAuthors = null;

      // Declarations
      String line = null;
      Variant varBookmark;
      String strCommand = null;
      int lngMove;
      BufferedReader in =
         new BufferedReader(new InputStreamReader(System.in));

      try
      {
         //  Open recordset from Authors table.
         String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"+
            "Initial Catalog='Pubs';Integrated Security='SSPI';";

         rstAuthors = new Recordset();
         rstAuthors.setCursorType(AdoEnums.CursorType.STATIC);

         // Use client cursor to allow use of
         // Absolute Position property.
         rstAuthors.setCursorLocation(AdoEnums.CursorLocation.CLIENT);
         rstAuthors.open("select au_id,au_fname,au_lname,city,state " +
            "from Authors order by au_lname",
            strCnn,AdoEnums.CursorType.STATIC,
            AdoEnums.CursorLocation.CLIENT, AdoEnums.CommandType.TEXT);

         rstAuthors.moveFirst();

         while(true)
         {
            // Display information about current record and
            // ask how many records to move.
            strCommand = "Record:\t\t"+ rstAuthors.getAbsolutePosition() +
               " of " + rstAuthors.getRecordCount() + "\n" + "\tAuthor:\t\t"
                + rstAuthors.getField("au_fname").getString() +
                " " + rstAuthors.getField("au_lname").getString() +
               "\n" +"\tLocation:\t" +
               rstAuthors.getField("city").getString() +
                ", " +rstAuthors.getField("state").getString()
                +"\n\n"+"\tEnter number of records to move" +
               " (positive or negative).";

            System.out.print("\t"+ strCommand + "\t");
            line =in.readLine();

            // No entry exits program loop.
            if (line.length()== 0)
               break;

            // Converts string entry to int.
            lngMove = Integer.parseInt(line);

            // Store bookmark in case the move goes too far
            // forward or backward.
            varBookmark =(Variant)rstAuthors.getBookmark();

            // Move method requires parameter of data type int.
            rstAuthors.move(lngMove);

            // Trap for BOF and EOF.
            if (rstAuthors.getBOF())
            {
               System.out.println("\tToo far backward!  " +
                  "Returning to the current record.");
               rstAuthors.setBookmark(varBookmark);
            }
            if (rstAuthors.getEOF())
            {
               System.out.println("\tToo far forward!  " +
                  "Returning to the current record.");
               rstAuthors.setBookmark(varBookmark);
            }
         }
         System.out.println("\tPress <Enter> to continue..");
         in.readLine();
      }

      catch(AdoException ae)
      {
         // Notify user of any errors that result from ADO.

         // As passing a recordset, check for null pointer.
         if (rstAuthors!=null)
         {
            PrintProviderError(rstAuthors.getActiveConnection());
         }
         else
         {
            System.out.println(" Exception: "+ ae.getMessage());
         }
      }
      // System Read requires this catch.
      catch(java.io.IOException je)
      {
         PrintIOError(je);
      }
      // Required if the user enter non integer value.
      catch(java.lang.NumberFormatException ne)
      {
         System.out.println("\n\nPlease enter integer values!");
         rstAuthors.close();
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstAuthors != null)
            if (rstAuthors.getState() == 1)
               rstAuthors.close();
      }
   }
   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndMoveJ

请参阅

Move 方法


MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法范例 (VJ++)

本范例使用 MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法，按照提供的命令移动 Recordset 的记录指针。运行此过程需要 MoveAny 过程。

// BeginMoveFirstJ
import com.ms.wfc.data.*;
import java.io.*;

public class MoveFirstX  // DLL name.
{
   // Main Function

   public static void main( String rgArg[] )
   {
      MoveFirstX();
   }

   // MoveFirstX Function

   static void MoveFirstX()
   {
      // Declarations
      Recordset rsAuthors = null;
      BufferedReader in =
            new BufferedReader(new InputStreamReader(System.in));
      String  line = null;

      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
         + "Initial Catalog='Pubs';Integrated Security='SSPI';";

      String strMessage = "UPDATE Titles SET type = 'psychology' "
         +"WHERE type = 'self_help'";

      int intCommand = 0;
      String strFName;
      String strLName;

      try
      {
         // Open recordset from Authors table.
         rsAuthors = new Recordset();
         rsAuthors.setCursorLocation( AdoEnums.CursorLocation.CLIENT );

         // Use client cursor to enable AbsolutePosition property.
         rsAuthors.open( "Authors", strCnn, AdoEnums.CursorType.STATIC,
            AdoEnums.LockType.BATCHOPTIMISTIC, AdoEnums.CommandType.TABLE );

         // Get user's move requests and show current record information.
         while( true )   // Continuous loop.
         {
            // Assign field information to variable to simplify output code.
            strFName = rsAuthors.getField("au_fname").getString();
            strLName = rsAuthors.getField("au_lname").getString();

            System.out.println
               ( "\nName: " + strFName + " " + strLName + "\n"
               + "Record " + rsAuthors.getAbsolutePosition()
               + " of " + rsAuthors.getRecordCount() + "\n\n" );
            System.out.println( "[1 - MoveFirst, 2 - MoveLast, \n");
            System.out.println( " 3 - MoveNext, 4 - MovePrevious]\n");

            // User types a number followed by enter (cr-lf).
            line = in.readLine();

            // No entry exits program loop.
            if (line.length() == 0) break;
            // Convert string entry to int.
            intCommand = Integer.parseInt(line);
            // Out of range entry exits program loop.
            if ((intCommand < 1) || (intCommand > 4)) break;

            // Call method based on user's validated selection.
            MoveAny(intCommand, rsAuthors);
         }
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rsAuthors != null)
         {
            PrintProviderError(rsAuthors.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }
      // System Read requires this catch.
      catch( java.io.IOException je )
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rsAuthors != null)
            if (rsAuthors.getState() == 1)
               rsAuthors.close();
      }
   }

   // MoveAny Function

   static void MoveAny(int intChoice, Recordset rsTemp)
   {
      // Move per selection from user, checking for BOF and EOF.
      try
      {
         switch(intChoice)
         {
         case 1:   // Equals char of 1.
            rsTemp.moveFirst();
            break;
         case 2:   // Equals char of 2.
            rsTemp.moveLast();
            break;
         case 3:   // Equals char of 3.
            rsTemp.moveNext();
            if(rsTemp.getEOF())
            {
               System.out.println("\nAlready at end of recordset!\n");
               rsTemp.moveLast();
            }
            break;
         case 4:   // Equals char of 4.
            rsTemp.movePrevious();
            if(rsTemp.getBOF())
            {
               System.out.println
                  ("\nAlready at beginning of recordset!\n");
               rsTemp.moveFirst();
            }
            break;
         default:
            break;
         }
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rsTemp != null)
         {
            PrintProviderError(rsTemp.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndMoveFirstJ

请参阅

MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法 | Recordset 对象


NextRecordset 方法范例 (VJ++)

本范例使用 NextRecordset 方法，查看使用复合命令语句的记录集中的数据，其中的复合命令语句由三个独立 SELECT 语句组成。

// BeginNextRecordsetJ
import java.io.*;
import com.ms.wfc.data.*;

public class NextRecordsetX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      NextRecordsetX();
      System.exit(0);
   }
   // NextRecordsetX Function
   static void NextRecordsetX()
   {
      // Define ADO Object
      Recordset rstCompound = null;

      // Declarations
      BufferedReader in =
         new BufferedReader(new InputStreamReader(System.in));
      String strCnn;
      int intCount;
      int intDisplayRecords = 15;
      int intRecordCount;

      try
      {
         // Open compound recordset.
         strCnn = "Provider='sqloledb';Data Source='MySqlServer';" +
             "Initial Catalog='Pubs';Integrated Security='SSPI';";

         rstCompound = new Recordset();
         rstCompound.open("select * from Authors;" +
             "select * from stores;" +
             "select * from jobs", strCnn, AdoEnums.CursorType.FORWARDONLY,
            AdoEnums.LockType.READONLY,AdoEnums.CommandType.TEXT);

         // Display results from each select statement.
         intCount=1;

         while (rstCompound != null)
         {
            System.out.println(
               "Contents of recordset #" + intCount + "\n");
            intRecordCount = 0;

            while(!rstCompound.getEOF())
               {
                  System.out.println(
                     rstCompound.getField(0).getString()+" " +
                     rstCompound.getField(1).getString());
                  intRecordCount++;

                  rstCompound.moveNext();
                  if ( intRecordCount == intDisplayRecords)
                  {
                     System.out.println("\nPress <Enter> to continue..");
                     in.readLine();
                     intRecordCount = 0;
                  }
               }
            System.out.println("\nPress <Enter> to continue..");
            in.readLine();

            rstCompound = rstCompound.nextRecordset();

            intCount++;
         }
      }
      // System read requires this catch.
      catch(java.io.IOException je)
      {
         PrintIOError(je);
      }
      catch(AdoException ae)
      {
         // Notify the user of any errors that result from ADO.

         // As passing a recordset. check for the null pointer first
         if(rstCompound!=null)
         {
            PrintProviderError(rstCompound.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }
      catch(java.lang.NullPointerException ne)
      {
         System.out.println("Error Description: " + ne.getMessage());
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstCompound != null)
            if (rstCompound.getState() == 1)
               rstCompound.close();
      }

   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndNextRecordsetJ

请参阅

NextRecordset 方法


NumericScale 和 Precision 属性范例 (VJ++)

本范例使用 NumericScale 和 Precision 属性来显示在 Pubs 数据库 Discounts 表中的字段的数值范围和精度。

// BeginNumericScaleJ
import com.ms.wfc.data.*;
import java.io.* ;

public class NumericScaleX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      NumericScaleX();
      System.exit(0);
   }

   // NumericScaleX function

   static void NumericScaleX()
   {

      // Define ADO Objects.
      Recordset rstDiscounts = null;
      Field fldTemp = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
          + "Initial Catalog='Pubs';Integrated Security='SSPI';";
      int intLoop;

      try
      {
         rstDiscounts = new Recordset();

         // Open recordset.
         rstDiscounts.open("Discounts", strCnn,
                    AdoEnums.CursorType.FORWARDONLY,
                    AdoEnums.LockType.READONLY,
                    AdoEnums.CommandType.TABLE);

         // Display numeric scale and precision of
         // numeric and small integer fields.
         for ( intLoop=0; intLoop <
            rstDiscounts.getFields().getCount();intLoop++)
         {
            fldTemp = rstDiscounts.getFields().getItem(intLoop);
            if((fldTemp.getType()== AdoEnums.DataType.NUMERIC) |
               (fldTemp.getType()== AdoEnums.DataType.SMALLINT))
            {
               System.out.println("\nField: "
                  + fldTemp.getName());
               System.out.println("\nNumeric scale: "
                  + fldTemp.getNumericScale());
               System.out.println("\nPrecision: "
                  + fldTemp.getPrecision());
               System.out.println("\n\nPress <Enter> to continue..");
               in.readLine();
            }
         }

      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstDiscounts != null)
         {
            PrintProviderError(rstDiscounts.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }

      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstDiscounts != null)
            if (rstDiscounts.getState() == 1)
               rstDiscounts.close();
      }

   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndNumericScaleJ

请参阅

NumericScale 属性 | Precision 属性


Open 和 Close 方法范例 (VJ++)

本范例在已打开的 Recordset 和 Connection 对象上使用 Open 和 Close 方法。

// BeginOpenJ
import com.ms.wfc.data.*;
import java.io.* ;
import com.ms.com.*;

public class OpenX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      OpenX();
      System.exit(0);
   }

   // OpenX function

   static void OpenX()
   {

      // Define ADO Objects.
      Connection cnConn1 = null;
      Recordset rstEmployees = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
                  + "Initial Catalog='Pubs';Integrated Security='SSPI';";
      Variant varDate;
      String strHDate;

      try
      {
         // Open connection.
         cnConn1 = new Connection();
         cnConn1.open(strCnn);

         // Open Employees table.
         rstEmployees = new Recordset();
         rstEmployees.setCursorType(AdoEnums.CursorType.KEYSET);
         rstEmployees.setLockType(AdoEnums.LockType.OPTIMISTIC);
         rstEmployees.open("Employee", cnConn1,
                    AdoEnums.CursorType.KEYSET,
                    AdoEnums.LockType.OPTIMISTIC,
                    AdoEnums.CommandType.TABLE);

         // Assign the first employee record's hire date
         // to a variable, then change the hire date.
         varDate = rstEmployees.getField("hire_date").getOriginalValue();
         System.out.println("Original data\n");
         System.out.println("\tName - Hire Date");
         strHDate = rstEmployees.getField("hire_date").getString();
         strHDate = strHDate.substring(5,7) + "/" +
            strHDate.substring(8,10)
             + "/" + strHDate.substring(2,4);
         System.out.println("\t" +
            rstEmployees.getField("fName").getString()+ " "
             + rstEmployees.getField("lName").getString()+ " - "
             + strHDate);
         System.out.println("\nPress <Enter> to continue..");
         in.readLine();
         rstEmployees.getField("hire_date").setString("1/1/1900");
         rstEmployees.update();
         System.out.println("Changed data\n");
         System.out.println("\tName - Hire Date");
         strHDate = rstEmployees.getField("hire_date").getString();
         strHDate = strHDate.substring(5,7) + "/" +
            strHDate.substring(8,10)
             + "/" + strHDate.substring(0,4);
         System.out.println("\t" +
            rstEmployees.getField("fName").getString()+ " "
             + rstEmployees.getField("lName").getString()+ " - "
             + strHDate);
         System.out.println("\nPress <Enter> to continue..");
         in.readLine();

         // Requery Recordset and reset the hire date.
         rstEmployees.requery();
         rstEmployees.getField("hire_date").setValue(varDate);
         rstEmployees.update();
         System.out.println("Data after reset\n");
         System.out.println("\tName - Hire Date");
         strHDate = rstEmployees.getField("hire_date").getString();
         strHDate = strHDate.substring(5,7) + "/" +
            strHDate.substring(8,10)
             + "/" + strHDate.substring(2,4);
         System.out.println("\t" +
            rstEmployees.getField("fName").getString()+ " "
             + rstEmployees.getField("lName").getString()+ " - "
             + strHDate);
         System.out.println("\nPress <Enter> to continue..");
         in.readLine();
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstEmployees != null)
         {
            PrintProviderError(rstEmployees.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }

      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstEmployees != null)
            if (rstEmployees.getState() == 1)
               rstEmployees.close();
         // Cleanup objects before exit.
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
      }

   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndOpenJ

请参阅

Close 方法 | Connection 对象 | Open 方法 (ADO Connection) | Open 方法 (ADO Recordset) | Recordset 对象


OpenSchema 方法范例 (VJ++)

本范例使用 OpenSchema 方法显示 Pubs 数据库中每个表的名称和类型。

// BeginOpenSchemaJ
import com.ms.wfc.data.*;
import java.io.*;
import com.ms.com.*;

public class OpenSchemaX
{
 // The main entry point of the application.

public static void main (String[] args)
{
   System.out.println("\nResults for OpenSchemaX:\n\n");
   OpenSchemaX();
   System.out.println("\nResults for OpenSchemaX2:\n\n");
   OpenSchemaX2();
   System.exit(0);
}

// OpenSchemaX Function
   static void OpenSchemaX()
   {
      // Define ADO Objects
      Connection cnn1 = null;
      Recordset rstSchema = null;

      //  Declarations
      String strCnn;
      BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
      int intDisplayRecords = 5;
      int intRecordCount = 0;

      try
      {

         cnn1 = new Connection();
         strCnn = "Provider = Microsoft.Jet.OLEDB.4.0;" +
            "Data Source=C:\\Program Files\\Microsoft " +
            "Office\\Office\\Samples\\Northwind.mdb;";
         cnn1.open(strCnn);
         rstSchema = cnn1.openSchema(AdoEnums.Schema.TABLES);

         while (!rstSchema.getEOF())
         {

            System.out.println("Table Name: " +
               rstSchema.getField("TABLE_NAME").getString()+"\n"+
               "Table Type: " +
               rstSchema.getField("TABLE_TYPE").getString()+"\n");
            intRecordCount++;
            if ( intRecordCount == intDisplayRecords)
            {
               System.out.println("Press <Enter> to continue..");
               in.readLine();
               intRecordCount = 0;
            }
            rstSchema.moveNext();

         }
         System.out.println("Press <Enter> to continue..");
         in.readLine();

      }
      catch(AdoException ae)
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if(rstSchema != null)
         {
            PrintProviderError(rstSchema.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }
      // System read requires this catch.
      catch(java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstSchema != null)
            if (rstSchema.getState() == 1)
               rstSchema.close();
         if (cnn1 != null)
            if (cnn1.getState() == 1)
               cnn1.close();
      }
   }

   // OpenSchemaX2 Function

   static void OpenSchemaX2()
   {
      // Define ADO Objects
      Connection cnn2 = null;
      Recordset rstSchema = null;

      // Declarations
      String strCnn;
      BufferedReader in =
         new BufferedReader(new InputStreamReader(System.in));
      int intDisplayRecords = 5;
      int intRecordCount = 0;

      try
      {
         cnn2 = new Connection();
         strCnn = "Provider = Microsoft.Jet.OLEDB.4.0;" +
            "Data Source=C:\\Program Files\\Microsoft " +
            "Office\\Office\\Samples\\Northwind.mdb;";
         cnn2.open(strCnn);

         Variant[] va = new Variant[4];
         va[0] = new Variant();
         va[1] = new Variant();
         va[2] = new Variant();
         va[3] = new Variant("VIEW");
         rstSchema = cnn2.openSchema(AdoEnums.Schema.TABLES,(Object[])va);

         while (!rstSchema.getEOF())
         {
            System.out.println("Table Name: " +
               rstSchema.getField("TABLE_NAME").getString()+"\n"+
               "Table Type: " +
               rstSchema.getField("TABLE_TYPE").getString()+"\n");
            intRecordCount++;
            if ( intRecordCount == intDisplayRecords)
            {
               System.out.println("Press <Enter> to continue..");
               in.readLine();
               intRecordCount = 0;
            }
            rstSchema.moveNext();

         }
         System.out.println("Press <Enter> to continue..");
         in.readLine();

      }
      catch(AdoException ae)
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if(rstSchema != null)
         {
            PrintProviderError(rstSchema.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }
      // System read requires this catch.
      catch(java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup Objects before exit.
         rstSchema.close();
         cnn2.close();
         // Cleanup objects before exit.
         if (rstSchema != null)
            if (rstSchema.getState() == 1)
               rstSchema.close();
         if (cnn2 != null)
            if (cnn2.getState() == 1)
               cnn2.close();
      }

   }
   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndOpenSchemaJ

请参阅

OpenSchema 方法


Optimize 属性范例 (VJ++)

本范例演示 Field 对象的动态 Optimize 属性。Pubs 数据库的 Authors 表的 Zip 字段未被索引。将 zip 字段的 Optimize 属性设置为 True 将授权 ADO 建立索引，以提高 Find 方法的性能。

// BeginOptimizeJ
import com.ms.wfc.data.*;
import java.io.* ;

public class OptimizeX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      OptimizeX();
      System.exit(0);
   }

   // OptimizeX function

   static void OptimizeX()
   {

      // Define ADO Objects.
      Recordset rstAuthors = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
         + "Initial Catalog='Pubs';Integrated Security='SSPI';";

      try
      {
         rstAuthors = new Recordset();
         rstAuthors.setCursorLocation(AdoEnums.CursorLocation.CLIENT);
         // Enable index creation.
         rstAuthors.open("SELECT * FROM Authors",
               strCnn,
               AdoEnums.CursorType.STATIC,
               AdoEnums.LockType.READONLY,
               AdoEnums.CommandType.TEXT);
         rstAuthors.getField("zip").getProperties().
            getItem("Optimize").setBoolean(true); // Create the index.
         rstAuthors.find("zip = '94595'");   // Find Akiko Yokomoto.
         System.out.println(rstAuthors.getField("au_fname").getString() +
            " " + rstAuthors.getField("au_lname").getString() + " " +
            rstAuthors.getField("address").getString() + " " +
            rstAuthors.getField("city").getString() + " " +
            rstAuthors.getField("state").getString() + " ");
         rstAuthors.getField("zip").getProperties().
            getItem("Optimize").setBoolean(false); // Delete the index.

         System.out.println("\nPress <Enter> to continue..");
         in.readLine();
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstAuthors != null)
         {
            PrintProviderError(rstAuthors.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstAuthors != null)
            if (rstAuthors.getState() == 1)
               rstAuthors.close();
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndOptimizeJ

请参阅

Field 对象 | Optimize 动态属性 (ADO)


OriginalValue 和 UnderlyingValue 属性范例 (VJ++)

本范例演示 OriginalValue 和 UnderlyingValue 属性。如果在 Recordset 批更新过程中记录的基本数据发生了更改，就会显示一条信息。

// BeginOriginalValueJ
import com.ms.wfc.data.*;
import java.io.* ;

public class OriginalValueX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      OriginalValueX();
      System.exit(0);
   }

   // OriginalValueX function

   static void OriginalValueX()
   {
      // Define ADO Objects.
      Connection cnConn1 = null;
      Recordset rstTitles = null;
      Field fldType = null;

      // Declarations.
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
         + "Initial Catalog='Pubs';Integrated Security='SSPI';";
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));

      try
      {
         // Open a connection.
         cnConn1 = new Connection();
         cnConn1.open(strCnn);

         // Open recordset for batch update.
         rstTitles = new Recordset();
         rstTitles.setActiveConnection(cnConn1);
         rstTitles.setCursorType(AdoEnums.CursorType.KEYSET);
         rstTitles.setLockType(AdoEnums.LockType.BATCHOPTIMISTIC);
         rstTitles.open("Titles",cnConn1,
                     AdoEnums.CursorType.KEYSET,
                     AdoEnums.LockType.BATCHOPTIMISTIC,
                     AdoEnums.CommandType.TABLE);

         // Set field object variable for Type field.
         fldType = rstTitles.getField("type");

         // Change the type of psychology titles.
         while(!rstTitles.getEOF())
         {
            if(rstTitles.getField("type").getString().
               trim().equals("psychology"))
               fldType.setString("self_help");
            rstTitles.moveNext();
         }

         // Similate a change by another user by updating
         // data using a command string.
         cnConn1.execute("UPDATE Titles SET type = 'sociology' "
                        + "WHERE type = 'psychology'");

         // Check for changes.
         rstTitles.moveFirst();

         while(!rstTitles.getEOF())
         {
            String strOriginalValue =
               fldType.getOriginalValue().toString().trim();
            String strUnderlyingValue =
               fldType.getUnderlyingValue().toString().trim();
            if(!(strOriginalValue.equals(strUnderlyingValue)))
            {
               System.out.println("Data has changed!" + "\n\n");
               System.out.println("\tTitle ID: "
                  + rstTitles.getField("title_id").getString().trim() +
                  "\n");
               System.out.println("\tCurrent value: "
                     + fldType.getString()+ "\n");
               System.out.println("\tOriginal value: "
                     + fldType.getOriginalValue().toString()+ "\n");
               System.out.println("\tUnderlying value: "
                     + fldType.getUnderlyingValue().toString()+ "\n");
               System.out.println("\n\nPress <Enter> to continue..");
               in.readLine();
            }
            rstTitles.moveNext();
         }
         // Cancel the update because this is a demonstration.

         rstTitles.cancelBatch();

         // Restore original values.
         cnConn1.execute("UPDATE Titles SET type = 'psychology' "
                     + "WHERE type = 'sociology'");
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstTitles!= null)
         {
            PrintProviderError(rstTitles.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstTitles != null)
            if (rstTitles.getState() == 1)
               rstTitles.close();
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
      }

   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndOriginalValueJ

请参阅

OriginalValue 属性 | Recordset 对象 | UnderlyingValue 属性


Prepared 属性范例 (VJ++)

本范例打开两个 Command 对象（一个已准备好，另一个未准备好），来演示 Prepared 属性。

// BeginPreparedJ
import com.ms.wfc.data.*;
import java.io.* ;

public class PreparedX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      PreparedX();
      System.exit(0);
   }

   // PreparedX function

   static void PreparedX()
   {
      // Define string variables.
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
            + "Initial Catalog='Pubs';Integrated Security='SSPI';";
      String strCmd = "SELECT title, type FROM Titles ORDER BY type";

      // Define ADO Objects.
      Connection cnConn1 = null;
      Command cmd1 = null;
      Command cmd2 = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      long timeStart;
      long timeEnd;
      float timeNotPrepared ;
      float timePrepared;
      int   intLoop;
      String strTemp;

      try
      {
         // Open a connection.
         cnConn1 = new Connection();
         cnConn1.open(strCnn);

         // Create two command objects for the same
         // command - one prepared and one not prepared.
         cmd1 = new Command();
         cmd1.setActiveConnection(cnConn1);
         cmd1.setCommandType(AdoEnums.CommandType.TEXT);
         cmd1.setCommandText(strCmd);

         cmd2 = new Command();
         cmd2.setActiveConnection(cnConn1);
         cmd2.setCommandType(AdoEnums.CommandType.TEXT);
         cmd2.setCommandText(strCmd);
         cmd2.setPrepared(true);

         // Set a timer, then execute the unprepared
         // command 20 times.
         timeStart = System.currentTimeMillis();
         for ( intLoop = 0; intLoop < 20; intLoop++)
            cmd1.execute();
         timeEnd = System.currentTimeMillis();
         timeNotPrepared =(float)(timeEnd - timeStart)/1000f;

         // Reset the timer, then execute the prepared
         // command 20 times.
         timeStart = System.currentTimeMillis();
         for ( intLoop = 0; intLoop < 20; intLoop++)
            cmd2.execute();
         timeEnd = System.currentTimeMillis();
         timePrepared =(float)(timeEnd - timeStart)/1000f;

         // Display performance results.
         System.out.println("\nPerformance Results:");
         System.out.println("\n\tNot Prepared: " + timeNotPrepared +
            " seconds");
         System.out.println("\n\tPrepared: " + timePrepared +
            " seconds");
         System.out.println("\n\nPress <Enter> to continue..");
         in.readLine();

      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Connection, check for null pointer first.
         if (cnConn1!= null)
         {
            PrintProviderError(cnConn1);
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
      }

   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndPreparedJ

请参阅

Command 对象 | Prepared 属性


Provider 和 DefaultDatabase 属性范例 (VJ++)

本范例通过打开三个使用不同提供者的 Connection 对象来演示 Provider 属性。范例中还使用 DefaultDatabase 属性设置 Microsoft ODBC Provider 的默认数据库。

// BeginProviderJ
import java.io.*;
import com.ms.wfc.data.*;

public class ProviderX
{
   //    The main entry point of the application.
   public static void main (String[] args)
   {
      ProviderX();
      System.exit(0);
   }
   // ProviderX Function
   static void ProviderX()
   {
      // Define ADO Objects.
      Connection cnn1 = null;
      Connection cnn2 = null;
      Connection cnn3 = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader(new InputStreamReader(System.in));
      try
      {
         // Open a connection using the Microsoft ODBC Provider.
         cnn1 = new Connection();
         cnn1.setConnectionString("driver={SQL Server};"+
             "server='MySqlServer';User ID='MyUserID';Password='MyPassword';");
         cnn1.open();
         cnn1.setDefaultDatabase("Pubs");

         // Display the provider.
         System.out.println("\n\n\tCnn1 provider: "+ cnn1.getProvider());

         // Open connection using the OLE DB Provider for Microsoft Jet.
         cnn2 = new Connection();
         cnn2.setProvider("Microsoft.Jet.OLEDB.4.0");
         cnn2.open("C:\\Program Files\\Microsoft Office\\Office\\Samples\\Northwind.mdb","admin","");

         // Display the provider.
         System.out.println("\n\n\tCnn2 provider: " +
            cnn2.getProvider());

         // Open a connection using the Microsoft SQL Server Provider.
         cnn3 = new Connection();
         cnn3.setProvider("sqloledb");
         cnn3.open("Data Source='MySqlServer';Initial Catalog='Pubs';Integrated Security='SSPI';","","");

         // Display the provider.
         System.out.println("\n\n\tCnn3 provider: " +
            cnn3.getProvider());

         System.out.println("\n\n\tPress <Enter> to continue..");
         in.readLine();
      }
      catch(AdoException ae)
      {
         // Notify the user of any errors that result from ADO.

         // As passing a Connection, check for null pointer first.
         if(cnn1 != null)
         {
            PrintProviderError(cnn1);
         }
         else
         {
            System.out.println("Exception: " + ae.getLocalizedMessage());
         }
      }
      // System read requires needs this catch.
      catch(java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (cnn1 != null)
            if (cnn1.getState() == 1)
               cnn1.close();
         if (cnn2 != null)
            if (cnn2.getState() == 1)
               cnn2.close();
         if (cnn3 != null)
            if (cnn3.getState() == 1)
               cnn3.close();
      }
   }
   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndProviderJ

请参阅

Connection 对象 | DefaultDatabase 属性 | Provider 属性


Refresh 方法范例 (VJ++)

本范例演示使用 Refresh 方法来刷新存储过程 Command 对象的 Parameters 集合。

// BeginRefreshJ
import  com.ms.wfc.data.*;
import java.io.*;

public class RefreshX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      RefreshX();
      System.exit(0);
   }

   // RefreshX function

   static void RefreshX()
   {
      // Define ADO Objects.
      Connection cnConn1 = null;
      Command cmdByRoyalty = null;
      Recordset rstByRoyalty = null;
      Recordset rstAuthors = null;

      //Declarations.
      String strAuthorID;
      String strFName;
      String strLName;
      int intRoyalty ;
      BufferedReader in =
         new BufferedReader (new InputStreamReader (System.in));
      String line = null;

      try
      {
         // Open a connection.
         String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"
                     + "Initial Catalog='Pubs';Integrated Security='SSPI';";

         cnConn1 = new Connection();
         cnConn1.open(strCnn);

         // Open a command object for a stored procedure
         // with one parameter.
         cmdByRoyalty = new Command();
         cmdByRoyalty.setActiveConnection(cnConn1);
         cmdByRoyalty.setCommandText("byRoyalty");
         cmdByRoyalty.setCommandType(AdoEnums.CommandType.STOREDPROC);
         cmdByRoyalty.getParameters().refresh();

         // Get Parameter value and execute the command
         // storing the results in the recordset.
         System.out.println ("\nEnter Royalty : ");
         line = in.readLine().trim();
         intRoyalty = Integer.parseInt(line);
         cmdByRoyalty.getParameters().getItem(1).setInt(intRoyalty);

         // Create a recordset by executing the command.
         rstByRoyalty = cmdByRoyalty.execute();

         // Open the Authors table to get author names for display.
         rstAuthors = new Recordset ();
         rstAuthors.open(
            "Authors",strCnn,AdoEnums.CursorType.FORWARDONLY,
            AdoEnums.LockType.READONLY, AdoEnums.CommandType.TABLE );

         // Print current data in the recordset,
         // adding author names from Authors table.
         System.out.println("\nAuthors with " + intRoyalty +
                        " percent royalty");
         while (!rstByRoyalty.getEOF())
         {
            strAuthorID =  rstByRoyalty.getField("au_id").getString();
            rstAuthors.setFilter("au_id ='" +  strAuthorID + "'");
            strFName = rstAuthors.getField("au_fname").getString();
            strLName = rstAuthors.getField("au_lname").getString();
            System.out.println("\t" + strAuthorID + ", " + strFName
                           + " " + strLName);
            rstByRoyalty.moveNext();
         }
         System.out.println("\n\nPress <Enter> key to continue..");
         line = in.readLine();

      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstByRoyalty != null)
         {
            PrintProviderError(rstByRoyalty.getActiveConnection());
         }
         else if (rstAuthors != null)
         {
            PrintProviderError(rstAuthors.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // This catch is required if input string cannot be converted to
      // Integer data type.
      catch ( java.lang.NumberFormatException ne)
      {
            System.out.println("\nException: Integer Input required.");
      }
      // System Read requires this catch.
      catch( java.io.IOException je )
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstByRoyalty != null)
            if (rstByRoyalty.getState() == 1)
               rstByRoyalty.close();
         if (rstAuthors != null)
            if (rstAuthors.getState() == 1)
               rstAuthors.close();
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndRefreshJ

请参阅

Command 对象 | Parameters 集合 | Refresh 方法


Resync 方法范例 (VJ++)

本范例演示使用 Resync 方法来刷新静态记录集中的数据。

// BeginResyncJ
import java.io.*;
import com.ms.wfc.data.*;

public class ResyncX
{
   // The main entry point of the application.
   public static void main (String[] args)
   {
      ResyncX();
      System.exit(0);
   }
   static void ResyncX()
   {
      // Define ADO Objects.
      Recordset rstTitles = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader(new InputStreamReader(System.in));
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';" +
                  "Initial Catalog='Pubs';Integrated Security='SSPI';";

      try
      {
         // Open recordset for Titles table.
         rstTitles = new Recordset();
         rstTitles.setCursorLocation(AdoEnums.CursorLocation.CLIENT);
         rstTitles.setCursorType(AdoEnums.CursorType.STATIC);
         rstTitles.setLockType(AdoEnums.LockType.BATCHOPTIMISTIC);
         rstTitles.open("Titles", strCnn, AdoEnums.CursorType.STATIC,
            AdoEnums.LockType.BATCHOPTIMISTIC,
            AdoEnums.CommandType.TABLE);

         // Change the type of the first title in the recordset.
         rstTitles.getField("type").setString("database");

         // Display the results of the change.
         System.out.println("\n\n\tBefore resync:\n" + "\tTitle - " +
            rstTitles.getField("title").getString() +
            "\n\tType  - " + rstTitles.getField("type").getString());

         // Resync with database and redisplay the results.
         rstTitles.resync();
         System.out.println("\n\n\tAfter resync:\n" + "\tTitle - " +
            rstTitles.getField("title").getString() +
            "\n\tType  - " +
            rstTitles.getField("type").getString()+"\n");
         rstTitles.cancelBatch();

         System.out.println("\tPress <Enter> to continue..");
         in.readLine();

      }
      catch(AdoException ae)
      {
         // Notify user of any errors that result from ADO.

         // As passing a recordset, check for null pointer first.
         if(rstTitles != null)
         {
            PrintProviderError(rstTitles.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }
      // System read requires this catch.
      catch(java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstTitles != null)
            if (rstTitles.getState() == 1)
               rstTitles.close();
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndResyncJ

请参阅

Resync 方法


Save 和 Open 方法范例 (VJ++)

这三个范例演示如何配合使用 Save 和 Open 方法。

假设用户在出差时需要携带数据库中的一个表。在出发前，用户以 Recordset 访问数据，并将其保存为便携格式。在到达目的地后，用户以本地、断开连接的 Recordset 访问 Recordset，在修改 Recordset 后将其保存。最后，当用户回家后，再次连接数据库并用旅途中所做的更改对其进行更新。

// BeginSaveJ
import com.ms.wfc.data.*;
import java.io.* ;

public class SaveX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      SaveX1();
      SaveX2();
      SaveX3();
      System.exit(0);
   }

   // First, access and save the Authors table.

   // SaveX1 function

   static void SaveX1()
   {
      // Define ADO Objects.
      Recordset rstAuthors = null;

      // Declarations.
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';" +
                      "Initial Catalog='Pubs';Integrated Security='SSPI';";
      BufferedReader in =
         new BufferedReader(new InputStreamReader(System.in));
      File file;

      try
      {
         rstAuthors = new Recordset();
         rstAuthors.setCursorLocation(AdoEnums.CursorLocation.CLIENT);
         rstAuthors.open("SELECT * FROM Authors",
                        strCnn,
                        AdoEnums.CursorType.DYNAMIC,
                        AdoEnums.LockType.OPTIMISTIC,
                        AdoEnums.CommandType.TEXT);

         // For the sake of illustration, save the recordset to a
         //diskette in XML format.
         file = new File("c:\\Pubs.xml");
         if(!file.exists())
            rstAuthors.save("c:\\Pubs.xml",AdoEnums.PersistFormat.XML);
         else
         {
            System.out.println("\nFile already exists.");
            System.out.println("\nPress <Enter> to continue..");
            in.readLine();
            System.exit(0);
         }
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstAuthors != null)
         {
            PrintProviderError(rstAuthors.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }
      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstAuthors != null)
            if (rstAuthors.getState() == 1)
               rstAuthors.close();
      }
   }

   // At this point, you have arrived at your destination. You will
   // access the Authors table as a local, disconnected Recordset.
   // Don't forget you must have the MSPersist provider on the machine
   // you are using in order to access the saved file, a:\Pubs.xml.

   // SaveX2 function

   static void SaveX2()
   {
      // Define ADO Objects.
      Recordset rstAuthors = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader(new InputStreamReader(System.in));

      try
      {
         rstAuthors = new Recordset();

         // For sake of illustration, we specify all parameters.
         rstAuthors.open("c:\\Pubs.xml",
               "Provider=MSPersist;",
               AdoEnums.CursorType.FORWARDONLY,
               AdoEnums.LockType.BATCHOPTIMISTIC,
               AdoEnums.CommandType.FILE);

         // Now you have a local, disconnected recordset.
         // Edit it as you desire.
         // (In this example, the change makes no difference).
         rstAuthors.find("au_lname = 'Carson'");
         if(rstAuthors.getEOF())
         {
            System.out.println("Name not found.");
            System.out.println("\nPress <Enter> to continue..");
            in.readLine();
            return;
         }
         rstAuthors.getField("city").setString("Berkeley");
         rstAuthors.update();

         // Save changes in ADTG format this time, for illustration.
         // Note that previous version on the diskette, as a:\Pubs.xml.
         rstAuthors.save("c:\\Pubs.adtg",AdoEnums.PersistFormat.ADTG);

      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstAuthors != null)
         {
            PrintProviderError(rstAuthors.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstAuthors != null)
            if (rstAuthors.getState() == 1)
               rstAuthors.close();
      }
   }

   // Finally, update the database with your changes.

   // SaveX3 function

   static void SaveX3()
   {
      // Define ADO Objects.
      Connection cnConn1 = null;
      Recordset rstAuthors = null;

      // Declarations.
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';" +
                      "Initial Catalog='Pubs';Integrated Security='SSPI';";

      try
      {
         // If there is no ActiveConnection, you can open with defaults.
         rstAuthors = new Recordset();
         rstAuthors.open("c:\\Pubs.adtg");

         // Connect to the database, associate the Recordset with
         // connection, then update the database table with the changed
         // Recordset.
         cnConn1 = new Connection();
         cnConn1.open(strCnn);
         rstAuthors.setActiveConnection(cnConn1);
         rstAuthors.updateBatch();
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstAuthors != null)
         {
            PrintProviderError(rstAuthors.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstAuthors != null)
            if (rstAuthors.getState() == 1)
               rstAuthors.close();
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
      }
   }

   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndSaveJ


Sort 属性范例 (VJ++)

本范例使用 Recordset 对象的 Sort 属性来调整 Recordset 中行的顺序，该 Recordset 来自 Pubs 数据库的 Authors 表。辅助实用程序例程将打印每一行。

// BeginSortJ
import com.ms.wfc.data.*;
import java.io.* ;

public class SortX
{
   // The main entry point for the application.

   public static void main (String[] args)
   {
      SortX();
      System.exit(0);
   }

   // SortX function

   static void SortX()
   {
      // Define ADO Objects.
      Connection cnConn1 = null;
      Recordset rstAuthors = null;

      // Declarations.
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';" +
                      "Initial Catalog='Pubs';Integrated Security='SSPI';";

      try
      {
         cnConn1 = new Connection();
         cnConn1.open(strCnn);
         rstAuthors = new Recordset();
         rstAuthors.setCursorLocation(AdoEnums.CursorLocation.CLIENT);
         rstAuthors.open("SELECT * FROM Authors",
               cnConn1,
               AdoEnums.CursorType.STATIC,
               AdoEnums.LockType.READONLY,
               AdoEnums.CommandType.TEXT);
         SortXprint("Initial Order",rstAuthors);

         rstAuthors.setSort("au_lname ASC, au_fname ASC");
         SortXprint("Last Name Ascending",rstAuthors);

         rstAuthors.setSort("au_lname DESC, au_fname ASC");
         SortXprint("Last Name Descending",rstAuthors);
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstAuthors != null)
         {
            PrintProviderError(rstAuthors.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstAuthors != null)
            if (rstAuthors.getState() == 1)
               rstAuthors.close();
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
      }

   }

   // SortXprint function

   static void SortXprint(String strTitle,Recordset rstp)
   {
      // Declarations.
      BufferedReader in =
         new BufferedReader (new InputStreamReader(System.in));
      int intDisplaysize = 15;
      int intCount = 1;
      try
      {
         System.out.println("---------------" +
                        strTitle +
                        "---------------");
         System.out.println("First Name   Last Name" + "\n" +
                        "-------------------------" +
                        "-------------------------");
         rstp.moveFirst();
         while(!rstp.getEOF())
         {
            System.out.println(rstp.getField("au_fname").getString() +
                           "   " +
                           rstp.getField("au_lname").getString());
            if(intCount % intDisplaysize == 0)
            {
               System.out.println("\nPress <Enter> to continue..");
               in.readLine();
               intCount = 0;
            }
            intCount++;
            rstp.moveNext();
         }
         System.out.println("\nPress <Enter> to continue..");
         in.readLine();
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstp != null)
         {
            PrintProviderError(rstp.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }
   }
   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndSortJ

请参阅

Recordset 对象 | Sort 属性


Source 属性范例 (VJ++)

本范例通过打开三个基于不同数据源的 Recordset 对象来演示 Source 属性。

// BeginSourceJ
import java.io.*;
import com.ms.wfc.data.*;

public class SourceX
{
   // The main entry point of the application.
   public static void main (String[] args)
   {
      SourceX();
      System.exit(0);
   }
   // SourceX Function
   static void SourceX()
   {
      // Define string variables.
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';" +
                  "Initial Catalog='Pubs';Integrated Security='SSPI';";
      String strSQL = "SELECT title_ID AS TitleID, title AS Title,"+
                "publishers.pub_id AS PubID, pub_name AS PubName "+
                "FROM publishers INNER JOIN Titles "+
                "ON publishers.pub_id=Titles.pub_id "+
                "ORDER BY Title";

      // Define ADO Objects.
      Connection cnn1 = null;
      Recordset rstTitles = null;
      Recordset rstPublishers = null;
      Recordset rstPublishersDirect = null;
      Recordset rstTitlesPublishers = null;
      Command cmdSQL = null;

      // Declarations.
      BufferedReader in =
         new BufferedReader(new InputStreamReader(System.in));

      try
      {
         // Open a connection.
         cnn1 = new Connection();
         cnn1.open(strCnn);

         // Open a recordset based on a command object.
         cmdSQL = new Command();
         cmdSQL.setActiveConnection(cnn1);
         cmdSQL.setCommandText("Select title,type,pubdate " +
             "FROM Titles ORDER BY title");

         rstTitles = new Recordset();
         rstTitles = cmdSQL.execute();

         // Open a recordset based on a table.
         rstPublishers = new Recordset();
         rstPublishers.open("publishers", strCnn,
            AdoEnums.CursorType.FORWARDONLY, AdoEnums.LockType.READONLY,
            AdoEnums.CommandType.TABLE);

         // Open a recordset based on a table.
         rstPublishersDirect = new Recordset();
         rstPublishersDirect.open("publishers", strCnn,
            AdoEnums.CursorType.FORWARDONLY, AdoEnums.LockType.READONLY,
            AdoEnums.CommandType.TABLEDIRECT);

         // Open a recordset based on an SQL String.
         rstTitlesPublishers = new Recordset();

         rstTitlesPublishers.open(strSQL, strCnn,
            AdoEnums.CursorType.FORWARDONLY, AdoEnums.LockType.READONLY,
            AdoEnums.CommandType.TEXT);

         // Use Source property to display the source of each recordset.
         System.out.println("\nrstTitles source: \n"+
            rstTitles.getSource());
         System.out.println("\nrstPublishers source: \n"+
            rstPublishers.getSource());
         System.out.println("\nrstPublishersDirect source:\n" +
            rstPublishersDirect.getSource() );
         System.out.println("\nrstTitlesPublishers source: \n" +
            rstTitlesPublishers.getSource());

         System.out.println("\n\nPress <Enter> to continue..");
         in.readLine();
      }
      catch(AdoException ae)
      {
         // Notify the user of any errors that result from ADO.

         // As passing a recordset, check for null pointer first.

         if(rstPublishers != null)
         {
            PrintProviderError(rstPublishers.getActiveConnection());
         }
         else if(rstPublishersDirect != null)
         {
            PrintProviderError(
               rstPublishersDirect.getActiveConnection());
         }
         else if(rstTitles != null)
         {
            PrintProviderError(rstTitles.getActiveConnection());
         }
         else if(rstTitlesPublishers != null)
         {
            PrintProviderError(
               rstTitlesPublishers.getActiveConnection());
         }
         else
            System.out.println("Exception: " + ae.getMessage());

      }
      // System read requires this catch.
      catch(java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstTitles != null)
            if (rstTitles.getState() == 1)
               rstTitles.close();
         if (rstPublishers != null)
            if (rstPublishers.getState() == 1)
               rstPublishers.close();
         if (rstPublishersDirect != null)
            if (rstPublishersDirect.getState() == 1)
               rstPublishersDirect.close();
         if (rstTitlesPublishers != null)
            if (rstTitlesPublishers.getState() == 1)
               rstTitlesPublishers.close();
         if (cnn1 != null)
            if (cnn1.getState() == 1)
               cnn1.close();
      }

   }
   // PrintProviderError Function

   static void PrintProviderError( Connection Cnn1 )
   {
      // Print Provider errors from Connection object.
      // ErrItem is an item object in the Connections Errors collection.
      com.ms.wfc.data.Error  ErrItem = null;
      long nCount = 0;
      int  i      = 0;

      nCount = Cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if( nCount > 0);
      {
         // Collection ranges from 0 to nCount - 1
         for (i = 0; i< nCount; i++)
         {
            ErrItem = Cnn1.getErrors().getItem(i);
            System.out.println("\t Error number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription() );
         }
      }

   }

   // PrintIOError Function

   static void PrintIOError( java.io.IOException je)
   {
      System.out.println("Error \n");
      System.out.println("\tSource = " + je.getClass() + "\n");
      System.out.println("\tDescription = " + je.getMessage() + "\n");
   }
}
// EndSourceJ

请参阅

Recordset 对象 | Source 属性 (ADO Recordset)


State 属性范例 (VJ++)

本范例使用 State 属性，在异步连接为开且异步命令正在执行时显示消息。

// BeginStateJ
import com.ms.wfc.data.*;
import java.io.*;

public class StateX
{
   // The main entry point of the application.
   public static void main (String[] args)
   {
      StateX();
      System.exit(0);
   }
   // StateX Function
   static void StateX()
   {
      // Define ADO Objects.
      Connection cnn1 = null;
      Connection cnn2 = null;
      Command cmdChange = null;
      Command cmdRestore = null;

      // Declarations.
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"+
                  "Initial Catalog='Pubs';Integrated Security='SSPI';";
      BufferedReader in =
         new BufferedReader(new InputStreamReader(System.in));

      try
      {
         // Open two Asynchronous connections, displaying
         // a message while connecting.
         cnn1 = new Connection();
         cnn2 = new Connection();

         cnn1.open(strCnn,"","",AdoEnums.ConnectOption.ASYNCCONNECT);
         while(cnn1.getState()==AdoEnums.ObjectState.CONNECTING)
            System.out.println("Opening the first connection....");

         cnn2.open(strCnn,"","",AdoEnums.ConnectOption.ASYNCCONNECT);
         while(cnn2.getState()==AdoEnums.ObjectState.CONNECTING)
            System.out.println("Opening the second connection....");

         // Create two command Objects.
         cmdChange = new Command();
         cmdChange.setActiveConnection(cnn1);
         cmdChange.setCommandText("UPDATE Titles SET type = 'self_help'"+
                            "WHERE type = 'psychology'");

         cmdRestore = new Command();
         cmdRestore.setActiveConnection(cnn2);
         cmdRestore.setCommandText(
            "UPDATE Titles SET type = 'psychology'"+
            "WHERE type = 'self_help'");

         // Executing the commands, displaying a message
         // while they are executing.
         cmdChange.execute(null,AdoEnums.ExecuteOption.ASYNCEXECUTE);

         while(cmdChange.getState() == AdoEnums.ObjectState.EXECUTING)
            System.out.println("Change command executing....");

         cmdRestore.execute(null,AdoEnums.ExecuteOption.ASYNCEXECUTE);

         while(cmdRestore.getState() == AdoEnums.ObjectState.EXECUTING)
            System.out.println("Restore command executing....");

         System.out.println("Press <Enter> to continue..");
         in.readLine();
      }
      // System read requires this catch.
      catch(java.io.IOException je)
      {
         PrintIOError(je);
      }
      catch(AdoException ae)
      {
         // Notify user of any errors resulting from ADO.

         // As passing a connection, check for null pointer first.
         if(cnn1 != null)
         {
            System.out.println("The error has occured in cnn1:");
            PrintProviderError(cnn1);
         }
         else if(cnn2 != null)
         {
            System.out.println("The error has occured in cnn2:");
            PrintProviderError(cnn2);
         }
         else
         {
            System.out.println("Exception: "+ ae.getMessage());
         }
      }

      finally
      {
         // Cleanup objects before exit.
         if (cnn1 != null)
            if (cnn1.getState() == 1)
               cnn1.close();
         if (cnn2 != null)
            if (cnn2.getState() == 1)
               cnn2.close();
      }

   }
   // PrintProviderError Function
   static void PrintProviderError(Connection cnn1)
   {
      // Print Provider Errors from Connection Object.
      // ErrItem is an item object in the Connections Errors Collection.
      com.ms.wfc.data.Error               ErrItem = null;
      long                                 nCount = 0;
      int                                       i = 0;

      nCount = cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if ( nCount > 0)
      {
         // Collection ranges from 0 to nCount-1.
         for ( i=0;i<nCount; i++)
         {
            ErrItem = cnn1.getErrors().getItem(i);
            System.out.println("\t Error Number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription());
         }
      }
   }
   // PrintIOError Function
   static void PrintIOError(java.io.IOException je)
   {
      System.out.println("Error: \n");
      System.out.println("\t Source: " + je.getClass() + "\n");
      System.out.println("\t Description: "+ je.getMessage() + "\n");
   }
}
// EndStateJ

请参阅

State 属性


Status 属性范例 (VJ++)

本范例使用 Status 属性来显示在批更新发生前被批操作修改的记录。

// BeginStatusJ
import java.io.*;
import com.ms.wfc.data.*;

public class StatusX
{
   // The main entry point of the application.

   public static void main (String[] args)
   {
      StatusX();
      System.exit(0);
   }
   // StatusX Function

   static void StatusX()
   {
      // Define ADO Objects.
      Recordset rstTitles = null;

      // Declarations.
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"+
                  "Initial Catalog='Pubs';Integrated Security='SSPI';";
      BufferedReader in =
         new BufferedReader(new InputStreamReader(System.in));

      try
      {
         // Open Recordset for batch update.
         rstTitles = new Recordset();
         rstTitles.setCursorType(AdoEnums.CursorType.KEYSET);
         rstTitles.setLockType(AdoEnums.LockType.BATCHOPTIMISTIC);
         rstTitles.open("Titles", strCnn, AdoEnums.CursorType.KEYSET,
            AdoEnums.LockType.BATCHOPTIMISTIC,
            AdoEnums.CommandType.TABLE);

         // Change the type of psychology titles.
         while(!rstTitles.getEOF())
         {
            if(rstTitles.getField("Type").getString().trim().
               equals(new String("psychology")))
               rstTitles.getField("Type").setString("self_help");

            rstTitles.moveNext();
         }

         // Display Title ID and status.
         rstTitles.moveFirst();

         while(!rstTitles.getEOF())
         {
            if(rstTitles.getStatus()==AdoEnums.RecordStatus.MODIFIED)
               System.out.println(rstTitles.getField("title_id").
                  getString() + "-  Modified");
            else
               System.out.println(rstTitles.getField("title_id").
                  getString());
            rstTitles.moveNext();
         }

         // Cancel the update because this is a demonstration.
         rstTitles.cancelBatch();

         System.out.println("Press <Enter> to continue..");
         in.readLine();
      }
      catch(AdoException ae)
      {
         // Notify the user of any errors that result from ADO.

         // As passing a Recordset, check for the null pointer first.
         if(rstTitles != null)
         {
            PrintProviderError(rstTitles.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }
      // System read requires this catch.
      catch(java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstTitles != null)
            if (rstTitles.getState() == 1)
               rstTitles.close();
      }
   }
   // PrintProviderError Function
   static void PrintProviderError(Connection cnn1)
   {
      // Print Provider Errors from Connection Object.
      // ErrItem is an item object in the Connections Errors Collection.
      com.ms.wfc.data.Error               ErrItem = null;
      long                                 nCount = 0;
      int                                       i = 0;

      nCount = cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if ( nCount > 0)
      {
         // Collection ranges from 0 to nCount-1.
         for ( i=0;i<nCount; i++)
         {
            ErrItem = cnn1.getErrors().getItem(i);
            System.out.println("\t Error Number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription());
         }
      }
   }
   // PrintIOError Function
   static void PrintIOError(java.io.IOException je)
   {
      System.out.println("Error: \n");
      System.out.println("\t Source: " + je.getClass() + "\n");
      System.out.println("\t Description: "+ je.getMessage() + "\n");
   }
}
// EndStatusJ

请参阅

Status 属性 (ADO Recordset)


StayInSync 属性范例 (VJ++)

本范例演示 StayInSync 属性如何方便地访问分级 Recordset 的行。

外循环显示每个作者的姓名、州/省别和标识。每行追加的 Recordset 都从 Fields 集合进行检索，一旦父 Recordset 移至新行，StayInSync 属性即自动将其分配给 rstTitleAuthor。内循环显示追加的记录集中每行的四个字段。

// BeginStayInSyncJ
import com.ms.wfc.data.*;
import java.io.* ;
import com.ms.com.*;

public class StayInSyncX
{
    // The main entry point for the application.

   public static void main (String[] args)
   {
      StayInSyncX();
      System.exit(0);
   }

   // StayInSyncX function

   static void StayInSyncX()
   {

      // Define ADO Objects.
      Connection cnConn1 = null;
      Recordset rstAuthors = null;
      Recordset rstTitleAuthor = null;

      // Declarations.
      BufferedReader in = new
         BufferedReader (new InputStreamReader(System.in));
      String strCnn = "Provider=MSDataShape;" +
         "Data Provider='sqloledb';Data Source='MySqlServer';" +
         "Initial Catalog='Pubs';Integrated Security='SSPI';";

      try
      {
         cnConn1 = new Connection();
         cnConn1.open(strCnn);
         rstAuthors = new Recordset();
         rstAuthors.setStayInSync(true);
         rstAuthors.open("SHAPE  {select * from Authors} " +
                "APPEND ({select * from titleauthor}" +
                "RELATE au_id TO au_id) AS chapTitleAuthor",
               cnConn1,
               AdoEnums.CursorType.STATIC,
               AdoEnums.LockType.READONLY,
               AdoEnums.CommandType.TEXT);

         Variant varRstTitleAuthor = rstAuthors.getFields().
            getItem("chapTitleAuthor").getValue();
         rstTitleAuthor =new Recordset(varRstTitleAuthor.toObject());
         int intCount =0;
         while(!rstAuthors.getEOF())
         {
            System.out.println("\n" +
               rstAuthors.getField("au_fname").getString() + " " +
               rstAuthors.getField("au_lname").getString() + " " +
                rstAuthors.getField("state").getString() + " " +
                rstAuthors.getField("au_id").getString());
            while(!rstTitleAuthor.getEOF())
            {
               System.out.println(rstTitleAuthor.getField(0).
                  getString() + " " +
                  rstTitleAuthor.getField(1).getString() + " " +
                  rstTitleAuthor.getField(2).getString() + " " +
                  rstTitleAuthor.getField(3).getString());
               rstTitleAuthor.moveNext();
            }
            if(++intCount % 5 == 0)
            {
               System.out.println("\nPress <Enter> to continue..");
               in.readLine();
            }
            rstAuthors.moveNext();
         }

         System.out.println("\nPress <Enter> to continue..");
         in.readLine();
      }
      catch( AdoException ae )
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstAuthors != null)
         {
            PrintProviderError(rstAuthors.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstTitleAuthor != null)
            if (rstTitleAuthor.getState() == 1)
               rstTitleAuthor.close();
         if (rstAuthors != null)
            if (rstAuthors.getState() == 1)
               rstAuthors.close();
         if (cnConn1 != null)
            if (cnConn1.getState() == 1)
               cnConn1.close();
      }
   }

   // PrintProviderError Function
   static void PrintProviderError(Connection cnn1)
   {
      // Print Provider Errors from Connection Object.
      // ErrItem is an item object in the Connections Errors Collection.
      com.ms.wfc.data.Error               ErrItem = null;
      long                                 nCount = 0;
      int                                       i = 0;

      nCount = cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if ( nCount > 0)
      {
         // Collection ranges from 0 to nCount-1.
         for ( i=0;i<nCount; i++)
         {
            ErrItem = cnn1.getErrors().getItem(i);
            System.out.println("\t Error Number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription());
         }
      }
   }
   // PrintIOError Function
   static void PrintIOError(java.io.IOException je)
   {
      System.out.println("Error: \n");
      System.out.println("\t Source: " + je.getClass() + "\n");
      System.out.println("\t Description: "+ je.getMessage() + "\n");
   }
}
// EndStayInSyncJ

请参阅

Fields 集合 | Recordset 对象 | StayInSync 属性


Supports 方法范例 (VJ++)

本范例使用 Supports 方法来显示用不同游标类型打开的记录集所支持的选项。运行本范例需要 DisplaySupport 函数。

// BeginSupportsJ
import com.ms.wfc.data.*;
import java.io.*;

public class SupportsX
{
   // The main entry point of the application.

   public static void main (String[] args)
   {
      SupportsX();
      System.exit(0);
   }
   // SupportsX Function

   static void SupportsX()
   {
      // Define ADO Objects.
      Recordset rstTitles = null;

      // Declarations.
      int[] aintCursorType = new int[4];
      String strCnn;
      int intIndex;
      BufferedReader in =
         new BufferedReader(new InputStreamReader(System.in));

      try
      {
         // Open connections.
         strCnn = "Provider='sqloledb';Data Source='MySqlServer';"+
                "Initial Catalog='Pubs';Integrated Security='SSPI';";

         // Fill array with CursorType constants.
         aintCursorType[0] = AdoEnums.CursorType.FORWARDONLY;
         aintCursorType[1] = AdoEnums.CursorType.KEYSET;
         aintCursorType[2] = AdoEnums.CursorType.DYNAMIC;
         aintCursorType[3] = AdoEnums.CursorType.STATIC;

         // Open recordset using each CursorType and
         // Optimistic Locking.  Then call the DisplaySupport
         // procedure to display the supported options.
         for(intIndex = 0; intIndex < 4; intIndex++)
         {
            rstTitles = new Recordset();
            rstTitles.setCursorType(aintCursorType[intIndex]);
            rstTitles.setLockType(AdoEnums.LockType.OPTIMISTIC);
            rstTitles.open("Titles", strCnn, aintCursorType[intIndex],
               AdoEnums.LockType.OPTIMISTIC, AdoEnums.CommandType.TABLE);

            switch(aintCursorType[intIndex])
            {
            case AdoEnums.CursorType.FORWARDONLY:
               System.out.println("ForwardOnly cursor supports:");
               break;
            case AdoEnums.CursorType.KEYSET:
               System.out.println("Keyset cursor supports:");
               break;
            case AdoEnums.CursorType.DYNAMIC:
               System.out.println("Dynamic cursor supports:");
               break;
            case AdoEnums.CursorType.STATIC:
               System.out.println("Static cursor supports:");
               break;
            default:
               break;
            }
            DisplaySupport(rstTitles);
            System.out.println("Press <Enter> to continue..");
            in.readLine();
         }
      }
      catch(AdoException ae)
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstTitles!= null)
         {
            PrintProviderError(rstTitles.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }
      // System read requires this catch.
      catch( java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstTitles != null)
            if (rstTitles.getState() == 1)
               rstTitles.close();
      }
   }
   // DisplaySupport Function

   static void DisplaySupport( Recordset rstTemp )
   {
      long[] alngConstants = new long[11];
      boolean booSupports;
      int intIndex;
      try
      {
         // Fill array with cursor option constants.
         alngConstants[0]  = AdoEnums.CursorOption.ADDNEW;
         alngConstants[1]  = AdoEnums.CursorOption.APPROXPOSITION;
         alngConstants[2]  = AdoEnums.CursorOption.BOOKMARK;
         alngConstants[3]  = AdoEnums.CursorOption.DELETE;
         alngConstants[4]  = AdoEnums.CursorOption.FIND;
         alngConstants[5]  = AdoEnums.CursorOption.HOLDRECORDS;
         alngConstants[6]  = AdoEnums.CursorOption.MOVEPREVIOUS;
         alngConstants[7]  = AdoEnums.CursorOption.NOTIFY;
         alngConstants[8]  = AdoEnums.CursorOption.RESYNC;
         alngConstants[9]  = AdoEnums.CursorOption.UPDATE;
         alngConstants[10] = AdoEnums.CursorOption.UPDATEBATCH;

         for(intIndex = 0; intIndex <= 10; intIndex++)
         {
            booSupports = rstTemp.supports((int)alngConstants[intIndex]);
            if (booSupports)
            {
               switch((int)alngConstants[intIndex])
               {
               case AdoEnums.CursorOption.ADDNEW:
                     System.out.println("    AddNew");
                     break;
               case AdoEnums.CursorOption.APPROXPOSITION:
                     System.out.println(
                        "    AbsolutePosition and AbsolutePage");
                     break;
               case AdoEnums.CursorOption.BOOKMARK:
                     System.out.println("    Bookmark");
                     break;
               case AdoEnums.CursorOption.DELETE:
                     System.out.println("    Delete");
                     break;
               case AdoEnums.CursorOption.FIND:
                     System.out.println("    Find");
                     break;
               case AdoEnums.CursorOption.HOLDRECORDS:
                     System.out.println("    Holding Records");
                     break;
               case AdoEnums.CursorOption.MOVEPREVIOUS:
                     System.out.println("    MovePrevious and Move");
                     break;
               case AdoEnums.CursorOption.NOTIFY:
                     System.out.println("    Notifications");
                     break;
               case AdoEnums.CursorOption.RESYNC:
                     System.out.println("    Resyncing Data");
                     break;
               case AdoEnums.CursorOption.UPDATE:
                     System.out.println("    Update");
                     break;
               case AdoEnums.CursorOption.UPDATEBATCH:
                     System.out.println("    Batch Updating");
                     break;
               default:
                     break;
               }
            }
         }
      }
      catch(AdoException ae)
      {
         // Notify user of any errors that result from ADO.

         // As passing a Recordset, check for null pointer first.
         if (rstTemp!= null)
         {
            PrintProviderError(rstTemp.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }
   }

   // PrintProviderError Function
   static void PrintProviderError(Connection cnn1)
   {
      // Print Provider Errors from Connection Object.
      // ErrItem is an item object in the Connections Errors Collection.
      com.ms.wfc.data.Error               ErrItem = null;
      long                                 nCount = 0;
      int                                       i = 0;

      nCount = cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if ( nCount > 0)
      {
         // Collection ranges from 0 to nCount-1.
         for ( i=0;i<nCount; i++)
         {
            ErrItem = cnn1.getErrors().getItem(i);
            System.out.println("\t Error Number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription());
         }
      }
   }
   // PrintIOError Function
   static void PrintIOError(java.io.IOException je)
   {
      System.out.println("Error: \n");
      System.out.println("\t Source: " + je.getClass() + "\n");
      System.out.println("\t Description: "+ je.getMessage() + "\n");
   }
}
// EndSupportsJ

请参阅

Recordset 对象 | Supports 方法


Type 属性范例 (Field) (VJ++)

本范例通过显示与 Employees 表中所有 Field 对象的 Type 属性值对应的常量名，来演示 Type 属性。运行此过程需要 FieldType 函数。

// BeginFieldTypeJ
import java.io.*;
import com.ms.wfc.data.*;

public class TypeFieldX
{

   // The main entry point of the application.

   public static void main (String[] args)
   {
      TypeFieldX();
      System.exit(0);
   }

   // TypeFieldX Function
   static void TypeFieldX()
   {
      // Define ADO Objects.
      Recordset rstEmployees = null;
      Field fldLoop = null;

      // Declarations.
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"+
                "Initial Catalog='Pubs';Integrated Security='SSPI';";
      int intLoop;
      int intRecordCount = 0;
      BufferedReader in =
         new BufferedReader(new InputStreamReader(System.in));

      try
      {
         // Open the Recordset with data from Employees table.
         rstEmployees = new Recordset();
         rstEmployees.open("employee", strCnn,
            AdoEnums.CursorType.FORWARDONLY, AdoEnums.LockType.READONLY,
            AdoEnums.CommandType.TABLE);

         System.out.println("Fields in the Employees table:\n");

         // Enumerate fields collection of Employees table.
         for(intLoop = 0;intLoop <
            rstEmployees.getFields().getCount();intLoop++)
         {
            intRecordCount++;
            // Loop needed for display of records
            if((intRecordCount % 6)==0)
            {
               System.out.println("Press <Enter> to continue..");
               in.readLine();
            }

            fldLoop = rstEmployees.getFields().getItem(intLoop);
            System.out.println("  Name:" + fldLoop.getName() + "\n"+
               "  Type:" + FieldType(fldLoop.getType()) + "\n");

         }
         System.out.println("Press <Enter> to continue");
         in.readLine();
      }
      catch(AdoException ae)
      {
         // Notify the user of any errors that result from ADO.

         // As passing a Recordset, check for the null pointer first.
         if(rstEmployees != null)
         {
            PrintProviderError(rstEmployees.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }
      // System read requires this catch.
      catch(java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstEmployees != null)
            if (rstEmployees.getState() == 1)
               rstEmployees.close();
      }
   }
   // FieldType Function
   static String FieldType( int intType )
   {
      String strLoop = null;

         switch(intType)
         {
         case AdoEnums.DataType.CHAR:
            strLoop = "adChar";
            break;
         case AdoEnums.DataType.VARCHAR:
            strLoop ="adVarChar";
            break;
         case AdoEnums.DataType.SMALLINT:
            strLoop = "adSmallInt";
            break;
         case AdoEnums.DataType.UNSIGNEDTINYINT:
            strLoop = "adUnsignedTinyInt" ;
            break;
         case AdoEnums.DataType.DBTIMESTAMP:
            strLoop = "adDBTimeStamp";
            break;
         default:
            break;
         }

      return strLoop;
   }

   // PrintProviderError Function
   static void PrintProviderError(Connection cnn1)
   {
      // Print Provider Errors from Connection Object.
      // ErrItem is an item object in the Connections Errors Collection.
      com.ms.wfc.data.Error               ErrItem = null;
      long                                 nCount = 0;
      int                                       i = 0;

      nCount = cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if ( nCount > 0)
      {
         // Collection ranges from 0 to nCount-1.
         for ( i=0;i<nCount; i++)
         {
            ErrItem = cnn1.getErrors().getItem(i);
            System.out.println("\t Error Number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription());
         }
      }
   }
   // PrintIOError Function
   static void PrintIOError(java.io.IOException je)
   {
      System.out.println("Error: \n");
      System.out.println("\t Source: " + je.getClass() + "\n");
      System.out.println("\t Description: "+ je.getMessage() + "\n");
   }
}
// EndFieldTypeJ

请参阅

Field 对象 | Type 属性


Type 属性范例 (Property) (VJ++)

本范例演示 Type 属性。这是列出集合（如 Properties、Fields 等等）的名称和类型的实用程序模型。

不需要打开 Recordset 即可访问其 Properties 集合；在 Recordset 对象实例化时它们即已存在。但是，将 CursorLocation 属性设置为 adUseClient 会向 Recordset 对象的 Properties 集合添加若干个动态属性，这将给范例增添一些趣味。为了达到说明的效果，在此使用 Item 属性来访问每个 Property 对象。

// BegintTypePropertyJ
import com.ms.wfc.data.*;
import java.io.* ;

public class TypePropertyX
{
    // The main entry point for the application.

    public static void main (String[] args)
    {
        TypePropertyX();
        System.exit(0);
    }

    // TypePropertyX  function
    static void TypePropertyX()
    {
        // Define ADO Objects.
        Recordset rst = null;
        AdoProperty prop = null;

        // Declarations.
        BufferedReader in =
            new BufferedReader (new InputStreamReader(System.in));
        String strCnn = "DSN='Pubs';Provider='MSDASQL';Integrated Security='SSPI';";
        String strMsg;
        int intIndex;
        int intDisplaysize = 15;

        try
        {
            rst = new Recordset();
            rst.setCursorLocation(AdoEnums.CursorLocation.CLIENT);
            for(intIndex = 0;
                intIndex <= rst.getProperties().getCount() - 1;intIndex++)
            {
                prop = rst.getProperties().getItem(intIndex);
                switch(prop.getType())
                {
                    case AdoEnums.DataType.BIGINT :
                        strMsg = "adBigInt";
                        break;
                    case AdoEnums.DataType.BINARY :
                        strMsg = "adBinary";
                        break;
                    case AdoEnums.DataType.BOOLEAN :
                        strMsg = "adBoolean";
                        break;
                    case AdoEnums.DataType.BSTR :
                        strMsg = "adBSTR";
                        break;
                    case AdoEnums.DataType.CHAPTER :
                        strMsg = "adChapter";
                        break;
                    case AdoEnums.DataType.CHAR :
                        strMsg = "adChar";
                        break;
                    case AdoEnums.DataType.CURRENCY :
                        strMsg = "adCurrency";
                        break;
                    case AdoEnums.DataType.DATE :
                        strMsg = "adDate";
                        break;
                    case AdoEnums.DataType.DBDATE :
                        strMsg = "adDBDate";
                        break;
                    case AdoEnums.DataType.DBTIME :
                        strMsg = "adDBTime";
                        break;
                    case AdoEnums.DataType.DBTIMESTAMP :
                        strMsg = "adDBTimeStamp";
                        break;
                    case AdoEnums.DataType.DECIMAL :
                        strMsg = "adDecimal";
                        break;
                    case AdoEnums.DataType.DOUBLE :
                        strMsg = "adDouble";
                        break;
                    case AdoEnums.DataType.EMPTY :
                        strMsg = "adEmpty";
                        break;
                    case AdoEnums.DataType.ERROR :
                        strMsg = "adError";
                        break;
                    case AdoEnums.DataType.FILETIME :
                        strMsg = "adFileTime";
                        break;
                    case AdoEnums.DataType.GUID :
                        strMsg = "adGUID";
                        break;
                    case AdoEnums.DataType.IDISPATCH :
                        strMsg = "adIDispatch";
                        break;
                    case AdoEnums.DataType.INTEGER :
                        strMsg = "adInteger";
                        break;
                    case AdoEnums.DataType.IUNKNOWN :
                        strMsg = "adIUnknown";
                        break;
                    case AdoEnums.DataType.LONGVARBINARY :
                        strMsg = "adLongVarBinary";
                        break;
                    case AdoEnums.DataType.LONGVARCHAR :
                        strMsg = "adLongVarChar";
                        break;
                    case AdoEnums.DataType.LONGVARWCHAR :
                        strMsg = "adLongVarWChar";
                        break;
                    case AdoEnums.DataType.NUMERIC :
                        strMsg = "adNumeric";
                        break;
                    case AdoEnums.DataType.PROPVARIANT :
                        strMsg = "adPropVariant";
                        break;
                    case AdoEnums.DataType.SINGLE :
                        strMsg = "adSingle";
                        break;
                    case AdoEnums.DataType.SMALLINT :
                        strMsg = "adSmallInt";
                        break;
                    case AdoEnums.DataType.TINYINT :
                        strMsg = "adTinyInt";
                        break;
                    case AdoEnums.DataType.UNSIGNEDBIGINT :
                        strMsg = "adUnsignedBigInt";
                        break;
                    case AdoEnums.DataType.UNSIGNEDINT :
                        strMsg = "adUnsignedInt";
                        break;
                    case AdoEnums.DataType.UNSIGNEDSMALLINT :
                        strMsg = "adUnsignedSmallInt";
                        break;
                    case AdoEnums.DataType.UNSIGNEDTINYINT :
                        strMsg = "adUnsignedTinyInt";
                        break;
                    case AdoEnums.DataType.USERDEFINED :
                        strMsg = "adUserDefined";
                        break;
                    case AdoEnums.DataType.VARBINARY :
                        strMsg = "adVarBinary";
                        break;
                    case AdoEnums.DataType.VARCHAR :
                        strMsg = "adVarChar";
                        break;
                    case AdoEnums.DataType.VARIANT :
                        strMsg = "adVariant";
                        break;
                    case AdoEnums.DataType.VARNUMERIC :
                        strMsg = "adVarNumeric";
                        break;
                    case AdoEnums.DataType.VARWCHAR :
                        strMsg = "adVarWChar";
                        break;
                    case AdoEnums.DataType.WCHAR :
                        strMsg = "adWChar";
                        break;
                    default:
                        strMsg = "*UNKNOWN*";
                        break;
                }
                System.out.println("Property " +
                                   Integer.toString(intIndex) +
                                   " : " +
                                   prop.getName() +
                                   ", Type = " +
                                   strMsg);
                if(intIndex % intDisplaysize == 0 && intIndex != 0)
                {
                    System.out.println("\nPress <Enter> to continue..");
                    in.readLine();
                }
            }

            System.out.println("\nPress <Enter> to continue..");
            in.readLine();
        }
        catch( AdoException ae )
        {
            // Notify user of any errors that result from ADO.

            // As passing a Recordset, check for null pointer first.
            if (rst != null)
            {
                PrintProviderError(rst.getActiveConnection());
            }
            else
            {
                System.out.println("Exception: " + ae.getMessage());
            }
        }

        // System read requires this catch.
        catch( java.io.IOException je)
        {
            PrintIOError(je);
        }

      finally
      {
         // Cleanup objects before exit.
         if (rst != null)
            if (rst.getState() == 1)
               rst.close();
      }
    }

    // PrintProviderError Function
    static void PrintProviderError(Connection cnn1)
    {
        // Print Provider Errors from Connection Object.
        // ErrItem is an item object in the Connections Errors Collection.
        com.ms.wfc.data.Error               ErrItem = null;
        long                                 nCount = 0;
        int                                       i = 0;

        nCount = cnn1.getErrors().getCount();

        // If there are any errors in the collection, print them.
        if ( nCount > 0)
        {
            // Collection ranges from 0 to nCount-1.
            for ( i=0;i<nCount; i++)
            {
                ErrItem = cnn1.getErrors().getItem(i);
                System.out.println("\t Error Number: " + ErrItem.getNumber()
                    + "\t" + ErrItem.getDescription());
            }
        }
    }
    // PrintIOError Function
    static void PrintIOError(java.io.IOException je)
    {
        System.out.println("Error: \n");
        System.out.println("\t Source: " + je.getClass() + "\n");
        System.out.println("\t Description: "+ je.getMessage() + "\n");
    }
}
// EndTypePropertyJ

请参阅

Property 对象 | Type 属性


Update 和 CancelUpdate 方法范例 (VJ++)

本范例演示 Update 和 CancelUpdate 方法。

// BeginUpdateJ
import java.io.*;
import com.ms.wfc.data.*;

public class UpdateX
{
   // The main entry point of the application.

   public static void main (String[] args)
   {
      UpdateX();
      UpdateX2();
      System.exit(0);
   }
   // UpdateX Function

   static void UpdateX()
   {
      // Define ADO objects.
      Recordset rstEmployees = null;

      // Declarations.
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"+
                  "Initial Catalog='Pubs';Integrated Security='SSPI';";
      String strOldFirst;
      String strOldLast;
      String strMessage;
      BufferedReader in =
         new BufferedReader(new InputStreamReader(System.in));

      try
      {
         // Open Recordset with names from Employees table.
         rstEmployees = new Recordset();
         rstEmployees.setCursorType(AdoEnums.CursorType.KEYSET);
         rstEmployees.setLockType(AdoEnums.LockType.OPTIMISTIC);
         rstEmployees.open("SELECT fname,lname FROM Employees " +
            "ORDER BY lname", strCnn, AdoEnums.CursorType.KEYSET,
            AdoEnums.LockType.OPTIMISTIC, AdoEnums.CommandType.TEXT);

         // Store Original data.
         strOldFirst = rstEmployees.getField("fname").getString();
         strOldLast = rstEmployees.getField("lname").getString();

         // Change data in edit buffer.
         rstEmployees.getField("fname").setString("Linda");
         rstEmployees.getField("lname").setString("Kobara");

         // Show contents of buffer and get user input.
         strMessage = "Edit in Progress :\n" +
            "\tOriginal Data = " + strOldFirst + "  " + strOldLast +
            "\n\tData in Buffer = " +
            rstEmployees.getField("fname").getString() + " " +
            rstEmployees.getField("lname").getString() + "\n\n" +
             "Use Update to replace the original data with " +
            "the buffered data in the Recordset?Enter (Y/N)";

         System.out.println(strMessage);
         if(in.readLine().trim().equalsIgnoreCase("Y"))
            rstEmployees.update();
         else
            rstEmployees.cancelUpdate();

         // Show the resulting data.
         System.out.println("Data in Recordset = " +
            rstEmployees.getField("fname").getString() +
            "  " + rstEmployees.getField("lname").getString()+ "\n");

         // Restore original data because this is a demonstration.
         if(!(strOldFirst.equals(
            rstEmployees.getField("fname").getString()) &&
            strOldLast.equals(
            rstEmployees.getField("lname").getString())))
         {
            rstEmployees.getField("fname").setString(strOldFirst);
            rstEmployees.getField("lname").setString(strOldLast);
            rstEmployees.update();
         }
         // Cleanup Objects before exit.
         rstEmployees.close();

         System.out.println("Press <Enter> to continue..");
         in.readLine();

      }
      catch(AdoException ae)
      {
         // Notify the user of any errors that result from ADO.

         // As passing a recordset, check for null pointer first.
         if(rstEmployees != null)
         {
            PrintProviderError(rstEmployees.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: "+ ae.getMessage());
         }
      }
      // System read requires this catch.
      catch(java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstEmployees != null)
            if (rstEmployees.getState() == 1)
               rstEmployees.close();
      }
   }
   // UpdateX2 Function

   static void UpdateX2()
   {
      // This example demonstrates the Update method in conjunction
      // with the AddNew method.

      // Define ADO Objects.
      Connection cnn1 = null;
      Recordset rstEmployees = null;

      // Declarations.
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"+
                  "Initial Catalog='Pubs';Integrated Security='SSPI';";
      String strEmpID;
      String strOldFirst;
      String strOldLast;
      String strMessage;
      BufferedReader in =
         new BufferedReader(new InputStreamReader(System.in));

      try
      {
         // Open a connection.
         cnn1 = new Connection();
         cnn1.open(strCnn);

         // Open Recordset with data from Employees table.
         rstEmployees = new Recordset();
         rstEmployees.setCursorType(AdoEnums.CursorType.KEYSET);
         rstEmployees.setLockType(AdoEnums.LockType.OPTIMISTIC);
         rstEmployees.open("employee", cnn1, AdoEnums.CursorType.KEYSET,
            AdoEnums.LockType.OPTIMISTIC, AdoEnums.CommandType.TABLE);

         rstEmployees.addNew();
         strEmpID="B-S55555M";
         rstEmployees.getField("emp_id").setString(strEmpID);
         rstEmployees.getField("fname").setString("Bill");
         rstEmployees.getField("lname").setString("Sornsin");

         // Show contents of buffer and get user input.
         strMessage = "AddNew in progress : " + "\n" +
            "\tData in Buffer = " +
            rstEmployees.getField("emp_id").getString() +
            "  " + rstEmployees.getField("fname").getString() + "  " +
            rstEmployees.getField("lname").getString()+ "\n\n" +
            "Use Update to save buffer to recordset?Enter (Y/N)";
         System.out.println(strMessage);
         if(in.readLine().trim().equalsIgnoreCase("Y"))
         {
            rstEmployees.update();
            // Go to the new record and show the resulting data.
            System.out.println("Data in recordset = " +
               rstEmployees.getField("emp_id").getString()+
               "  " + rstEmployees.getField("fname").getString() +
               "  " + rstEmployees.getField("lname").getString() + "\n");
         }
         else
         {
            rstEmployees.cancelUpdate();
            System.out.println("No new Record added.\n");
         }
         // Delete new data because this is a demonstration.
         cnn1.execute(
            "DELETE FROM employee WHERE emp_id='" + strEmpID +"'");

         // Cleanup Objects before exit
         rstEmployees.close();

         System.out.println("Press <Enter> to continue..");
         in.readLine();
      }
      catch(AdoException ae)
      {
         // Notify the user of any errors that result from ADO.

         // As passing a recordset, check for null pointer first.
         if(rstEmployees != null)
         {
            PrintProviderError(rstEmployees.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: "+ ae.getMessage());
         }
      }
      // System read requires this catch.
      catch(java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstEmployees != null)
            if (rstEmployees.getState() == 1)
               rstEmployees.close();
      }
   }
   // PrintProviderError Function
   static void PrintProviderError(Connection cnn1)
   {
      // Print Provider Errors from Connection Object.
      // ErrItem is an item object in the Connections Errors Collection.
      com.ms.wfc.data.Error               ErrItem = null;
      long                                 nCount = 0;
      int                                       i = 0;

      nCount = cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if ( nCount > 0)
      {
         // Collection ranges from 0 to nCount-1.
         for ( i=0;i<nCount; i++)
         {
            ErrItem = cnn1.getErrors().getItem(i);
            System.out.println("\t Error Number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription());
         }
      }
   }
   // PrintIOError Function
   static void PrintIOError(java.io.IOException je)
   {
      System.out.println("Error: \n");
      System.out.println("\t Source: " + je.getClass() + "\n");
      System.out.println("\t Description: "+ je.getMessage() + "\n");
   }
}
// EndUpdateJ

请参阅

CancelUpdate 方法 | Update 方法


UpdateBatch 和 CancelBatch 方法范例 (VJ++)

本范例演示 UpdateBatch 和 CancelBatch 方法。

// BeginUpdateBatchJ
import java.io.*;
import com.ms.wfc.data.*;

public class UpdateBatchX
{
   // The main entry point of the application.
   public static void main (String[] args)
   {
      UpdateBatchX();
      System.exit(0);
   }
   // UpdateBatchX Function

   static void UpdateBatchX()
   {
      // Define ADO Objects.
      Recordset rstTitles = null;

      // Declarations.
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';"+
                  "Initial Catalog='Pubs';Integrated Security='SSPI';";
      String strTitle;
      String strMessage;
      BufferedReader in =
         new BufferedReader(new InputStreamReader(System.in));

      try
      {
         rstTitles = new Recordset();
         rstTitles.setCursorType(AdoEnums.CursorType.KEYSET);
         rstTitles.setLockType(AdoEnums.LockType.BATCHOPTIMISTIC);
         rstTitles.open("Titles", strCnn, AdoEnums.CursorType.KEYSET,
            AdoEnums.LockType.BATCHOPTIMISTIC,
            AdoEnums.CommandType.TABLE);

         rstTitles.moveFirst();

         // Loop through recordset and ask user if she wants
         // to change the type for the specified table.
         while(!rstTitles.getEOF())
         {
            if(rstTitles.getField("Type").getString().
               trim().equalsIgnoreCase("psychology"))
            {
               strTitle = rstTitles.getField("Title").getString();
               strMessage = "Title: "+ strTitle + "\n" +
                  "Change type to self_help?Enter (Y/N)";
               System.out.println(strMessage);
               if(in.readLine().trim().equalsIgnoreCase("Y"))
                  rstTitles.getField("type").setString("self_help");
            }
            rstTitles.moveNext();
         }
         // Ask the user if she wants to commit to all the
         // changes made above.
         System.out.println("Save all changes?Enter (Y/N)");
         if(in.readLine().trim().equalsIgnoreCase("Y"))
            rstTitles.updateBatch();
         else
            rstTitles.cancelBatch();

         // Print current data in recordset.
         rstTitles.requery();
         rstTitles.moveFirst();
         while(!rstTitles.getEOF())
         {
         System.out.println(rstTitles.getField("title").getString() +
            " - " + rstTitles.getField("type").getString());
         rstTitles.moveNext();
         }

         // Restore original values because this is a demonstration.
         rstTitles.moveFirst();
         while(!rstTitles.getEOF())
         {
            if(rstTitles.getField("type").getString().
               trim().equalsIgnoreCase("self_help"))
               rstTitles.getField("type").setString("psychology");
            rstTitles.moveNext();
         }
         rstTitles.updateBatch();

         System.out.println("Press <Enter> to continue..");
         in.readLine();

      }
      catch(AdoException ae)
      {
         // Notify the user of any errors that result from ADO.

         // As passing a recordset, check for null pointer first.
         if(rstTitles != null)
         {
            PrintProviderError(rstTitles.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }
      // System read requires this catch.
      catch(java.io.IOException je)
      {
         PrintIOError(je);
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstTitles != null)
            if (rstTitles.getState() == 1)
               rstTitles.close();
      }
   }

   // PrintProviderError Function
   static void PrintProviderError(Connection cnn1)
   {
      // Print Provider Errors from Connection Object.
      // ErrItem is an item object in the Connections Errors Collection.
      com.ms.wfc.data.Error               ErrItem = null;
      long                                 nCount = 0;
      int                                       i = 0;

      nCount = cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if ( nCount > 0)
      {
         // Collection ranges from 0 to nCount-1.
         for ( i=0;i<nCount; i++)
         {
            ErrItem = cnn1.getErrors().getItem(i);
            System.out.println("\t Error Number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription());
         }
      }
   }
   // PrintIOError Function
   static void PrintIOError(java.io.IOException je)
   {
      System.out.println("Error: \n");
      System.out.println("\t Source: " + je.getClass() + "\n");
      System.out.println("\t Description: "+ je.getMessage() + "\n");
   }
}
// EndUpdateBatchJ

请参阅

CancelBatch 方法 | UpdateBatch 方法


Value 属性范例 (VJ++)

本范例通过显示 Employees 表的字段和属性值来演示 Field 和 Property 对象的 Value 属性。

// BeginValueJ
import java.io.*;
import com.ms.wfc.data.*;
import com.ms.com.*;

public class ValueX
{
   // Main Function
   public static void main (String[] args)
   {
      ValueX();
      System.exit(0);
   }
   static void ValueX()
   {
      // Define ADO Objects.
      Recordset rstEmployees = null;
      Field    fldLoop     = null;
      AdoProperty  prpLoop   = null;

      // Declarations.
      String strCnn = "Provider='sqloledb';Data Source='MySqlServer';" +
         "Initial Catalog='Pubs';Integrated Security='SSPI';";
      int intLoop;
      BufferedReader in = new
         BufferedReader(new InputStreamReader(System.in));
      Variant varPropertyValue;
      String strMessage;

      try
      {
         // Open a Recordset with data from Employees table.
         rstEmployees = new Recordset();
         rstEmployees.open("employee", strCnn,
            AdoEnums.CursorType.FORWARDONLY, AdoEnums.LockType.READONLY,
            AdoEnums.CommandType.TABLE);

         System.out.println("Field values in rstEmployees\n");

         // Enumerate the Fields collection of the Employees
         // table.
         for(intLoop = 0;
            intLoop<rstEmployees.getFields().getCount();intLoop++)
         {
            fldLoop = rstEmployees.getFields().getItem(intLoop);
            // Because Value is the default property of a
            // Field object, the use of the actual keyword
            // here is optional.
            System.out.println("\t" + fldLoop.getName() + " = " +
               fldLoop.getValue());
         }
         System.out.println("\nPress <Enter> to continue..");
         in.readLine();
         System.out.println("Property values in rstEmployees\n");

         // Enumerate the Properties collection of the
         // Recordset object.
         int intCount = 0;
         for(intLoop = 0;
            intLoop<rstEmployees.getProperties().getCount();intLoop++)
         {
            prpLoop = rstEmployees.getProperties().getItem(intLoop);
            // Because Value is the default property of a
            // Field object, the use of the actual keyword
            // here is optional.
            strMessage = "\t" + prpLoop.getName() + " =  ";
            varPropertyValue = prpLoop.getValue();
            short vttype =varPropertyValue.getvt();
            switch (vttype)
            {
            case Variant.VariantBoolean :
               {
                  if (varPropertyValue.getBoolean())
                     strMessage +="True";
                  else
                     strMessage +="False";
               }
               break;
            case Variant.VariantInt :
               strMessage += varPropertyValue.getInt();
               break;
            default :
               break;
            }
            System.out.println(strMessage);
            intCount++;
            // Loop used to display records
            if (intCount % 15 == 0)
            {
               System.out.println("\nPress <Enter> to continue..");
               in.readLine();
               intCount = 0;
            }

         }
         // Cleanup objects before exit.
         rstEmployees.close();
         System.out.println("\nPress <Enter> to continue..");
         in.readLine();
      }
      // System read requires this catch.
      catch(java.io.IOException je)
      {
         PrintIOError(je);
      }
      catch(AdoException ae)
      {
         // Notify the user of any errors that result from ADO.

         // As passing a recordset, check for null pointer first.
         if(rstEmployees != null)
         {
            PrintProviderError(rstEmployees.getActiveConnection());
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }

      finally
      {
         // Cleanup objects before exit.
         if (rstEmployees != null)
            if (rstEmployees.getState() == 1)
               rstEmployees.close();
      }

   }
   // PrintProviderError Function
   static void PrintProviderError(Connection cnn1)
   {
      // Print Provider Errors from Connection Object.
      // ErrItem is an item object in the Connections Errors Collection.
      com.ms.wfc.data.Error               ErrItem = null;
      long                                 nCount = 0;
      int                                       i = 0;

      nCount = cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if ( nCount > 0)
      {
         // Collection ranges from 0 to nCount-1.
         for ( i=0;i<nCount; i++)
         {
            ErrItem = cnn1.getErrors().getItem(i);
            System.out.println("\t Error Number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription());
         }
      }
   }
   // PrintIOError Function
   static void PrintIOError(java.io.IOException je)
   {
      System.out.println("Error: \n");
      System.out.println("\t Source: " + je.getClass() + "\n");
      System.out.println("\t Description: "+ je.getMessage() + "\n");
   }
}
// EndValueJ

请参阅

Field 对象 | Property 对象 | Value 属性


Version 属性范例 (VJ++)

本范例使用 Connection 对象的 Version 属性来显示当前 ADO 版本。范例中还使用若干动态属性来显示：

  • 当前 DBMS 名称和版本。
  • OLE DB 版本。
  • 提供者名称和版本。
  • ODBC 版本。
  • ODBC 驱动程序名称和版本。
// BeginVersionJ
import com.ms.wfc.data.*;
import java.io.*;

public class VersionX
{
   // The main entry point of the application.
   public static void main (String[] args)
   {
      VersionX();
      System.exit(0);
   }
   // VersionX Function
   static void VersionX()
   {
      // Define ADO Objects.
      Connection cnn1 = null;

      // Declarations.
      String strCnn = "Driver={SQL Server};Server='MySqlServer';" +
                  "User ID='MyUserID';Password='MyPassword';database='Pubs';";
      String strVersionInfo;
      BufferedReader in = new
         BufferedReader(new InputStreamReader(System.in));
      try
      {
         // Open connection.
         cnn1 = new Connection();
         cnn1.open(strCnn);

         strVersionInfo = "\tADO Version:\t\t" +
            cnn1.getVersion().toString()+"\n"+
            "\tDBMS Name:\t\t" +
            cnn1.getProperties().getItem("DBMS Name").getString() +"\n"+
            "\tDBMS Version:\t\t"+
            cnn1.getProperties().getItem("DBMS Version").getString() +
            "\n" + "\tOLE DB Version:\t\t" +
            cnn1.getProperties().getItem("OLE DB Version").getString()+
            "\n" + "\tProvider Name:\t\t" +
            cnn1.getProperties().getItem("Provider Name").getString() +
            "\n" + "\tProvider Version:\t" +
            cnn1.getProperties().getItem("Provider Version").
            getString() + "\n" + "\tDriver Name:\t\t" +
            cnn1.getProperties().getItem("Driver Name").getString() +
            "\n" + "\tDriver Version:\t\t" +
            cnn1.getProperties().getItem("Driver Version").getString()+
            "\n" + "\tDriver ODBC Version:\t" +
            cnn1.getProperties().getItem(
            "Driver ODBC Version").getString()+ "\n";
         System.out.println("\n\n" + strVersionInfo);

         System.out.println("Press <Enter> to continue..");
         in.readLine();
      }
      // System read requires this catch.
      catch(java.io.IOException je)
      {
         PrintIOError(je);
      }
      catch(AdoException ae)
      {
         // Notify the user of any errors that result from ADO.

         // As passing a recordset, check for null pointer first.
         if(cnn1!= null)
         {
            PrintProviderError(cnn1);
         }
         else
         {
            System.out.println("Exception: " + ae.getMessage());
         }
      }
      finally
      {
         // Cleanup objects before exit.
         if (cnn1 != null)
            if (cnn1.getState() == 1)
               cnn1.close();
      }

   }
   // PrintProviderError Function
   static void PrintProviderError(Connection cnn1)
   {
      // Print Provider Errors from Connection Object.
      // ErrItem is an item object in the Connections Errors Collection.
      com.ms.wfc.data.Error               ErrItem = null;
      long                                 nCount = 0;
      int                                       i = 0;

      nCount = cnn1.getErrors().getCount();

      // If there are any errors in the collection, print them.
      if ( nCount > 0)
      {
         // Collection ranges from 0 to nCount-1.
         for ( i=0;i<nCount; i++)
         {
            ErrItem = cnn1.getErrors().getItem(i);
            System.out.println("\t Error Number: " + ErrItem.getNumber()
               + "\t" + ErrItem.getDescription());
         }
      }
   }
   // PrintIOError Function
   static void PrintIOError(java.io.IOException je)
   {
      System.out.println("Error: \n");
      System.out.println("\t Source: " + je.getClass() + "\n");
      System.out.println("\t Description: "+ je.getMessage() + "\n");
   }
}
// EndVersionJ

请参阅

Connection 对象 | Version 属性


Microsoft JScript 中的 ADO 代码范例

通过下列代码范例来学习用 JScript 编程时如何使用 ADO 方法、属性和事件。

注意 请将整个代码范例（从开始到结束）粘贴到代码编辑器中。如果只使用部分范例或者丢失了段落格式，范例可能无法正确运行。

方法

  • AddNew 方法范例
  • Append 和 CreateParameter 方法范例
  • Execute、Requery 和 Clear 方法范例
  • Find 方法范例
  • GetRows 方法范例

Properties

  • AbsolutePage、PageCount 和 PageSize 属性范例
  • AbsolutePosition 和 CursorLocation 属性范例
  • ActiveCommand 属性范例
  • ActiveConnection、CommandText、CommandTimeout、CommandType、Size 和 Direction 属性范例
  • ActualSize 和 DefinedSize 属性范例
  • CacheSize 属性范例
  • Filter 和 RecordCount 属性范例

请参阅

Microsoft Visual Basic 中的 ADO 代码范例 | Microsoft Visual Basic Scripting Edition 中的 ADO 代码范例 | Microsoft Visual C++ 中的 ADO 代码范例 | Microsoft Visual J++ 中的 ADO 代码范例


AbsolutePage、PageCount 和 PageSize 属性范例 (JScript)

本范例演示了 AbsolutePage、PageCount 和 PageSize 属性。请将下列代码剪切并粘贴到记事本或其他文本编辑器，并将其保存为 AbsolutePageJS.asp。

<!-- BeginAbsolutePageJS -->
<%@LANGUAGE="JScript" %>
<%// use this meta tag instead of adojavas.inc%>
<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<html>

<head>
<title>AbsolutePage, PageSize, and PageSize Properties (JScript)</title>
<style>
<!--
BODY {
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   BACKGROUND-COLOR:white;
   COLOR:black;
    }
.thead2 {
   background-color: #800000;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
   color: white;
   }
.tbody {
   text-align: center;
   background-color: #f7efde;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
    }
-->
</style>
</head>

<body bgcolor="White">
<h1>AbsolutePage, PageSize, and PageSize Properties (JScript)</h1>
<%
    // connection and recordset variables
    var Cnxn = Server.CreateObject("ADODB.Connection")
    var strCnxn = "Provider='sqloledb';Data Source=" + Request.ServerVariables("SERVER_NAME") + ";" +
            "Initial Catalog='Northwind';Integrated Security='SSPI';";
    var rsEmployee = Server.CreateObject("ADODB.Recordset");
    // display variables
    var strMessage, iRecord, iPageCount;

    try
    {
        // open connection
        Cnxn.Open(strCnxn);

        // Open a recordset on the Employee table using
        // a client-side cursor to enable AbsolutePage property.
        rsEmployee.CursorLocation = adUseClient;
        rsEmployee.Open("employees", strCnxn, adOpenStatic, adLockOptimistic, adCmdTable);

        // Set PageSize to five to display names and hire dates of five employees at a time
        rsEmployee.PageSize = 5;
        iPageCount = rsEmployee.PageCount;

        // Write header information to the document
        Response.Write('<p align="center">There are ' + iPageCount);
        Response.Write(" pages, each containing ");
        Response.Write(rsEmployee.PageSize + " or fewer records.</p>");
        Response.Write('<table border="0" align="center">');
        Response.Write('<tr class="thead2">');
        Response.Write("<th>Page</th><th>Name</th><th>Hire Date</th></tr>");

        for (var i=1; i<=iPageCount; i++)
        {
            rsEmployee.AbsolutePage = i;

            for (iRecord = 1; iRecord <= rsEmployee.PageSize; iRecord++)
            {
                strMessage = "";

                    // Start a new table row.
                    strMessage = '<tr class="tbody">';

                    // First column in row contains page number on
                    // first record of each page. Otherwise, the column
                    // contains a non-breaking space.
                    if (iRecord == 1)
                        strMessage += "<td>Page " + i + " of " + rsEmployee.PageCount + "</td>"
                    else
                        strMessage += "<td>&nbsp;</td>";

                    // First and last name are in first column.
                    strMessage += "<TD>" + rsEmployee.Fields("FirstName") + " ";
                    strMessage += rsEmployee.Fields("LastName") + " " + "</td>";

                    // Hire date in second column.
                    strMessage += "<td>" + rsEmployee.Fields("HireDate") + "</td>";

                    // End the row.
                    strMessage += "</tr>";

                    // Write line to document.
                    Response.Write(strMessage);

                    // Get next record.
                    rsEmployee.MoveNext;

                    if (rsEmployee.EOF)
                        break;
            }
        }

        // Finish writing table.
        Response.Write("</table>");
    }
    catch (e)
    {
        Response.Write(e.message);
    }
    finally
    {
        // 'clean up
        if (rsEmployee.State == adStateOpen)
            rsEmployee.Close;
        if (Cnxn.State == adStateOpen)
            Cnxn.Close;
        rsEmployee = null;
        Cnxn = null;
    }
%>

</body>

</html>
<!-- EndAbsolutePageJS -->

请参阅

AbsolutePage 属性 | PageCount 属性 | PageSize 属性 | Recordset 对象


AbsolutePosition 和 CursorLocation 属性范例 (JScript)

本范例演示 AbsolutePosition 属性如何跟踪循环的进度。该循环用于枚举 Recordset 中的所有记录。范例中使用了 CursorLocation 属性，通过将游标设置为客户游标来启用 AbsolutePosition 属性。请将下列代码剪切并粘贴到“记事本”或其他文本编辑器，然后将它另存为 AbsolutePositionJS.asp。

<!-- BeginAbsolutePositionJS -->
<%@LANGUAGE="JScript" %>
<%// use this meta tag instead of adojavas.inc%>
<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<html>

<head>
<title>AbsolutePosition and CursorLocation Properties Example (JScript)</title>
<style>
<!--
BODY {
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   BACKGROUND-COLOR:white;
   COLOR:black;
    }
.thead2 {
   background-color: #800000;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
   color: white;
   }
.tbody {
   text-align: center;
   background-color: #f7efde;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
    }
-->
</style>
</head>

<body>
<h1>AbsolutePosition and CursorLocation Properties Example (JScript)</h1>
<%
    // connection and recordset variables
    var strCnxn = "Provider='sqloledb';Data Source=" + Request.ServerVariables("SERVER_NAME") + ";" +
            "Initial Catalog='Northwind';Integrated Security='SSPI';";
    var rsEmployee = Server.CreateObject("ADODB.Recordset");
        // display string
    var strMessage;

    try
    {
        // Open a recordset on the Employee table using
        // a client-side cursor to enable AbsolutePosition property.
        rsEmployee.CursorLocation = adUseClient;
        rsEmployee.Open("employees", strCnxn, adOpenStatic, adLockOptimistic, adCmdTable);

        // Write beginning of table to the document.
        Response.Write('<table border="0" align="center">');
        Response.Write('<tr class="thead2">');
        Response.Write("<th>AbsolutePosition</th><th>Name</th><th>Hire Date</th></tr>");

        while (!rsEmployee.EOF)
        {
            strMessage = "";

            // Start a new table row.
            strMessage = '<tr class="tbody">';

            // First column in row contains AbsolutePosition value.
            strMessage += "<td>" + rsEmployee.AbsolutePosition + " of " + rsEmployee.RecordCount + "</td>"

            // First and last name are in first column.
            strMessage += "<td>" + rsEmployee.Fields("FirstName") + " ";
            strMessage += rsEmployee.Fields("LastName") + " " + "</td>";

            // Hire date in second column.
            strMessage += "<td>" + rsEmployee.Fields("HireDate") + "</td>";

            // End the row.
            strMessage += "</tr>";

            // Write line to document.
            Response.Write(strMessage);

            // Get next record.
            rsEmployee.MoveNext;
        }

        // Finish writing document.
        Response.Write("</table>");
    }
    catch (e)
    {
        Response.Write(e.message);
    }
    finally
    {
        // 'clean up
        if (rsEmployee.State == adStateOpen)
            rsEmployee.Close;
        rsEmployee = null;
    }
%>

</html>
<!-- EndAbsolutePositionJS -->

请参阅

AbsolutePosition 属性 | CursorLocation 属性 | Recordset 对象


ActiveCommand 属性范例 (JScript)

本范例演示 ActiveCommand 属性。请将下列代码剪切并粘贴到记事本或其他文本编辑器，并将其保存为 ActiveCommandJS.asp。

<!-- BeginActiveCommandJS -->
<%@LANGUAGE="JScript" %>
<%// use this meta tag instead of adojavas.inc%>
<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<%
    // user input
    strName = new String(Request.Form("ContactName"))
%>

<html>

<head>
<title>ActiveCommand Property Example (JScript)</title>
<style>
<!--
BODY {
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   BACKGROUND-COLOR:white;
   COLOR:black;
    }
-->
</style>
</head>

<body bgcolor="White">

<h1>ActiveCommand Property Example (JScript)</h1>

<%
if (strName.length > 0)
    {
        // connection and recordset variables
        var Cnxn = Server.CreateObject("ADODB.Connection")
        var strCnxn = "Provider='sqloledb';Data Source=" + Request.ServerVariables("SERVER_NAME") + ";" +
            "Initial Catalog='Northwind';Integrated Security='SSPI';";
        var cmdContact = Server.CreateObject("ADODB.Command");
        var rsContact = Server.CreateObject("ADODB.Recordset");
        // display variables
        var strMessage;

        try
        {
            // open connection
            Cnxn.Open(strCnxn);

            // Open a recordset using a command object
            cmdContact.CommandText = "SELECT ContactName FROM Customers WHERE City = ?";
            cmdContact.ActiveConnection = Cnxn;
            // create parameter and insert variable value
            cmdContact.Parameters.Append(cmdContact.CreateParameter("ContactName", adChar, adParamInput, 30, strName));

            rsContact = cmdContact.Execute();

            while(!rsContact.EOF){
                // start new line
                strMessage = "<P>";

                // get data
                strMessage += rsContact("ContactName")

                // end the line
                strMessage += "</P>";

                // show data
                Response.Write(strMessage);

                // get next record
                rsContact.MoveNext;
            }
        }
        catch (e)
        {
            Response.Write(e.message);
        }
        finally
        {
            // 'clean up
            if (rsContact.State == adStateOpen)
                rsContact.Close;
            if (Cnxn.State == adStateOpen)
                Cnxn.Close;
            rsContact = null;
            Cnxn = null;
        }
    }
%>

<hr>

<form method="POST" action="ActiveCommandJS.asp">
  <p align="left">Enter city of customer to find (e.g., Paris): <input type="text" name="ContactName" size="40" value=""></p>
  <p align="left"><input type="submit" value="Submit" name="B1"><input type="reset" value="Reset" name="B2"></p>
</form>
</body>

</html>
<!-- EndActiveCommandJS -->

请参阅

ActiveCommand 属性 | Command 对象 | Recordset 对象


ActiveConnection、CommandText、CommandTimeout、CommandType、Size 和 Direction 属性范例 (JScript)

本范例使用 ActiveConnection、CommandText、CommandTimeout、CommandType、Size 和 Direction 属性来执行存储过程。请将下列代码剪切并粘贴到记事本或其他文本编辑器中，并将其保存为 ActiveConnectionJS.asp。

<!-- BeginActiveConnectionJS -->
<%@LANGUAGE="JScript"%>
<%// use this meta tag instead of adojavas.inc%>
<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<html>
<head>
    <title>ActiveConnection, CommandText, CommandTimeout, CommandType, Size, and Direction Properties</title>
<style>
<!--
BODY {
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   BACKGROUND-COLOR:white;
   COLOR:black;
    }
.thead {
   background-color: #008080;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
   color: white;
   }
.thead2 {
   background-color: #800000;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
   color: white;
   }
.tbody {
   text-align: center;
   background-color: #f7efde;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
    }
-->
</style>
</head>

<body bgcolor="White">

<%
    var iRoyalty = parseInt(Request.Form("RoyaltyValue"));
    // check user input

    if (iRoyalty > -1)
    {
            // connection and recordset variables
        var Cnxn = Server.CreateObject("ADODB.Connection")
        var strCnxn = "Provider='sqloledb';Data Source=" + Request.ServerVariables("SERVER_NAME") + ";" +
            "Initial Catalog='pubs';Integrated Security='SSPI';";
        var cmdByRoyalty = Server.CreateObject("ADODB.Command");
        var rsByRoyalty = Server.CreateObject("ADODB.Recordset");
        var rsAuthor = Server.CreateObject("ADODB.Recordset");
        // display variables
        var filter, strMessage;

        try
        {
            // open connection
            Cnxn.Open(strCnxn);

            cmdByRoyalty.CommandText = "byroyalty";
            cmdByRoyalty.CommandType = adCmdStoredProc;
            cmdByRoyalty.CommandTimeOut = 15;

            // The stored procedure called above is as follows:
                //    CREATE PROCEDURE byroyalty
                //  @percentage int
                //    AS
                //  SELECT au_id from titleauthor
                //  WHERE titleauthor.royaltyper = @percentage
                //  GO

            prmByRoyalty = Server.CreateObject("ADODB.Parameter");
            prmByRoyalty.Type = adInteger;
            prmByRoyalty.Size = 3;
            prmByRoyalty.Direction = adParamInput;
            prmByRoyalty.Value = iRoyalty;
            cmdByRoyalty.Parameters.Append(prmByRoyalty);

            cmdByRoyalty.ActiveConnection = Cnxn;

            // recordset by Command - Execute
            rsByRoyalty = cmdByRoyalty.Execute();

            // recordset by Recordset - Open
            rsAuthor.Open("Authors", Cnxn);

            while (!rsByRoyalty.EOF)
            {
                // set filter
                filter = "au_id='" + rsByRoyalty("au_id")
                rsAuthor.Filter = filter + "'";

                // start new line
                strMessage = "<P>";

                // get data
                strMessage += rsAuthor("au_fname") + " ";
                strMessage += rsAuthor("au_lname") + " ";

                // end line
                strMessage += "</P>";

                // show data
                Response.Write(strMessage);

                // get next record
                rsByRoyalty.MoveNext;
            }
        }
        catch (e)
        {
            Response.Write(e.message);
        }
        finally
        {
            // clean up
            if (rsByRoyalty.State == adStateOpen)
                rsByRoyalty.Close;
            if (rsAuthor.State == adStateOpen)
                rsAuthor.Close;
            if (Cnxn.State == adStateOpen)
                Cnxn.Close;
            rsByRoyalty = null;
            rsAuthor = null;
            Cnxn = null;
        }
    }
%>

<hr>

<form method="POST" action="ActiveConnectionJS.asp">
  <p align="left">Enter royalty percentage to find (e.g., 40): <input type="text" name="RoyaltyValue" size="5"></p>
  <p align="left"><input type="submit" value="Submit" name="B1"><input type="reset" value="Reset" name="B2"></p>
</form>
&nbsp;

</body>

</html>
<!-- EndActiveConnectionJS -->

请参阅

ActiveCommand 属性 | Command 对象 | CommandText 属性 | CommandTimeout 属性 | CommandType 属性 | Connection 对象 | Direction 属性 | Parameter 对象 | Record 对象 | Recordset 对象 | Size 属性


ActualSize 和 DefinedSize 属性范例 (JScript)

本范例使用 ActualSize 和 DefinedSize 属性显示字段的定义大小和实际大小。请将下列代码剪切并粘贴到记事本或其他文本编辑器，并将其保存为 ActualSizeJS.asp。

<!-- BeginActualSizeJS -->
<%@LANGUAGE="JScript" %>
<%// use this meta tag instead of adojavas.inc%>
<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->
<html>

<head>
    <title>ActualSize and DefinedSize Properties Example (JScript)</title>
<style>
<!--
body {
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   BACKGROUND-COLOR:white;
   COLOR:black;
    }
.thead2 {
   background-color: #800000;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
   color: white;
   }
.tbody {
   text-align: center;
   background-color: #f7efde;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
    }
-->
</style>
</head>

<body bgcolor="White">

<h1>ADO ActualSize and DefinedSize Properties (JScript)</h1>
<%
    // connection and recordset variables
    var Cnxn = Server.CreateObject("ADODB.Connection")
    var strCnxn = "Provider='sqloledb';Data Source=" + Request.ServerVariables("SERVER_NAME") + ";" +
            "Initial Catalog='Northwind';Integrated Security='SSPI';";
    var rsSuppliers = Server.CreateObject("ADODB.Recordset");
    // display variables
    var fld, strMessage;

    try
    {
        // open connection
        Cnxn.Open(strCnxn);

        // Open a recordset on the stores table
        rsSuppliers.Open("Suppliers", strCnxn);

        // build table headers
        Response.Write("<table>");
        Response.Write('<tr class="thead2"><th>Field Value</th>');
        Response.Write("<th>Defined Size</th>");
        Response.Write("<th>Actual Size</th></tr>");

        while (!rsSuppliers.EOF)
        {
            // start a new line
            strMessage = '<tr class="tbody">';

            // Display the contents of the chosen field with
            // its defined size and actual size
            fld = rsSuppliers("CompanyName");
            strMessage += '<td align="left">' + fld.Value + "</td>"
            strMessage += "<td>" + fld.DefinedSize + "</td>";
            strMessage += "<td>" + fld.ActualSize + "</td>";

            // end the line
            strMessage += "</tr>";

            // display data
            Response.Write(strMessage);

            // get next record
            rsSuppliers.MoveNext;

        }
         // close the table
        Response.Write("</table>");
    }
    catch (e)
    {
        Response.Write(e.message);
    }
    finally
    {
        // clean up
        if (rsSuppliers.State == adStateOpen)
            rsSuppliers.Close;
        if (Cnxn.State == adStateOpen)
            Cnxn.Close;
        rsSuppliers = null;
        Cnxn = null;
    }
%>

</body>

</html>
<!-- EndActualSizeJS -->

请参阅

ActualSize 属性 | DefinedSize 属性 | Field 对象


AddNew 方法范例 (JScript)

本范例使用 AddNew 方法来创建具有指定名称的新记录。请将以下代码剪切并粘贴到记事本或其他文本编辑器中，并将其另存为 AddNewJS.asp。

<!-- BeginAddNewJS -->
<%@LANGUAGE="JScript" %>
<!-- Include file for JScript ADO Constants -->
<%// use this meta tag instead of adojavas.inc%>
<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<html>

<head>
    <title>Add New Method Example (JScript)</title>
<style>
<!--
body {
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   BACKGROUND-COLOR:white;
   COLOR:black;
    }
-->
</style>
</head>

<body>
<h1>AddNew Method Example (JScript)</h1>

<%
    if (Request.Form("Addit") == "AddNew")
    {
        // connection and recordset variables
        var Cnxn = Server.CreateObject("ADODB.Connection")
        var strCnxn = "Provider='sqloledb';Data Source=" + Request.ServerVariables("SERVER_NAME") + ";" +
            "Initial Catalog='Northwind';Integrated Security='SSPI';";
        var rsEmployee = Server.CreateObject("ADODB.Recordset");
        //record variables
        var FName = String(Request.Form("FirstName"));
        var LName = String(Request.Form("LastName"));

        try
        {
            // open connection
            Cnxn.Open(strCnxn)

            // open Employee recordset using client-side cursor
            rsEmployee.CursorLocation = adUseClient;
            rsEmployee.Open("Employees", strCnxn, adOpenKeyset, adLockOptimistic, adCmdTable);

            rsEmployee.AddNew();
            rsEmployee("FirstName") = FName;
            rsEmployee("LastName") = LName;
            rsEmployee.Update;

            // of course, you would normally do error handling here
            Response.Write("New record added.")
        }
        catch (e)
        {
            Response.Write(e.message);
        }
        finally
        {
            // clean up
            if (rsEmployee.State == adStateOpen)
                rsEmployee.Close;
            if (Cnxn.State == adStateOpen)
                Cnxn.Close;
            rsEmployee = null;
            Cnxn = null;
        }
    }
%>

<form method="post" action="AddNewJS.asp" id=form1 name=form1>
<table>
<tr>
    <td colspan="2">
    <h4>Please enter the record to add:</h4>
    </td>
</tr>
<tr>
    <td>
        First Name:
    </td>
    <td>
        <input name="FirstName" maxLength=20>
    </td>
</tr>
<tr>
    <td>
        Last Name:
    </td>
    <td>
        <input name="LastName" size="30" maxLength=30>
    </td>
</tr>
<tr>
    <td align="right">
        <input type="submit" value="Submit" name="Submit">
    </td>
    <TD align="left">
        <INPUT type="reset" value="Reset" name="Reset">
    </TD>
</tr>
</table>
<INPUT type="hidden" value="AddNew" name="Addit">
</form>
</body>
</HTML>
<!-- EndAddNewJS -->

请参阅

AddNew 方法 | Recordset 对象


Append 和 CreateParameter 方法范例 (JScript)

本范例使用 Append 和 CreateParameter 方法执行具有输入参数的存储过程。请将下列代码剪切并粘贴到记事本或其他文本编辑器中，并将其另存为 AppendJS.asp。

<!-- BeginAppendJS -->
<%@LANGUAGE="JScript" %>
<%// use this meta tag instead of adojavas.inc%>
<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<html>
<head>
    <title>Append and CreateParameter Methods Example (JScript)</title>
<style>
<!--
body {
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   BACKGROUND-COLOR:white;
   COLOR:black;
    }
-->
</style>
</head>

<body>
<h1>Append and CreateParameter Methods Example (JScript)</h1>
<%
    // verify user-input
    var iRoyalty = parseInt(Request.Form("RoyaltyValue"));
    if (iRoyalty > -1)
    {

        // connection, recordset and command variables
        var strCnxn = "Provider='sqloledb';Data Source=" + Request.ServerVariables("SERVER_NAME") + ";" +
            "Initial Catalog='pubs';Integrated Security='SSPI';";
        var Cnxn = Server.CreateObject("ADODB.Connection");
        var cmdByRoyalty = Server.CreateObject("ADODB.Command");
        var rsByRoyalty = Server.CreateObject("ADODB.Recordset");
        var rsAuthor = Server.CreateObject("ADODB.Recordset");
        // display variables
        var strMessage;

        try
        {
            // open connection and set cursor location
            Cnxn.Open(strCnxn);
            Cnxn.CursorLocation = adUseClient;

            // command object initial parameters
            cmdByRoyalty.CommandText = "byroyalty";
            cmdByRoyalty.CommandType = adCmdStoredProc;

            // create the new parameter and append to
            // the Command object's parameters collection
            var prmByRoyalty = cmdByRoyalty.CreateParameter("percentage", adInteger, adParamInput);
            cmdByRoyalty.Parameters.Append(prmByRoyalty);
            prmByRoyalty.Value = iRoyalty;

            cmdByRoyalty.ActiveConnection = Cnxn;

            // execute command
            rsByRoyalty = cmdByRoyalty.Execute();

            // display results
            rsAuthor.Open("Authors", Cnxn);

            while (!rsByRoyalty.EOF)
            {
                rsAuthor.Filter = "au_id='" + rsByRoyalty.Fields("au_id") + "'";

                // start new line
                strMessage = "<P>";

                // recordset data
                strMessage += rsAuthor.Fields("au_fname") + " ";
                strMessage += rsAuthor.Fields("au_lname") + " ";

                // end the line
                strMessage += "</P>";

                // show result
                Response.Write(strMessage);

                // et next record
                rsByRoyalty.MoveNext;
            }
        }
        catch (e)
        {
            Response.Write(e.message);
        }
        finally
        {
            // clean up
            if (rsByRoyalty.State == adStateOpen)
                rsByRoyalty.Close;
            if (rsAuthor.State == adStateOpen)
                rsAuthor.Close;
            if (Cnxn.State == adStateOpen)
                Cnxn.Close;
            rsByRoyalty = null;
            rsAuthor = null;
            Cnxn = null;
        }
    }
%>

<hr>

<form method="POST" action="AppendJS.asp" id=form1 name=form1>
  <p align="left">Enter royalty percentage to find (e.g., 40): <input type="text" name="RoyaltyValue" size="5"></p>
  <p align="left"><input type="submit" value="Submit" name="B1"><input type="reset" value="Reset" name="B2"></p>
</form>
&nbsp;

</body>

</html>
<!-- EndAppendJS -->

请参阅

Append 方法 | CreateParameter 方法 | Field 对象 | Fields 集合 | Parameter 对象


CacheSize 属性范例 (JScript)

本范例使用 CacheSize 属性显示使用和不使用缓存（大小为 30 条记录）时执行的操作在性能上的差别。请将下列代码剪切并粘贴到记事本或其他文本编辑器中，并将其保存为 CacheSizeJS.asp。

<!-- BeginCacheSizeJS -->
<%@ Language="JScript" %>
<%// use this meta tag instead of adojavas.inc%>
<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<HTML>
<HEAD>
<title>CacheSize Property Example (JScript)</title>
<style>
<!--
body {
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   BACKGROUND-COLOR:white;
   COLOR:black;
    }
.thead2 {
   background-color: #800000;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
   color: white;
   }
.tbody {
   text-align: center;
   background-color: #f7efde;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
    }
-->
</style>
</HEAD>
<BODY>
<h1>CacheSize Property Example (JScript)</h1>
<%
    // connection and recordset variables
    var Cnxn = Server.CreateObject("ADODB.Connection")
    var strCnxn = "Provider='sqloledb';Data Source=" + Request.ServerVariables("SERVER_NAME") + ";" +
            "Initial Catalog='Northwind';Integrated Security='SSPI';";
    var rsCustomer = Server.CreateObject("ADODB.Recordset");
    // caching variables
    var Now = new Date();
    var Start = Now.getTime();
    var End, Cache, NoCache

    try
    {
        // open connection
        Cnxn.Open(strCnxn)

        // open a recordset on the Employee table using client-side cursor
        rsCustomer.CursorLocation = adUseClient;
        rsCustomer.Open("Customers", strCnxn);

        // loop through the recordset 20 times
        for (var i=1; i<=20; i++)
        {
            rsCustomer.MoveFirst();
            while (!rsCustomer.EOF)
            {
                // do something with the record
                var strTemp = new String(rsCustomer("CompanyName"));
                rsCustomer.MoveNext();
            }
        }

        Now = new Date();
        End = Now.getTime();
        NoCache = End - Start;

        // cache records in groups of 30
        rsCustomer.MoveFirst();
        rsCustomer.CacheSize = 30;

        Now = new Date();
        Start = Now.getTime();

        // loop through the recordset 20 times
        for (var i=1; i<=20; i++)
        {
            rsCustomer.MoveFirst();
            while (!rsCustomer.EOF)
            {
                // do something with the record
                var strTemp = new String(rsCustomer("CompanyName"));
                rsCustomer.MoveNext();
            }
        }

        Now = new Date();
        End = Now.getTime();
        var Cache = End - Start;
    }
    catch (e)
    {
        Response.Write(e.message);
    }
    finally
    {
        // clean up
        if (rsCustomer.State == adStateOpen)
            rsCustomer.Close;
        if (Cnxn.State == adStateOpen)
            Cnxn.Close;
        rsCustomer = null;
        Cnxn = null;
    }
%>

    <table border="2">
        <tr class="thead2">
            <th>No Cache</th>
            <th>30 Record Cache</th>
        </tr>
        <tr class="tbody">
            <td><%=NoCache%></td>
            <td><%=Cache%></td>
        </tr>
    </table>

</BODY>
</HTML>
<!-- EndCacheSizeJS -->

请参阅

CacheSize 属性 | Recordset 对象


Execute、Requery 和 Clear 方法范例 (JScript)

本范例演示从 Command 和 Connection 对象运行 Execute 方法。范例中还使用 Requery 方法检索 Recordset 中的当前数据，并用 Clear 方法清除 Errors 集合的内容。（通过 Recordset 的 ActiveConnection 属性的 Connection 对象来访问 Errors 集合。）将该文件命名为 ExecuteJS.asp。

<!-- BeginExecuteJS -->
<%@LANGUAGE="JScript"%>
<%// use this meta tag instead of adojavas.inc%>
<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<%
    strLastName = new String(Request.Form("AuthorLName"));

    if (strLastName.indexOf("undefined") > -1)
        strLastName = "";
%>

<html>

<head>
<title>Execute, Requery and Clear Methods Example (JScript)</title>
<style>
<!--
BODY {
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   BACKGROUND-COLOR:white;
   COLOR:black;
    }
-->
</style>
</head>

<body bgcolor="White">
<h1>Execute, Requery and Clear Methods Example (JScript)</h1>
<%
    if (strLastName.length > 0)
    {
        // command and recordset variables
        var Connect = "Provider='sqloledb';Data Source=" + Request.ServerVariables("SERVER_NAME") + ";" +
            "Initial Catalog='pubs';Integrated Security='SSPI';";
        var Cnxn = Server.CreateObject("ADODB.Connection");
        var cmdAuthor = Server.CreateObject("ADODB.Command");
        var rsAuthor = Server.CreateObject("ADODB.Recordset");
        var rsAuthor2 = Server.CreateObject("ADODB.Recordset");
        var SQLAuthor2, strMessage, strMessage2;
        var Err, ErrCount;

        try
        {
            // open connection
            Cnxn.Open(Connect);

            // command object parameters
            cmdAuthor.CommandText = "SELECT * FROM Authors WHERE au_lname = ?";
            cmdAuthor.Parameters.Append(cmdAuthor.CreateParameter("Last Name", adChar, adParamInput, 20, strLastName));
            cmdAuthor.ActiveConnection = Cnxn;

            // recordset from command.execute
            rsAuthor = cmdAuthor.Execute();

            // recordset from connection.execute
            SQLAuthor2 = "SELECT * FROM Authors";
            rsAuthor2 = Cnxn.Execute(SQLAuthor2);

                // check for errors
                ErrCount = Cnxn.errors.count;
                if(ErrCount !== 0) //write the errors
                {
                    for(Err = 0; Err = ErrCount; Err++){
                        Err = Cnxn.errors.item;
                        Response.Write(Err);
                    }
                    // clean out any existing errors
                    Cnxn.Errors.Clear;
                }

                // show the data
            Response.Write("<HR><HR>");

                // first recordset
            Response.Write("<b>Command.Execute results</b>")
            while (!rsAuthor.EOF)
            {
                // build output string by starting a new line
                strMessage = "<P>";
                strMessage += "<br>";

                // recordset data
                strMessage += rsAuthor("au_fname") + " ";
                strMessage += rsAuthor("au_lname") + " ";

                // end the line
                strMessage += "</P>";

                // show the results
                Response.Write(strMessage);

                // get next record
                rsAuthor.MoveNext;
            }

            Response.Write("<HR><HR>");

            // second recordset
            Response.Write("<b>Connection.Execute results</b>")
            while (!rsAuthor2.EOF)
            {
                // start a new line
                strMessage2 = "<P>";

                // first and last name are in first column
                strMessage2 += rsAuthor2("au_fname") + " "
                strMessage2 += rsAuthor2("au_lname") + " ";

                // end the line
                strMessage2 += "</P>";

                // show results
                Response.Write(strMessage2);

                // get next record
                rsAuthor2.MoveNext;
            }
        }
        catch (e)
        {
            Response.Write(e.message);
        }
        finally
        {
            // clean up
            if (rsAuthor.State == adStateOpen)
                rsAuthor.Close;
            if (rsAuthor2.State == adStateOpen)
                rsAuthor2.Close;
            if (Cnxn.State == adStateOpen)
                Cnxn.Close;
            rsAuthor1 = null;
            rsAuthor2 = null;
            Cnxn = null;
        }
    }
%>

<hr>

<form method="POST" action="ExecuteJS.asp" id=form1 name=form1>
  <p align="left">Enter last name of author to find (e.g., Ringer): <input type="text" name="AuthorLName" size="40"></p>
  <p align="left"><input type="submit" value="Submit" name="B1"><input type="reset" value="Reset" name="B2"></p>
</form>
</body>

</html>
<!-- EndExecuteJS -->

请参阅

Clear 方法 | Command 对象 | Connection 对象 | Error 对象 | Execute 方法 (ADO Command) | Execute 方法 (ADO Connection) | Recordset 对象 | Requery 方法


Filter 和 RecordCount 属性范例 (JScript)

本范例打开了 Northwind 数据库的 Companies 表中的 Recordset，并使用 Filter 属性限制 CompanyName 字段以字母 D 开头的公司能够看到的记录。请将下列代码剪切并粘贴到记事本或其他文本编辑器，并将其保存为 FilterJS.asp。

<!-- BeginFilterJS -->
<%@  Language=JavaScript %>
<%// use this meta tag instead of adojavas.inc%>
<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<html>

<head>
<title>ADO Recordset.Filter Example</title>
<style>
<!--
BODY {
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   BACKGROUND-COLOR:white;
   COLOR:black;
    }
.thead {
   background-color: #008080;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
   color: white;
   }
.thead2 {
   background-color: #800000;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
   color: white;
   }
.tbody {
   text-align: center;
   background-color: #f7efde;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
    }
-->
</style>
</head>

<body bgcolor="White">

<h1>ADO Recordset.Filter Example</h1>
<!-- Page text goes here -->
<%
    // connection and recordset variables
    var Cnxn = Server.CreateObject("ADODB.Connection")
    var strCnxn = "Provider='sqloledb';Data Source=" + Request.ServerVariables("SERVER_NAME") + ";" +
            "Initial Catalog='Northwind';Integrated Security='SSPI';";
    var rsCustomers = Server.CreateObject("ADODB.Recordset");
    var SQLCustomers = "select * from Customers;";
    // record variables
    var fld, filter
    var showBlank = " ";
    var showNull = "-NULL-";

    try
    {
        //open connection
        Cnxn.Open(strCnxn);

        // create recordset client-side using object refs
        rsCustomers.ActiveConnection = Cnxn;
        rsCustomers.CursorLocation = adUseClient;
        rsCustomers.CursorType = adOpenKeyset;
        rsCustomers.LockType = adLockOptimistic;
        rsCustomers.Source = SQLCustomers;
        rsCustomers.Open();

        rsCustomers.MoveFirst();

        //set filter
        filter = "CompanyName LIKE 'b*'";
        rsCustomers.Filter = filter

        if (rsCustomers.RecordCount == 0) {
            Response.Write("No records matched ");
            Response.Write (SQLCustomers + "So cannot make table...");
            Cnxn.Close();
            Response.End
        }
        else {
        // show the data
            Response.Write('<table width="100%" border="2">');
            while(!rsCustomers.EOF) {
                Response.Write('<tr class="tbody">');
                for (var thisField = 0; thisField < rsCustomers.Fields.Count; thisField++) {
                    fld = rsCustomers(thisField);
                    fldValue = fld.Value;
                    if (fldValue == null)
                        fldValue = showNull;
                    if (fldValue == "")
                        thisField=showBlank;
                    Response.Write("<td>" + fldValue + "</td>")
                }
                rsCustomers.MoveNext();
                Response.Write("</tr>");
            }
            // close the table
            Response.Write("</table>");
        }
    }
    catch (e)
    {
        Response.Write(e.message);
    }
    finally
    {
        // clean up
        if (rsCustomers.State == adStateOpen)
            rsCustomers.Close;
        if (Cnxn.State == adStateOpen)
            Cnxn.Close;
        rsCustomers = null;
        Cnxn = null;
    }
%>

</body>

</html>
<!-- EndFilterJS -->

请参阅

Filter 属性 | RecordCount 属性 | Recordset 对象


Find 方法范例 (JScript)

本范例使用 Recordset 对象的 Find 方法定位并显示 Northwind 数据库中名称以字母 G 开始的公司。请将下列代码剪切并粘贴到记事本或其他文本编辑器中，并将其另存为 FindJS.asp。

<!-- BeginFindJS -->
<%@  Language=JavaScript %>
<%// use this meta tag instead of adojavas.inc%>
<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<html>

<head>
<title>ADO Recordset.Find Example</title>
<style>
<!--
BODY {
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   BACKGROUND-COLOR:white;
   COLOR:black;
    }
.thead {
   background-color: #008080;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
   color: white;
   }
.thead2 {
   background-color: #800000;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
   color: white;
   }
.tbody {
   text-align: center;
   background-color: #f7efde;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
    }
-->
</style>
</head>

<body bgcolor="white">

<h1>ADO Recordset.Find Example</h1>
<%
    // connection and recordset variables
    var Cnxn = Server.CreateObject("ADODB.Connection");
    var strCnxn = "Provider='sqloledb';Data Source=" + Request.ServerVariables("SERVER_NAME") + ";" +
            "Initial Catalog='Northwind';Integrated Security='SSPI';";
    var rsCustomers = Server.CreateObject("ADODB.Recordset");
        // display string
    var strMessage;
    var strFind;

    try
    {
            // open connection
        Cnxn.Open(strCnxn);

            //create recordset using object refs
        SQLCustomers = "select * from Customers;";

        rsCustomers.ActiveConnection = Cnxn;
        rsCustomers.CursorLocation = adUseClient;
        rsCustomers.CursorType = adOpenKeyset;
        rsCustomers.LockType = adLockOptimistic;
        rsCustomers.Source = SQLCustomers;

        rsCustomers.Open();
        rsCustomers.MoveFirst();

            //find criteria
        strFind = "CompanyName like 'g%'"
        rsCustomers.Find(strFind);

        if (rsCustomers.EOF) {
            Response.Write("No records matched ");
            Response.Write(SQLCustomers & "So cannot make table...");
            Cnxn.Close();
            Response.End();
        }
        else {
            Response.Write('<table width="100%" border="2">');
            Response.Write('<tr class="thead2">');
            // Put Headings On The Table for each Field Name
            for (thisField = 0; thisField < rsCustomers.Fields.Count; thisField++) {
                fieldObject = rsCustomers.Fields(thisField);
                Response.Write('<th width="' + Math.floor(100 / rsCustomers.Fields.Count) + '%">' + fieldObject.Name + "</th>");
            }
            Response.Write("</tr>");

            while (!rsCustomers.EOF) {
                Response.Write('<tr class="tbody">');
                for(thisField=0; thisField<rsCustomers.Fields.Count; thisField++) {
                    fieldObject = rsCustomers.Fields(thisField);
                    strField = fieldObject.Value;
                    if (strField == null)
                        strField = "-Null-";
                    if (strField == "")
                        strField = "";
                    Response.Write("<td>" + strField + "</td>");
                }
                rsCustomers.Find(strFind, 1, adSearchForward)
                Response.Write("</tr>");
            }
            Response.Write("</table>");
        }
    }
    catch (e)
    {
        Response.Write(e.message);
    }
    finally
    {
        // clean up
        if (rsCustomers.State == adStateOpen)
            rsCustomers.Close;
        if (Cnxn.State == adStateOpen)
            Cnxn.Close;
        rsCustomers = null;
        Cnxn = null;
    }
%>

</body>

</html>
<!-- EndFindJS -->

请参阅

Find 方法 | Recordset 对象


GetRows 方法范例 (JScript)

本范例使用 GetRows 方法从 Recordset 中检索 Custiomers 表中的所有行，并将结果数据填充到数组。在两种情况下，GetRows 方法返回的行将少于所需的数目：一种情况是到达了 EOF，另一种情况是 GetRows 试图检索被其他用户删除的记录。仅在发生第二种情况时，该函数才返回 False。将下列代码剪切并粘贴到记事本或其他文本编辑器中，并将其保存为 GetRowsJS.asp。

<!-- BeginGetRowsJS -->
<%@ LANGUAGE="JScript" %>
<%// use this meta tag instead of adojavas.inc%>
<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<html>

<head>
<title>ADO Recordset.GetRows Example (JScript)</title>
<style>
<!--
BODY {
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   BACKGROUND-COLOR:white;
   COLOR:black;
    }
.thead {
   background-color: #008080;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
   color: white;
   }
.thead2 {
   background-color: #800000;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
   color: white;
   }
.tbody {
   text-align: center;
   background-color: #f7efde;
   font-family: 'Verdana','Arial','Helvetica',sans-serif;
   font-size: x-small;
    }
-->
</style>
</head>

<body bgcolor="white">

<h1>ADO Recordset.GetRows Example (JScript)</h1>
    <!-- Page text goes here -->
<%
        var Connect = "Provider='sqloledb';Data Source=" + Request.ServerVariables("SERVER_NAME") + ";" +
            "Initial Catalog='Northwind';Integrated Security='SSPI';";
    var mySQL = "select * from customers;";
    var showblank = " ";
    var shownull = "-null-";

    var connTemp = Server.CreateObject("ADODB.Connection");

    try
    {
        connTemp.Open(Connect);
        var rsTemp = Server.CreateObject("ADODB.Recordset");
        rsTemp.ActiveConnection = connTemp;
        rsTemp.CursorLocation = adUseClient;
        rsTemp.CursorType = adOpenKeyset;
        rsTemp.LockType = adLockOptimistic;
        rsTemp.Open(mySQL);

        rsTemp.MoveFirst();

        if (rsTemp.RecordCount == 0)
        {
            Response.Write("No records matched ");
            Response.Write (mySQL & "So cannot make table...");
            connTemp.Close();
            Response.End();
        } else
        {
            Response.Write('<table width="100%" border="2">');
            Response.Write('<tr class="thead2">');

            //  Headings On The Table for each Field Name
            for (var i=0; i<rsTemp.Fields.Count; i++)
            {
                fieldObject = rsTemp.fields(i);
                Response.Write('<td width="' + Math.floor(100 / rsTemp.Fields.Count) + '%">' + fieldObject.name + "</td>");
            }

            Response.Write("</tr>");

            // JScript doesn't support multi-dimensional arrays
            // so we'll convert the returned array to a single
            // dimensional JScript array and then display the data.
            tempArray = rsTemp.GetRows();
            recArray = tempArray.toArray();

            var col = 1;
            var maxCols = rsTemp.Fields.Count;

            for (var thisField=0; thisField<recArray.length; thisField++)
            {
                if (col == 1)
                    Response.Write('<tr class="tbody">');
                if (recArray[thisField] == null)
                        recArray[thisField] = shownull;
                if (recArray[thisField] == "")
                        recArray[thisField] = showblank;
                Response.Write("<td>" + recArray[thisField] + "</td>");
                col++
                if (col > maxCols)
                {
                    Response.Write("</tr>");
                    col = 1;
                }
            }
            Response.Write("</table>");
        }
    }
    catch (e)
    {
        Response.Write(e.message);
    }
    finally
    {
        // clean up
        if (rsTemp.State == adStateOpen)
            rsTemp.Close;
        if (connTemp.State == adStateOpen)
            connTemp.Close;
        rsTemp = null;
        connTemp = null;
    }
%>

</body>

</html>
<!-- EndGetRowsJS -->

请参阅

GetRows 方法 | Recordset 对象


RDS API 参考

本部分 ADO 文档包含每个 RDS 对象、属性、方法和事件的主题。有关详细信息，请在索引中搜索特定主题或参阅下面的主题：

  • RDS 对象
  • RDS 属性
  • RDS 方法
  • RDS 事件


RDS 对象

DataControl (RDS) | 将数据查询 Recordset 绑定到一个或多个控件上（例如，文本框、网格控件或组合框），以便在 Web 页上显示 Recordset 数据。
DataFactory (RDSServer) | 实现对客户端应用程序的指定数据源进行读/写数据访问的方法。
DataSpace (RDS) | 创建客户端代理以自定义位于中间层的业务对象。


DataControl 对象 (RDS)

将数据查询 Recordset 绑定到一个或多个控件上（例如，文本框、网格控件或组合框），以便在 Web 页上显示 Recordset 数据。

语法

<OBJECT CLASSID="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" ID="DataControl"
   <PARAM NAME="Connect" VALUE="DSN=DSNName;UID=usr;PWD=pw;">
   <PARAM NAME="Server" VALUE="http://awebsrvr">
   <PARAM NAME="SQL" VALUE="QueryText">
</OBJECT>

说明

RDS.DataControl 对象的类 ID 为 BD96C556-65A3-11D0-983A-00C04FC29E33。

注意 如果获得 RDS.DataSpace 或 RDS.DataControl 对象未被加载的错误，请确保使用了正确的类 ID。这些对象的类 ID 已在版本 1.0 和版本 1.1 的基础上进行了更改。

对于基本应用方案，只需要设置 RDS.DataControl 对象的 SQL、Connect 和 Server 属性，该对象将自动调用默认业务对象 RDSServer.DataFactory。

RDS.DataControl 中的所有属性都是可选的，因为自定义业务对象可以替代它们的功能。

注意 如果查询出多个结果，将只返回第一个 Recordset。如果需要多个结果集合，请将每个集合分配给它自己的 DataControl。下面是用于查询多个结果的范例：
"Select * from Authors, Select * from Topics"

如果在使用 RDS.DataControl 对象时向连接字符串中添加“DFMode=20;”，可以在更新数据时提高服务器的性能。通过这项设置，服务器上的 RDSServer.DataFactory 对象将使用较低的资源集中模式。但是，下列功能在此配置中无效：

  • 使用参数化查询。
  • 调用 Execute 方法前获得参数或列信息。
  • 将 Transact Updates 设置为 True。
  • 获得行状态。
  • 调用 Resync 方法。
  • 通过 Update Resync 属性刷新（显式或自动）。
  • 设置 Command 或 Recordset 属性。
  • 使用 adCmdTableDirect。

在默认情况下，RDS.DataControl 对象以异步模式运行。如果应用程序需要同步执行，请将 ExecuteOptions 参数设置为 adcExecSync，将 FetchOptions 参数设置为 adcFetchUpFront，如下例所示。

<OBJECT CLASSID="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33"
    ID="DataControl"
   <PARAM NAME="Connect" VALUE="DSN=DSNName;UID=usr;PWD=pw;">
   <PARAM NAME="Server" VALUE="http://awebsrvr">
   <PARAM NAME="SQL" VALUE="QueryText">
   <PARAM NAME="ExecuteOptions" VALUE="1">
   <PARAM NAME="FetchOptions" VALUE="1">
</OBJECT>

使用一个 RDS.DataControl 对象将单个查询的结果链接到一个或多个可视控件上。例如，假设您编写查询请求客户数据，如姓名、住所、出生地、年龄及优先级客户状态。可以使用单个 RDS.DataControl 对象分别在三个单独的文本框中显示客户的姓名、年龄和居住区；在复选框中显示优先级客户状态；在网格控件中显示所有数据。

使用不同的 RDS.DataControl 对象将多个查询的结果链接到不同的可视控件上。例如，假设用一个查询获取有关客户的信息，用第二个查询获取有关该客户所购商品的信息。您想将第一个查询的结果显示在三个文本框和一个复选框中，将第二个查询的结果显示在网格控件中。如果使用默认的业务对象 (RDSServer.DataFactory)，需要执行以下操作：

  • 向 Web 页中添加两个 RDS.DataControl 对象。
  • 为两个 RDS.DataControl 对象的每个 SQL 属性各编写一个查询。一个 RDS.DataControl 对象将包含请求客户信息的 SQL 查询；另一个则包含请求客户所购商品列表的查询。
  • 在每个绑定控件的 OBJECT 标记中指定 DATAFLD 值，以便设置要显示在每个可视控件中的数据值。

通过 OBJECT 标记可在单个 Web 页中嵌入数目不限的 RDS.DataControl 对象。

在 Web 页上定义 RDS.DataControl 对象时，请使用非零的 Height 和 Width 值（例如 1）以避免包含额外的空间。

远程数据服务客户端组件已经是 Internet Explorer 4.0 的一部分，因此，RDS.DataControl 对象标记中不必包含 CODEBASE 参数。

使用 Internet Explorer 4.0 或更新版本时，如果要使用 HTML 控件和 ActiveX® 控件绑定到数据，这两种控件必须被标记为房间模型控件。

Microsoft Visual Basic 用户 RDS.DataControl 只用于基于 Web 的应用程序。Visual Basic 客户端应用程序不需要它。

请参阅

VBScript 范例

属性、方法和事件


属性、方法和事件

RDS 2.5 API 参考

DataControl 对象 (RDS) 属性、方法和事件

属性

Connect 属性 (RDS)

ExecuteOptions 属性 (RDS)

FetchOptions 属性 (RDS)

FilterColumn 属性 (RDS)

FilterCriterion 属性 (RDS)

FilterValue 属性 (RDS)

Handler 属性 (RDS)

InternetTimeout 属性 (RDS)

ReadyState 属性 (RDS)

Recordset 和 SourceRecordset 属性 (RDS)

Server 属性 (RDS)

SortColumn 属性 (RDS)

SortDirection 属性 (RDS)

SQL 属性 (RDS)

URL 属性 (RDS)

方法

Cancel 方法 (RDS)

CancelUpdate 方法 (RDS)

CreateRecordset 方法 (RDS)

MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法 (RDS)

Refresh 方法 (RDS)

Reset 方法 (RDS)

SubmitChanges 方法 (RDS)

事件

OnError 事件

OnReadyStateChange 事件

请参阅

适用于：DataControl 对象 (RDS)


DataFactory 对象 (RDSServer)

此默认的服务器端业务对象实现对客户端应用程序的指定数据源进行读/写数据访问的方法。

说明

RDSServer.DataFactory 对象被设计为服务器端的 Automation 对象，可以接收客户端请求。在 Internet 实现过程中，它驻留在 Web 服务器上，并通过 ADISAPI 组件实例化。RDSServer.DataFactory 对象提供对指定数据源的读写访问，但不包含任何验证或业务规则逻辑。

如果使用在 RDSServer.DataFactory 和 RDS.DataControl 对象中都有效的方法，远程数据服务将默认使用 RDS.DataControl 版本。默认采用基本编程方案，在此方案中，RDSServer.DataFactory 用作常规服务器端业务对象。

如果要让 Web 应用程序处理任务特有的服务器端进程，可以用自定义业务对象替代 RDSServer.DataFactory。

可以创建调用 RDSServer.DataFactory 方法的服务器端业务对象，如 Query 和 CreateRecordset。这有助于向业务对象添加功能，而利用现有的远程数据服务技术。

RDSServer.DataFactory 对象的类 ID 为 9381D8F5-0288-11D0-9501-00AA00B911A5。

请参阅

VBScript 范例

属性、方法和事件


属性、方法和事件

RDS 2.5 API 参考

DataFactory 对象 (RDSServer) 属性、方法和事件

属性

无。

方法

ConvertToString 方法 (RDS) | 将记录集转换为 MIME64 字符串。
CreateRecordset 方法 (RDS) | 创建并返回空的记录集。
Query 方法 (RDS) | 执行请求并创建高级数据行集合。
SubmitChanges 方法 (RDS) | 如果给出带有挂起更改的记录集，此方法会将这些更改提交到用连接字符串标识的数据库。

事件

无。

请参阅

适用于：DataFactory 对象 (RDSServer)

© 1998-2002 Microsoft Corporation。保留所有权利。


DataSpace 对象 (RDS)

创建客户端 代理以自定义位于中间层的业务对象。

说明

远程数据服务需要业务对象代理，这样客户端组件就可以与位于中间层的业务对象进行通讯。代理便于对跨越进程或计算机边界的应用程序的 Recordset 数据进行打包、拆包和传输（调度）。

远程数据服务使用 RDS.DataSpace 对象的 CreateObject 方法来创建业务对象代理。只要创建了相应的中间层业务对象的实例，就会动态创建业务对象代理。远程数据服务支持以下协议：HTTP、HTTPS（HTTP 安全套接字）、DCOM 以及进程内（客户端组件和业务对象驻留在同一台计算机上）。

注意 当 RDS.DataSpace 对象使用 HTTP 或 HTTPS 协议时，RDS 以“无状态信息”的方式运转。即当服务器返回一个响应后，任何关于客户请求的内部信息都将被放弃。
尽管业务对象对于业务对象代理的整个执行过程都看似存在，但实际上只有在请求接收到响应时，业务对象才存在。当请求发出（即在业务对象上调用一种方法）时，代理打开一个到服务器的新连接，并且服务器创建一个业务对象的新实例。当业务对象响应请求以后，服务器破坏业务对象并关闭连接。
这表明您不能使用业务对象属性或变量将数据从一个请求传递到另一个请求。必须采用其他机制（如文件或方法参数）来持久保留状态数据。

RDS.DataSpace 对象的类 ID 为 BD96C556-65A3-11D0-983A-00C04FC29E36。

请参阅

VBScript 范例

属性、方法和事件


属性、方法和事件

RDS 2.5 API 参考

DataSpace 对象 (RDS) 属性、方法和事件

属性

InternetTimeout 属性 (RDS)

方法

CreateObject 方法 (RDS)

事件

无。

请参阅

适用于：DataSpace 对象 (RDS)


RDS 属性

Connect (RDS) | 指示运行查询和更新操作的数据库名称。
ExecuteOptions (RDS) | 指示是否启用异步执行。
FetchOptions (RDS) | 指示异步提取的类型。
FilterColumn (RDS) | 指示计算过滤条件的列。
FilterCriterion (RDS) | 指示在过滤值中使用的计算操作符。
FilterValue (RDS) | 指示用于过滤记录的值。
Handler (RDS) | 指示扩展 RDSServer.DataFactory 功能的服务器端自定义程序（“处理程序”）的名称，以及“处理程序”使用的所有参数。
InternetTimeout (RDS) | 指示请求超时前等待的毫秒数。
ReadyState (RDS) | 指示 DataControl 对象在将数据提取到其 Recordset 对象时的进度。
Recordset 和 SourceRecordset (RDS) | 指示从自定义业务对象返回的 Recordset 对象。
Server (RDS) | 指示 Internet Information Services (IIS) 名称和通讯协议。
SortColumn (RDS) | 指示作为记录排序基准的列。
SortDirection (RDS) | 指示排序顺序是升序还是降序。
SQL (RDS) | 指示用于检索 Recordset 的查询字符串。
URL (RDS) | 指示包含相对 URL 或绝对 URL 的字符串。


Connect 属性 (RDS)

指示运行查询和更新操作的数据库名称。

可以在设计时在 RDS.DataControl 对象的 OBJECT 标记中设置 Connect 属性，或者在运行时在脚本代码（如 VBScript）中设置。

语法

Design time: <PARAM NAME="Connect" VALUE="ConnectionString">
Run time: DataControl.Connect = "ConnectionString"

参数

ConnectionString
有效的连接字符串。有关连接字符串的其他常规信息，请参阅 ConnectionString 属性或提供者文档。
注意 将 MS Remote 指定为 RDS.DataControl 的提供者将创建一个四层方案。超过三层的方案尚未进行测试，而且也不需要超过三层的方案。
DataControl
对象变量，表示 RDS.DataControl 对象。

请参阅

VBScript 范例

Query 方法 (RDS) | Refresh 方法 (RDS) | SubmitChanges 方法 (RDS)

适用于：DataControl 对象 (RDS)


ExecuteOptions 属性 (RDS)

指示是否启用异步执行。

设置和返回值

设置或返回下列值之一。

常量 | 说明
adcExecSync | 同步执行 Recordset 的下一个刷新操作。
adcExecAsync | 默认值。异步执行 Recordset 的下一个刷新操作。
注意 使用这些常量的每一个客户端可执行文件都必须提供这些常量的声明。可以从位于 C:\Program Files\Common Files\System\MSADC 文件夹中的 Adcvbs.inc 文件中剪切并粘贴所需的常量声明。

说明

如果将 ExecuteOptions 设置为 adcExecAsync，它将在 RDS.DataControl 对象的 Recordset 上异步执行下一个 Refresh 调用。

当正在执行可能更改 RDS.DataControl 对象的 Recordset 的另一个异步操作时，如果试图调用 Reset、Refresh、SubmitChanges、CancelUpdate 或 Recordset，将产生错误。

如果在异步操作过程中发生错误，RDS.DataControl 对象的 ReadyState 值将由 adcReadyStateLoaded 更改为 adcReadyStateComplete，Recordset 属性值仍保持为 Nothing。

请参阅

VBScript 范例

Cancel 方法 (RDS)

适用于：DataControl 对象 (RDS)


FetchOptions 属性 (RDS)

指示异步提取的类型。

设置和返回值

设置或返回下列值之一。

常量 | 说明
adcFetchUpFront | 在控制返回应用程序前提取 Recordset 的所有记录。在允许应用程序对 Recordset 执行任意操作之前提取完整的 Recordset。
adcFetchBackground | 一旦提取第一批记录，控制便可返回应用程序。对试图访问未在第一批提取的记录的 Recordset 后续读取将被延迟到实际提取查询记录，此时控制将返回应用程序。
adcFetchAsync | 默认值。在后台提取记录时，控制将立即返回应用程序。如果应用程序试图读取未被提取的记录，则最接近查询记录的记录将被读取，控制立即返回，指示已经到达 Recordset 的当前结尾处。例如，调用 MoveLast 将把当前记录位置移动到实际提取的最后一个记录，即使还有更多记录要继续预置 Recordset。
注意 使用这些常量的每一个客户端可执行文件都必须提供这些常量的声明。可以从 C:\Program Files\Common Files\System\MSADC 文件夹中的 Adcvbs.inc 文件中剪切并粘贴所需的常量声明。

说明

在 Web 应用程序中，通常使用 adcFetchAsync（默认值），因为它提供更好的性能。在已编译的客户端应用程序中，通常使用 adcFetchBackground。

请参阅

VBScript 范例

Cancel 方法 (RDS)

适用于：DataControl 对象 (RDS)


FilterColumn 属性 (RDS)

指示计算过滤条件的列。

语法

DataControl.FilterColumn = String

参数

DataControl
对象变量，表示 RDS.DataControl 对象。
String
String 值，指定要计算过滤条件的列。在 FilterCriterion 属性中指定过滤条件。

说明

SortColumn、SortDirection、FilterValue、FilterCriterion 和 FilterColumn 属性提供在客户端缓存上的排序和过滤功能。排序功能按一列中的值对记录进行排序。过滤功能基于查找条件显示记录的子集，而整个 Recordset 仍保存在缓存中。Reset 方法将执行条件并用可更新的 Recordset 替换当前的 Recordset。

请参阅

VBScript 范例

FilterCriterion 属性 (RDS) | FilterValue 属性 (RDS) | SortColumn 属性 (RDS) | SortDirection 属性 (RDS)

适用于：DataControl 对象 (RDS)


FilterCriterion 属性 (RDS)

指示在过滤值中使用的计算操作符。

语法

DataControl.FilterCriterion = String

参数

DataControl
对象变量，表示 RDS.DataControl 对象。
String
String 值，指定针对记录的 FilterValue 的计算操作符。它可以是下列字符串之一：<、<=、>、>=、= 或 <>。

说明

SortColumn、SortDirection、FilterValue、FilterCriterion 和 FilterColumn 属性提供在客户端缓存上的排序和过滤功能。排序功能按一列中的值对记录进行排序。过滤功能基于查找条件显示记录的子集，而整个 Recordset 仍保存在缓存中。Reset 方法将执行条件并用可更新的 Recordset 替换当前的 Recordset。

“!=”操作符对 FilterCriterion 无效，应使用“<>”。

如果既设置了过滤属性又设置了排序属性，调用 Reset 方法时，将先过滤行集合，然后排序。对于升序排序，Null 值位于顶部；对于降序排序，Null 值位于底部（升序排序为默认方式）。

请参阅

VBScript 范例

FilterColumn 属性 (RDS) | FilterValue 属性 (RDS) | SortColumn 属性 (RDS) | SortDirection 属性 (RDS)

适用于：DataControl 对象 (RDS)


FilterValue 属性 (RDS)

指示用于过滤记录的值。

语法

DataControl.FilterValue = String

参数

DataControl
对象变量，表示 RDS.DataControl 对象。
String
String 值，表示用于过滤记录的数据值（如 'Programmer' 或 125）。

说明

SortColumn、SortDirection、FilterValue、FilterCriterion 和 FilterColumn 属性提供在客户端缓存上的排序和过滤功能。排序功能按一列中的值对记录进行排序。过滤功能基于查找条件显示记录的子集，而整个 Recordset 仍保存在缓存中。Reset 方法将执行条件并用可更新的 Recordset 替换当前的 Recordset。

Null 值会导致类型不匹配错误。

请参阅

VBScript 范例

FilterColumn 属性 (RDS) | FilterCriterion 属性 (RDS) | SortColumn 属性 (RDS) | SortDirection 属性 (RDS)

适用于：DataControl 对象 (RDS)


Handler 属性 (RDS)

指示扩展 RDSServer.DataFactory 功能的服务器端自定义程序（处理程序）的名称，以及“处理程序”使用的所有参数。

语法

DataControl.Handler = String

参数

DataControl
对象变量，表示 RDS.DataControl 对象。
String
String 值，包含处理程序和所有参数名称，均由逗号间隔（例如 "handlerName,parm1,parm2,...,parm N"）。

说明

此属性支持自定义，自定义要求将 CursorLocation 属性设置为 adUseClient。

处理程序的名称及参数（如果有）由逗点（“,”）隔开。如果 String 中出现分号（“;”），将导致不可预测的行为。可以编写自己的处理程序使它支持 IDataFactoryHandler 接口。

默认的处理程序名称为 MSDFMAP.Handler，其默认参数是名为 MSDFMAP.INI 的自定义文件。用此属性可调用由服务器管理员创建的替换自定义文件。

设置 Handler 属性的另一方法是在 ConnectionString 属性中指定处理程序和参数，即“Handler=handlerName,parm1,parm2,...;”。

请参阅

Visual Basic 范例

DataFactory 自定义 | DataFactory 对象 (RDSServer)

适用于：DataControl 对象 (RDS)


InternetTimeout 属性 (RDS)

指示请求超时前等待的毫秒数。

设置和返回值

设置或返回 Long 值，表示请求超时前等待的毫秒数。

说明

此属性只适用于通过 HTTP 或 HTTPS 协议发送的请求。

执行三层环境中的请求需要几分钟。用此属性指定长时间运行的请求所需的额外时间。

请参阅

Visual Basic 范例 | VC++ 范例 | VJ++ 范例

适用于：DataControl 对象 (RDS) | DataSpace 对象 (RDS)


ReadyState 属性 (RDS)

指示 DataControl 对象在将数据检索到其 Recordset 对象中时的进度。

设置和返回值

设置或返回下列值之一。

值 | 说明
adcReadyStateLoaded | 当前查询仍在执行，没有提取行。DataControl 对象的 Recordset 不可用。
adcReadyStateInteractive | 当前查询检索到的初始行集合已被保存到 DataControl 对象的 Recordset 中，并且可供使用。仍在提取剩余的行。
adcReadyStateComplete | 当前查询检索到所有行已被保存到 DataControl 对象的 Recordset 中，并且可供使用。 如果由于出现错误而终止操作，或者没有初始化 Recordset 对象时，也会存在该状态。
注意 使用这些常量的每一个客户端可执行文件都必须提供这些常量的声明。可以从 C:\Program Files\Common Files\System\MSADC 文件夹中的 Adcvbs.inc 文件中剪切并粘贴所需的常量声明。

说明

用 onReadyStateChange 事件监视异步查询操作过程中对 ReadyState 属性的更改。这比定期检查属性的值效率更高。

如果在异步操作过程中发生错误，ReadyState 属性将更改为 adcReadyStateComplete，State 属性将由 adStateExecuting 更改为 adStateClosed，而 Recordset 对象的 Value 属性仍保持为 Nothing。

请参阅

VBScript 范例

Cancel 方法 (RDS) | ExecuteOptions 属性 (RDS)

适用于：DataControl 对象 (RDS)


Recordset,SourceRecordset 属性 (RDS)

RDS 2.5 API 参考

Recordset 和 SourceRecordset 属性 (RDS)

指示从自定义业务对象返回的 Recordset 对象。

语法

DataControl.SourceRecordset = Recordset
Recordset = DataControl.Recordset

参数

DataControl
对象变量，表示 RDS.DataControl 对象。
Recordset
对象变量，表示 Recordset 对象。

说明

可以将 SourceRecordset 属性设置为从自定义业务对象返回的 Recordset。

这些属性允许应用程序通过自定义进程的方式处理绑定进程。它们接收封装在 Recordset 中的行集合以便直接与 Recordset 交互作用，执行诸如设置属性或在 Recordset 中重复等操作。

可以在运行时在脚本代码中设置 SourceRecordset 属性或读取 Recordset 属性。

SourceRecordset 为只写属性，与之相反，Recordset 为只读属性。

请参阅

VBScript 范例

CreateRecordset 方法 (RDS) | Query 方法 (RDS)

适用于：DataControl 对象 (RDS)


Server 属性 (RDS)

指示 Internet Information Server (IIS) 名称和通讯协议。

可以在设计时在 RDS.DataControl 对象的 OBJECT 标记中设置 Server 属性，或者在运行时在脚本代码中设置。

语法

协议 设计时语法
HTTP
<PARAM NAME="Server" VALUE="http://awebsrvr:port">
HTTPS
<PARAM NAME="Server" VALUE="https://awebsrvr:port">
DCOM
<PARAM NAME="Server" VALUE="computername">
In-process
<PARAM NAME="Server" VALUE="">
协议 运行时语法
HTTP
DataControl.Server="http://awebsrvr:port"
HTTPS
DataControl.Server="https://awebsrvr:port"
DCOM
DataControl.Server="computername"
In-process
DataControl.Server=""

参数

awebsrvr 或 computername
String 值。如果服务器在远程计算机上，该值包含 Internet、Intranet 路径或计算机的名称；如果服务器在本地计算机上，该值包含空字符串。
port
可选。用于连接到 IIS 服务器的端口。端口号在 Internet Explorer（在“视图”菜单上单击“选项”，然后选择“连接”选项卡）中或在 IIS 中进行设置。
DataControl
对象变量，表示 RDS.DataControl 对象。

说明

服务器是处理 RDS.DataControl 请求（即查询或更新）的地方。默认情况下，所有请求均由 RDSServer.DataFactory 对象、MSDFMAP.Handler 组件和指定服务器上的 MSDFMAP.INI 文件处理。请记住要在适当时间更改服务器，以协调新旧 MSDFMAP.INI 文件中的设置。不兼容可能会导致请求在一个服务器上成功，而在另一个服务器上失败。如果将 Server 属性设置为 ""，将在本地计算机上使用这些对象。

请参阅

VBScript 范例

Connect 属性 (RDS) | SQL 属性 (RDS) | SubmitChanges 方法 (RDS)

适用于：DataControl 对象 (RDS)


SortColumn 属性 (RDS)

指示作为记录排序基准的列。

语法

DataControl.SortColumn = String

参数

DataControl
对象变量，表示 RDS.DataControl 对象。
String
String 值，表示作为记录排序基准的列名称或别名。

说明

SortColumn、SortDirection、FilterValue、FilterCriterion 和 FilterColumn 属性提供在客户端缓存上的排序和过滤功能。排序功能按一列中的值对记录进行排序。过滤功能基于查找条件显示记录的子集，而整个 Recordset 仍保存在缓存中。Reset 方法将执行查找条件并用可更新的 Recordset 替换当前 Recordset。

若要在 Recordset 上排序，必须先保存所有挂起更改。如果正在使用 RDS.DataControl，可以使用 SubmitChanges 方法。例如，如果 RDS.DataControl 名为 ADC1，那么代码应该为 ADC1.SubmitChanges。如果正在使用 ADO Recordset，可以使用其 UpdateBatch 方法。对于用 CreateRecordset 方法创建的 Recordset 对象，建议使用 UpdateBatch 方法。例如，您的代码可以是 myRS.UpdateBatch 或 ADC1.Recordset.UpdateBatch。

请参阅

VBScript 范例

Sort 属性 | SortDirection 属性 (RDS)

适用于：DataControl 对象 (RDS)


SortDirection 属性 (RDS)

指示排序顺序是升序还是降序。

语法

DataControl.SortDirection = value

参数

DataControl
对象变量，表示 RDS.DataControl 对象。
Value
Boolean 值，当设置为 True 时，指示排序方向为升序。设置为 False 时，指示排序方向为降序。

说明

SortColumn、SortDirection、FilterValue、FilterCriterion 和 FilterColumn 属性提供在客户端缓存上的排序和过滤功能。排序功能按一列中的值对记录进行排序。过滤功能基于查找条件显示记录的子集，而整个 Recordset 仍保存在缓存中。Reset 方法将执行查找条件并用可更新的 Recordset 替换当前 Recordset。

请参阅

VBScript 范例

Sort 属性 | SortColumn 属性 (RDS)

适用于：DataControl 对象 (RDS)


SQL 属性 [ADO]

RDS 2.5 API 参考

SQL 属性 (RDS)

指示用于检索 Recordset 的查询字符串。

可以在设计时在 RDS.DataControl 对象的 OBJECT 标记中设置 SQL 属性，或者在运行时在脚本代码中设置。

语法

Design time: <PARAM NAME="SQL" VALUE="QueryString">
Run time: DataControl.SQL = "QueryString"

参数

QueryString
String 值，包含有效的 SQL 数据请求。
DataControl
对象变量，表示 RDS.DataControl 对象。

说明

通常情况下，这是一个 SQL 语句（使用数据库服务器方言），如“Select * from NewTitles”。若要确保精确匹配和更新记录，可更新的查询必须包含非长二进制或计算字段的字段。

如果自定义服务器端业务对象检索客户端数据，则 SQL 属性为可选项。

请参阅

VBScript 范例

Connect 属性 (RDS) | Query 方法 (RDS) | Refresh 方法 (RDS) | SubmitChanges 方法 (RDS)

适用于：DataControl 对象 (RDS)


URL 属性 (RDS)

指示包含相对或绝对 URL 的字符串。

可以在设计时在 DataControl 对象的 OBJECT 标记中设置 URL 属性，或者在运行时在脚本代码中设置。

语法

Design time: <PARAM NAME="URL" VALUE="Server">
Run time: DataControl.URL="Server"

参数

Server
String 值，包含有效的 URL。
DataControl
对象变量，表示 DataControl 对象。

说明

通常情况下，URL 标识可以产生和返回 Recordset 的 Active Server Page (.asp) 文件。因此，用户可获取 Recordset 而不必调用服务器端 DataFactory 对象，或编写自定义业务对象。

如果已设置 URL 属性，则 SubmitChanges 将更改提交到由 URL 指定的位置。

请参阅

VBScript 范例

适用于：DataControl 对象 (RDS)


RDS 方法

Cancel (RDS) | 取消执行挂起的异步方法调用。
CancelUpdate (RDS) | 取消对 Recordset 对象的当前行或新行所做的任何更改。
ConvertToString (RDS) | 将 Recordset 转换为表示记录集数据的 MIME 字符串。
CreateObject (RDS) | 创建目标业务对象的代理并返回指向它的指针。
CreateRecordset (RDS) | 创建未连接的空 Recordset。
MoveFirst、MoveLast、MoveNext、MovePrevious (RDS) | 移动到指定的 Recordset 对象中的第一个、最后一个、下一个或上一个记录。
Query (RDS) | 使用有效的 SQL 查询字符串返回 Recordset。
Refresh (RDS) | 重新查询 Connect 属性中指定的数据源并更新查询结果。
Reset (RDS) | 根据指定的排序和过滤属性对客户端 Recordset 执行排序或过滤。
SubmitChanges (RDS) | 将本地缓存的可更新 Recordset 的挂起更改提交到 Connect 属性中指定的数据源。

© 1998-2002 Microsoft Corporation。保留所有权利。


Cancel 方法 (RDS)

取消执行挂起的异步方法调用。

语法

RDS.DataControl.Cancel

说明

调用 Cancel 时，ReadyState 将自动设置为 adcReadyStateLoaded，而 Recordset 将为空。

请参阅

VBScript 范例

Cancel 方法 | CancelBatch 方法 | CancelUpdate 方法 | CancelUpdate 方法 (RDS) | ExecuteOptions 属性 (RDS)

适用于：DataControl 对象 (RDS)


CancelUpdate 方法 (RDS)

取消对 Recordset 对象的当前行或新行所做的任何更改。

语法

DataControl.CancelUpdate

参数

DataControl
对象变量，表示 RDS.DataControl 对象。

说明

Cursor Service for OLE DB 将保持原值副本以及缓存的更改。当调用 CancelUpdate 时，缓存的更改被重置为空，并用原始数据刷新任何绑定控件。

请参阅

VBScript 范例

地址簿命令按钮 | Cancel 方法 | Cancel 方法 (RDS) | CancelBatch 方法 | CancelUpdate 方法 | Refresh 方法 (RDS) | SubmitChanges 方法 (RDS)

适用于：DataControl 对象 (RDS)


ConvertToString 方法 (RDS)

将 Recordset 转换为表示记录集数据的 MIME 字符串。

语法

DataFactory.ConvertToString(Recordset)

参数

DataFactory
对象变量，表示 RDSServer.DataFactory 对象。
Recordset
对象变量，表示 Recordset 对象。

说明

通过 .asp 文件，使用 ConvertToString 将 Recordset 嵌入到在服务器上生成的 HTML 页面中，从而将其传输到客户端计算机。

ConvertToString 先将 Recordset 加载到“Cursor Service”表，然后生成 MIME 格式的流。

在客户端，远程数据服务可以将 MIME 字符串转换回完全有效的 Recordset。它能很好地处理少于 400 行、每行不超过 1024 字节的数据。但它无法用于 BLOB 数据流和 HTTP 上的大的结果集。由于无法对字符串执行线压缩，因此与远程数据服务所定义并用于其原生传输协议格式的线优化图表格式相比较，在 HTTP 上传输庞大的数据集将花费大量的时间。

注意 如果要使用 Active Server Pages 将得到的 MIME 字符串嵌入客户端 HTML 页面，应注意早于 2.0 版本的 VBScript 版本会将字符串的大小限制在 32K。如果超过此限制，将返回错误。通过 .asp 文件使用 MIME 嵌入对象时应使用较小的查询范围。要改变这种情况，请从 Microsoft Windows Script Technologies Web 站点下载 VBScript 的最新版本。

请参阅

Visual Basic 范例 | VBScript 范例

Applies To: DataFactory 对象 (RDSServer)


CreateObject 方法 (RDS)

创建目标业务对象的代理并返回指向它的指针。代理把数据打包并调度到服务器端的通信模块，以便与业务对象通讯从而在 Internet 上发送请求和数据。对于进程内的组件对象则不使用代理，而只提供指向对象的指针。

语法

远程数据服务支持下列协议：HTTP、HTTPS（在 Secure Socket Layer 上的 HTTP）、DCOM 和 In-process。

协议 语法
HTTP
Set object = DataSpace.CreateObject("ProgId", "http://awebsrvr")
HTTPS
Set object = DataSpace.CreateObject("ProgId", "https://awebsrvr")
DCOM
Set object = DataSpace.CreateObject("ProgId", "computername")
In-process
Set object = DataSpace.CreateObject("ProgId", "")

参数

Object
对象变量，计算 ProgID 中指定类型的对象。
DataSpace
对象变量，表示用于创建新对象实例的 RDS.DataSpace 对象。
ProgID
String 值，包含指定服务器端业务对象的编程标识符，服务器端业务对象实现用户应用程序的业务规则。
awebsrvr 或 computername
String 值，表示标识创建服务器业务对象实例的 Internet Information Services (IIS) Web 服务器的 URL。

说明

HTTP 协议是标准 Web 协议；HTTPS 是安全 Web 协议；DCOM 协议在运行无 HTTP 的局域网时使用；In-process 协议是本地的动态链接库 (DLL)，它不使用网络。

请参阅

DataFactory 对象、Query 方法和 CreateObject 方法范例 (VBScript) | DataSpace 对象和 CreateObject 方法范例 (VBScript)

CreateRecordset 方法 (RDS)

应用于：DataSpace 对象 (RDS)


CreateRecordset 方法 (RDS)

创建未连接的空 Recordset。

语法

object.CreateRecordset(ColumnInfos)

参数

Object
对象变量，表示 RDSServer.DataFactory 对象或 RDS.DataControl 对象。
ColumnsInfos
属性的 Variant 数组，定义创建的 Recordset 的每一列。每一列的定义都包含四个所需属性和一个可选属性的数组。
属性 | 说明
Name | 列标题的名称。
Type | 整型数据类型。
Size | 表示宽度的整数，以字符为单位，与数据类型无关。
Nullability | Boolean 值。
Scale
（可选） 		此可选属性定义数字字段的范围。如果没有指定此值，则数值将被截断到小数点后三位。精度将不会受到影响，但是小数点后的位数将被截断到三位。

随后列数组的集合被组合为一个数组，用以定义 Recordset。

说明

服务器端业务对象可以使用来自非 OLE DB 数据提供者（例如包含股票报价的交易系统文件）的数据预置产生的 Recordset。

下表列出了 CreateRecordset 方法支持的 DataTypeEnum 值。所列编号是用于定义字段的引用编号。

每种数据类型可以是定长或变长。定长类型的大小应定义为 -1，因为其大小已预先确定而此处仍需要其大小的定义。变长数据类型大小的允许范围从 1 到 32767。

对于某些变长数据类型，可以强制为在“替换”列中注明的类型。只有在创建和填充 Recordset 之后才能查看替换。此后如有必要，可以检查实际数据类型。

长度 | 常量 | 编号 | 替换
定长 | adTinyInt | 16 |
定长 | adSmallInt | 2 |
定长 | adInteger | 3 |
定长 | adBigInt | 20 |
定长 | adUnsignedTinyInt | 17 |
定长 | adUnsignedSmallInt | 18 |
定长 | adUnsignedInt | 19 |
定长 | adUnsignedBigInt | 21 |
定长 | adSingle | 4 |
定长 | adDouble | 5 |
定长 | adCurrency | 6 |
定长 | adDecimal | 14 |
定长 | adNumeric | 131 |
定长 | adBoolean | 11 |
定长 | adError | 10 |
定长 | adGuid | 72 |
定长 | adDate | 7 |
定长 | adDBDate | 133 |
定长 | adDBTime | 134 |
定长 | adDBTimestamp | 135 | 7
变长 | adBSTR | 8 | 130
变长 | adChar | 129 | 200
变长 | adVarChar | 200 |
变长 | adLongVarChar | 201 | 200
变长 | adWChar | 130 |
变长 | adVarWChar | 202 | 130
变长 | adLongVarWChar | 203 | 130
变长 | adBinary | 128 |
变长 | adVarBinary | 204 |
变长 | adLongVarBinary | 205 | 204

请参阅

Visual Basic 范例 | VBScript 范例

CreateObject 方法 (RDS)

应用于：DataControl 对象 (RDS) | DataFactory 对象 (RDSServer)


MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法 (RDS)

移动到指定的 Recordset 对象中的第一个、最后一个、下一个或上一个记录。

语法

DataControl.Recordset.{MoveFirst | MoveLast | MoveNext | MovePrevious}

参数

DataControl
对象变量，表示 RDS.DataControl 对象。

说明

可以对 RDS.DataControl 对象使用 Move 方法，以便定位 Web 页上数据绑定控件中的数据记录。例如，假设通过绑定到 RDS.DataControl 对象来显示网格中的 Recordset。那么就可以将 First、Last、Next 和 Previous 按钮包括进来，使用户可以单击这些按钮移动到所显示的 Recordset 中的第一个、最后一个、下一个和上一个记录。针对 First、Last、Next 和 Previous 按钮，可在 onClick 过程中通过分别调用 RDS.DataControl 对象的 MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法来实现。地址簿范例显示如何完成这项工作。

请参阅

Move 方法 | MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法 | MoveRecord 方法

适用于：DataControl 对象 (RDS)


Query 方法 (RDS)

使用有效的 SQL 查询字符串返回 Recordset。

语法

Set Recordset = DataFactory.Query(Connection, Query)

参数

Recordset
对象变量，表示 Recordset 对象。
DataFactory
对象变量，表示 RDSServer.DataFactory 对象。
Connection
String 值，包含服务器连接信息。类似于 Connect 属性。
Query
String，包含 SQL 查询。

说明

查询应使用数据库服务器的 SQL 方言。如果执行的查询中包含错误，将返回一个结果状态。Query 方法不对 Query 字符串执行任何语法检查。

请参阅

VBScript 范例

适用于：DataFactory 对象 (RDSServer)


Refresh 方法 (RDS)

重新查询 Connect 属性中指定的数据源并更新查询结果。

语法

DataControl.Refresh

参数

DataControl
对象变量，表示 RDS.DataControl 对象。

说明

在使用 Refresh 方法之前，必须先设置 Connect、Server 和 SQL 属性。与 RDS.DataControl 对象相关联的格式中的所有数据绑定控件都将反映新记录集。所有预先存在的 Recordset 对象都将被释放，所有未保存的更改也将被放弃。Refresh 方法自动使第一个记录成为当前记录。

处理数据时，最好定期调用 Refresh 方法。如果检索数据并将其暂时留在客户端机器上，数据很可能会过时。您所做的所有更改可能将失败，因为也许别人已在您之前更改了记录并提交了更改。

请参阅

Visual Basic 范例 | VBScript 范例

地址簿命令按钮 | CancelUpdate 方法 (RDS) | Refresh 方法 | SubmitChanges 方法 (RDS)

适用于：DataControl 对象 (RDS)


Reset 方法 (RDS)

基于指定的排序和过滤属性对客户端 Recordset 执行排序或过滤。

语法

DataControl.Reset(value)

参数

DataControl
对象变量，表示 RDS.DataControl 对象。
value
可选。Boolean 值，如果要过滤当前“已过滤”的行集合，此值为 True（默认值）。False 指示对原始行集合进行过滤，删除所有先前的过滤选项。

说明

SortColumn、SortDirection、FilterValue、FilterCriterion 和 FilterColumn 属性提供在客户端缓存上的排序和过滤功能。排序功能按一个列中的值对记录进行排序。过滤功能基于查找条件显示记录的子集，而整个 Recordset 仍保存在缓存中。Reset 方法将执行查找标准并用可更新的 Recordset 替换当前的 Recordset。

如果尚未提交对原始数据所做的更改，Reset 方法将失败。首先，用 SubmitChanges 方法保存在读/写 Recordset 中所做的所有更改，然后用 Reset 方法排序或过滤记录。

如果要在行集合中执行多次过滤，可以使用 Reset 方法的可选 Boolean 参数。下列范例说明操作的步骤：

ADC.SQL = "Select au_lname from authors"
ADC.Refresh    ' Get the new rowset.

ADC.FilterColumn = "au_lname"
ADC.FilterCriterion = "<"
ADC.FilterValue = "'M'"
ADC.Reset         ' Rowset now has all Last Names < "M".

ADC.FilterCriterion = ">"
ADC.FilterValue = "'F'"
' Passing True is not necessary, because it is the
' default filter on the current "filtered" rowset.
ADC.Reset(TRUE)     ' Rowset now has all Last
                    ' Names < "M" and > "F".

ADC.FilterCriterion = ">"
ADC.FilterValue = "'T'"
' Filter on the original rowset, throwing out the
' previous filter options.
ADC.Reset(FALSE)   ' Rowset now has all Last Names > "T".

请参阅

VBScript 范例

SubmitChanges 方法 (RDS)

适用于：DataControl 对象 (RDS)


SubmitChanges 方法 (RDS)

将在本地缓存且可更新的 Recordset 的挂起更改提交到 Connect 属性或 URL 属性中指定的数据源。

语法

DataControl.SubmitChanges
DataFactory.SubmitChanges Connection, Recordset

参数

DataControl
对象变量，表示 RDS.DataControl 对象。
DataFactory
对象变量，表示 RDSServer.DataFactory 对象。
Connection
String 值，表示用 RDS.DataControl 对象的 Connect 属性创建的连接。
Recordset
对象变量，表示 Recordset 对象。

说明

必须先设置 Connect、Server 和 SQL 属性，然后才可以在 RDS.DataControl 对象中使用 SubmitChanges 方法。

如果在调用 SubmitChanges 后再调用同一 Recordset 对象的 CancelUpdate 方法，CancelUpdate 调用将失败，因为更改已被提交。

只发送更改过的记录供修改。要么所有更改都成功，要么所有更改都失败。

只可以对默认的 RDSServer.DataFactory 对象使用 SubmitChanges。自定义业务对象不能使用此方法。

如果已设置 URL 属性，则 SubmitChanges 将更改提交到由 URL 指定的位置。

请参阅

VBScript 范例

地址簿命令按钮 | CancelUpdate 方法 (RDS) | Refresh 方法 (RDS)

适用于：DataControl 对象 (RDS) | DataFactory 对象 (RDSServer)


RDS 事件

onError (RDS) | 在操作期间出现错误时调用。
onReadyStateChange (RDS) | 在 ReadyState 属性的值更改时调用。


onError 事件 (RDS)

onError 事件在操作期间发生错误时调用。

语法

onError SCode, Description, Source, CancelDisplay

参数

SCode
整数，指示错误的状态代码。
Description
String，指示错误的说明。
Source
String，指示引发错误的查询或命令。
CancelDisplay
Boolean 值，如果将其设置为 True，可使错误不显示在对话框中。

请参阅

Visual C++ 范例

ADO 事件处理程序汇总

应用于：DataControl 对象 (RDS)


onReadyStateChange 事件 (RDS)

onReadyStateChange 事件在 ReadyState 属性的值发生变化时调用。

语法

onReadyStateChange

参数

无

说明

当 RDS.DataControl 对象将数据异步检索到其 Recordset 对象中时，ReadyState 属性反映 RDS.DataControl 对象的进度。使用 onReadyStateChange 事件可随时监视 ReadyState 属性的变化。这比定期检查属性的值更为有效。

请参阅

Visual C++ 范例

ADO 事件处理程序汇总

应用于：DataControl 对象 (RDS)


RDS 代码范例

通过下列代码范例来学习如何使用 RDS 对象、方法、属性和事件。

注意 请将整个代码范例粘贴到代码编辑器中。如果只使用部分范例或者丢失了段落格式，范例可能无法正确运行。
  • Microsoft Visual Basic 中的 RDS 代码范例
  • Microsoft Visual Basic Scripting Edition 中的 RDS 代码范例
  • Microsoft Visual C++ 中的 RDS 代码范例
  • Microsoft Visual J++ 中的 RDS 代码范例


Microsoft Visual Basic 中的 RDS 代码范例

通过下列代码范例来学习用 Visual Basic 编程时如何使用 RDS 属性。

注意 请将 Sub 和 End Sub 之间的整个代码范例粘贴到您的代码编辑器中。如果只使用部分范例或者丢失了段落格式，范例可能无法正确运行。

Properties

  • Handler 属性范例
  • InternetTimeout 属性范例


Handler 属性范例 (VB)

本范例演示 RDS DataControl 对象的 Handler 属性。（有关详细信息，请参阅 DataFactory 自定义。）

假设在服务器上的参数文件 Msdfmap.ini 中有下列部分：

[connect AuthorDataBase]
Access=ReadWrite
Connect="DSN=Pubs"
[sql AuthorById]
SQL="SELECT * FROM Authors WHERE au_id = ?"

用户代码如下。分配给 SQL 属性的命令将与 AuthorById 标识符匹配，并将检索作者 Michael O'Leary 的行。将 DataControl 对象 Recordset 属性分配给断开连接的 Recordset 对象只是为了便于编码。

'BeginHandlerVB

Public Sub Main()

On Error GoTo ErrorHandler

Dim dc As New DataControl

Dim rst As ADODB.Recordset

dc.Handler = "MSDFMAP.Handler"

dc.ExecuteOptions = 1

dc.FetchOptions = 1

dc.Server = "http://MyServer"

dc.Connect = "Data Source=AuthorDataBase"

dc.SQL = "AuthorById('267-41-2394')"

dc.Refresh 'Retrieve the record

Set rst = dc.Recordset 'Use another Recordset as a convenience

Debug.Print "Author is '" & rst!au_fname & " " & rst!au_lname & "'"

' clean up

If rst.State = adStateOpen Then rst.Close

Set rst = Nothing

Set dc = Nothing

Exit Sub

ErrorHandler:

' clean up

If Not rst Is Nothing Then

If rst.State = adStateOpen Then rst.Close

End If

Set rst = Nothing

Set dc = Nothing

If Err <> 0 Then

MsgBox Err.Source & "-->" & Err.Description, , "Error"

End If

End Sub

'EndHandlerVB

请参阅

DataControl 对象 (RDS) | Handler 属性 (RDS)


InternetTimeout 属性范例 (VB)

本范例演示 InternetTimeout 属性，DataControl 和 DataSpace 对象具有该属性。本范例使用 DataControl 对象，并将超时设置为 20 秒。

'BeginInternetTimeoutVB

Public Sub Main()

On Error GoTo ErrorHandler

Dim dc As RDS.DataControl

Dim rst As ADODB.Recordset

Set dc = New RDS.DataControl

dc.Server = "http://MyServer"

dc.ExecuteOptions = 1

dc.FetchOptions = 1

dc.Connect = "Provider='sqloledb';Data Source='MySqlServer';" & _

"Initial Catalog='Pubs';Integrated Security='SSPI';"

dc.SQL = "SELECT * FROM Authors"

' Wait at least 20 seconds

dc.InternetTimeout = 200

dc.Refresh

' Use another Recordset as a convenience

Set rst = dc.Recordset

Do While Not rst.EOF

Debug.Print rst!au_fname & " " & rst!au_lname

rst.MoveNext

Loop

If rst.State = adStateOpen Then rst.Close

Set rst = Nothing

Set dc = Nothing

Exit Sub

ErrorHandler:

' clean up

If Not rst Is Nothing Then

If rst.State = adStateOpen Then rst.Close

End If

Set rst = Nothing

Set dc = Nothing

If Err <> 0 Then

MsgBox Err.Source & "-->" & Err.Description, , "Error"

End If

End Sub

'EndInternetTimeoutVB

请参阅

DataControl 对象 (RDS) | DataSpace 对象 (RDS) | InternetTimeout 属性 (RDS)


Microsoft Visual Basic Scripting Edition 中的 RDS 代码范例

通过下列代码范例来学习用 Visual Basic Scripting Edition (VBScript) 编程时如何使用 RDS 对象、方法和属性。

注意 请将整个代码范例粘贴到代码编辑器中。如果只使用部分范例或者丢失了段落格式，范例可能无法正确运行。

对象

  • DataControl 对象范例
  • DataSpace 对象范例
  • DataFactory 对象范例

方法

  • Cancel 方法范例
  • CancelUpdate 方法范例
  • ConvertToString 方法范例
  • CreateObject 方法
  • CreateRecordset 方法范例
  • Query 方法范例
  • Refresh 方法范例
  • Reset 方法范例
  • SubmitChanges 方法范例

属性

  • Connect 属性范例
  • ExecuteOptions 和 FetchOptions 属性范例
  • FilterColumn、FilterCriterion、FilterValue、SortColumn 和 SortDirection 属性范例
  • ReadyState 属性范例
  • Recordset 和 SourceRecordset 属性范例
  • Server 属性范例
  • SQL 属性范例
  • URL 属性范例


Cancel 方法范例 (VBScript)

以下范例显示如何在运行时读取 Cancel 方法。请将下列代码剪切并粘贴到记事本或其他文本编辑器中，并将其另存为 CancelVBS.asp。可以在任何客户端浏览器中查看结果。

<!-- BeginCancelVBS -->

<Script Language="VBScript">

<!--

Sub cmdCancelAsync_OnClick

' Terminates currently running AsyncExecute,

' ReadyState property set to adcReadyStateLoaded,

' Recordset set to Nothing

ADC.Cancel

End Sub

Sub cmdRefreshTable_OnClick

ADC.Refresh

End Sub

-->

</Script>

<OBJECT CLASSID="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" ID="ADC">

.

<PARAM NAME="SQL" VALUE="Select FirstName, LastName from Employees">

<PARAM NAME="CONNECT" VALUE="Provider='sqloledb';Integrated Security='SSPI';Initial Catalog='Northwind'">

<PARAM NAME="Server" VALUE="http://<%=Request.ServerVariables("SERVER_NAME")%>">

.

</OBJECT>

<TABLE DATASRC=#ADC>

<TBODY>

<TR>

<TD><SPAN DATAFLD="FirstName"></SPAN></TD>

<TD><SPAN DATAFLD="LastName"></SPAN></TD>

</TR>

</TBODY>

</TABLE>

<FORM>

<INPUT type="button" value="Refresh" id=cmdRefreshTable name=cmdRefreshTable>

<INPUT type="button" value="Cancel" id=cmdCancelAsync name=cmdCancelAsync>

</FORM>

<!-- EndCancelVBS -->

请参阅

Cancel 方法


CancelUpdate 方法范例 (VBScript)

要测试本范例，请将此代码剪切并粘贴到标准 HTML 文档的 <Body> 和 </Body> 标记之间，然后将其命名为 CancelUpdateVBS.asp。ASP 脚本将标识 Internet 服务器。您需要编辑该服务器的名称以反映自己的设置。仅更改从 MyServer 到 SQL Server 安装名称的连接字符串中的值。

<!-- BeginCancelUpdateVBS -->

<%@Language=VBScript%>

<%'Option Explicit%>

<% 'use the following META tag instead of adovbs.inc%>

<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<HTML>

<HEAD>

<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">

<TITLE></TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>Remote Data Service</H1>

<H2>SubmitChanges and CancelUpdate Methods</H2>

<% ' to integrate/test this code replace the Server property value and

' the Data Source value in the Connect property with appropriate values%>

<HR>

<OBJECT ID=RDS classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" HEIGHT=1 WIDTH=1></OBJECT>

<SCRIPT Language="VBScript">

'set RDS properties for control just created

RDS.Server = "http://<%=Request.ServerVariables("SERVER_NAME")%>"

RDS.SQL = "Select * from Employees"

RDS.Connect = "Provider='sqloledb';Integrated Security='SSPI';Initial Catalog='Northwind';"

RDS.Refresh

</SCRIPT>

<TABLE DATASRC=#RDS>

<THEAD>

<TR ID="ColHeaders">

<TH>ID</TH>

<TH>FName</TH>

<TH>LName</TH>

<TH>Title</TH>

<TH>Hire Date</TH>

<TH>Birth Date</TH>

<TH>Extension</TH>

<TH>Home Phone</TH>

</TR>

</THEAD>

<TBODY>

<TR>

<TD> <INPUT DATAFLD="EmployeeID" size=4> </TD>

<TD> <INPUT DATAFLD="FirstName" size=10> </TD>

<TD> <INPUT DATAFLD="LastName" size=10> </TD>

<TD> <INPUT DATAFLD="Title" size=10> </TD>

<TD> <INPUT DATAFLD="HireDate" size=10> </TD>

<TD> <INPUT DATAFLD="BirthDate" size=10> </TD>

<TD> <INPUT DATAFLD="Extension" size=10> </TD>

<TD> <INPUT DATAFLD="HomePhone" size=8> </TD>

</TR>

</TBODY>

</TABLE>

<HR>

<INPUT TYPE=button NAME="SubmitChange" VALUE="Submit Changes">

<INPUT TYPE=button NAME="CancelChange" VALUE="Cancel Update">

<BR>

<H4>Alter a current entry on the grid. Move off that Row. <BR>

Submit the Changes to your DBMS or cancel the updates. </H4>

</CENTER>

<SCRIPT Language="VBScript">

Sub SubmitChange_OnClick

msgbox "Changes will be made"

RDS.SubmitChanges

RDS.Refresh

End Sub

Sub CancelChange_OnClick

msgbox "Changes will be cancelled"

RDS.CancelUpdate

RDS.Refresh

End Sub

-->

</SCRIPT>

</BODY>

</HTML>

<!-- EndCancelUpdateVBS -->

请参阅

CancelUpdate 方法


Connect 属性范例 (VBScript)

此代码显示在设计时设置 Connect 属性的方式：

<OBJECT CLASSID="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" ID="ADC1">
.
   <PARAM NAME="SQL" VALUE="Select * from Sales">
   <PARAM NAME="CONNECT" VALUE="Provider=SQLOLEDB;Integrated Security=SSPI;Initial Catalog=Pubs">
   <PARAM NAME="Server" VALUE="http://MyWebServer">
.
</OBJECT>

以下范例显示以 VBScript 代码在运行时设置 Connect 属性的方式。

要测试本范例，请将此代码剪切并粘贴到标准 HTML 文档的 <Body> 和 </Body> 标记之间，并将其命名为 ConnectVBS.asp。ASP 脚本将标识用户服务器。

<!-- BeginConnectVBS -->

<%@ Language=VBScript %>

<HTML>

<HEAD>

<title>ADO Connect Property</title>

<%' local style sheet used for display%>

<STYLE>

<!--

BODY {

font-family: 'Verdana','Arial','Helvetica',sans-serif;

BACKGROUND-COLOR:white;

COLOR:black;

}

.tbody {

text-align: center;

background-color: #f7efde;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

}

-->

</STYLE>

</HEAD>

<BODY>

<h1>ADO Connect Property (RDS)</h1>

<HR>

<H3>Set Connect Property at Run Time</H3>

<% ' RDS.DataControl with no parameters set at design time %>

<OBJECT classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" ID=RDS HEIGHT=1 WIDTH=1></OBJECT>

<% ' Bind table to control for data display %>

<TABLE DATASRC=#RDS>

<TBODY>

<TR class="tbody">

<TD><SPAN DATAFLD="FirstName"></SPAN></TD>

<TD><SPAN DATAFLD="LastName"></SPAN></TD>

</TR>

</TBODY>

</TABLE>

<FORM name="frmInput">

SERVER: <INPUT Name="txtServer" Size="103" Value="http://<%=Request.ServerVariables("SERVER_NAME")%>"><BR>

DATA SOURCE: <INPUT Name="txtDataSource" Size="93" Value="<%=Request.ServerVariables("SERVER_NAME")%>"><BR>

CONNECT: <INPUT Name="txtConnect" Size="100"><BR>

SQL: <INPUT Name="txtSQL" Size="110" Value="Select FirstName, LastName from Employees">

<BR>

<INPUT TYPE=BUTTON NAME="Run" VALUE="Run">

<h4>

To make data grid appear, click 'Run' to see the connect string in text box above.

</h4>

</FORM>

<Script Language="VBScript">

' Set parameters of RDS.DataControl at Run Time

Sub Run_OnClick

Dim Cnxn

' build connection string

Cnxn = "Provider='sqloledb';"

Cnxn = Cnxn & "Data Source="

Cnxn = Cnxn & document.frmInput.txtDataSource.value & ";"

Cnxn = Cnxn & "Initial Catalog='Northwind';"

Cnxn = Cnxn & "Integrated Security='SSPI';"

' assign the value

document.frmInput.txtConnect.value = Cnxn

MsgBox "Here we go!"

' set RDS properties

RDS.Server = document.frmInput.txtServer.value

RDS.SQL = document.frmInput.txtSQL.value

RDS.Connect = document.frmInput.txtConnect.value

RDS.Refresh

End Sub

</Script>

</BODY>

</HTML>

<!-- EndConnectVBS -->

请参阅

Connect 属性 (RDS)


ConvertToString 方法范例 (VBScript)

以下范例显示如何用 RDSServer.DataFactory ConvertToString 方法将 Recordset 转换成 MIME 编码字符串，以及如何将该字符串转换回 Recordset。请将下列代码剪切并粘贴到记事本或其他文本编辑器中，并将其保存为 ConvertToString.htm。

<!-- BeginConvertToStringVBS -->

<HTML>

<HEAD><TITLE>ConvertToString Example</TITLE><HEAD>

<BODY>

<SCRIPT LANGUAGE=VBSCRIPT>

Sub ConvertToStringX()

Dim objRs, objDF, strServer, vString

Const adcExecSync = 1

Const adcFetchUpFront = 1

' Replace value below with your server name to use without ASP.

strServer = "http://<%=Request.ServerVariables("SERVER_NAME")%>">

Set objDF = RDS1.CreateObject("RDSServer.DataFactory", strServer)

Set objRs = objDF.Query(txtConnect.Value,txtQueryRecordset.Value)

' convert Recordset to MIME encoded string

vString = objDF.ConvertToString(objRs)

' display MIME string for demo purposes

txtRS.value = vString

' convert MIME string back to useable ADO Recordset

' using RDS.DataControl

RDC1.SQL = vString

RDC1.ExecuteOptions = adcExecSync

RDC1.FetchOptions = adcFetchUpFront

RDC1.Refresh

MsgBox "RecordCount = " & RDC1.Recordset.RecordCount

End Sub

</SCRIPT>

Connect String:

<INPUT TYPE=Text NAME=txtConnect SIZE=50

VALUE="Provider=sqloledb;Initial Catalog=pubs;Integrated Security='SSPI';">

<BR>

Query:

<INPUT TYPE=Text NAME=txtQueryRecordset SIZE=50

VALUE="select * from authors">

<BR>

<INPUT TYPE=Button VALUE="ConvertToString" OnClick="ConvertToStringX()">

<BR>

MIME Encoded RS: <BR>

<TEXTAREA NAME=txtRS ROWS=15 COLS=50 WRAP=virtual></TEXTAREA>

<!-- RDS.DataSpace ID RDS1 -->

<OBJECT ID="RDS1" WIDTH=1 HEIGHT=1

CLASSID="CLSID:BD96C556-65A3-11D0-983A-00C04FC29E36">

</OBJECT>

<!-- RDS.DataControl ID RDC1 -->

<OBJECT ID="RDC1" WIDTH=1 HEIGHT=1

CLASSID="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33">

</OBJECT>

</BODY>

</HTML>

<!-- EndConvertToStringVBS -->

请参阅

ConvertToString 方法 (RDS) | Recordset 对象


CreateRecordset 方法范例 (VBScript)

本代码范例在服务器端创建 Recordset。它有两列，每列四行。请将下列代码剪切并粘贴到记事本或其他文本编辑器中，并将其另存为 CreateRecordsetVBS.asp。

<!-- BeginCreateRecordsetVBS -->

<%@ Language=VBScript %>

<html>

<head>

<meta name="VI60_DefaultClientScript" content=VBScript>

<meta name="GENERATOR" content="Microsoft Visual Studio 6.0">

<title>CreateRecordset Method Example (VBScript)</title>

<style>

<!--

body {

font-family: 'Verdana','Arial','Helvetica',sans-serif;

BACKGROUND-COLOR:white;

COLOR:black;

}

.thead {

background-color: #008080;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.thead2 {

background-color: #800000;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.tbody {

text-align: center;

background-color: #f7efde;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

}

-->

</style>

</head>

<body>

<OBJECT classid=clsid:BD96C556-65A3-11D0-983A-00C04FC29E33 height=1 id=DC1 width=1>

</OBJECT>

<h1>CreateRecordset Method Example (VBScript)</h1>

<script language = "vbscript">

' use the RDS.DataControl to create an empty recordset;

' takes an array of variants where every element is itself another

' array of variants, one for every column required in the recordset

' the elements of the inner array are the column's

' name, type, size, and nullability

Sub GetRS()

Dim Record(2)

Dim Field1(3)

Dim Field2(3)

Dim Field3(3)

' for each field, specify the name type, size, and nullability

Field1(0) = "Name" ' Column name.

Field1(1) = CInt(129) ' Column type.

Field1(2) = CInt(40) ' Column size.

Field1(3) = False ' Nullable?

Field2(0) = "Age"

Field2 (1) = CInt(3)

Field2 (2) = CInt(-1)

Field2 (3) = True

Field3 (0) = "DateOfBirth"

Field3 (1) = CInt(7)

Field3 (2) = CInt(-1)

Field3 (3) = True

' put all fields into an array of arrays

Record(0) = Field1

Record(1) = Field2

Record(2) = Field3

Dim NewRs

Set NewRS = DC1.CreateRecordset(Record)

Dim fields(2)

fields(0) = Field1(0)

fields(1) = Field2(0)

fields(2) = Field3(0)

' Populate the new recordset with data values.

Dim fieldVals(2)

' Use AddNew to add the records.

fieldVals(0) = "Joe"

fieldVals(1) = 5

fieldVals(2) = CDate(#1/5/96#)

NewRS.AddNew fields, fieldVals

fieldVals(0) = "Mary"

fieldVals(1) = 6

fieldVals(2) = CDate(#6/5/94#)

NewRS.AddNew fields, fieldVals

fieldVals(0) = "Alex"

fieldVals(1) = 13

fieldVals(2) = CDate(#1/6/88#)

NewRS.AddNew fields, fieldVals

fieldVals(0) = "Susan"

fieldVals(1) = 13

fieldVals(2) = CDate(#8/6/87#)

NewRS.AddNew fields, fieldVals

NewRS.MoveFirst

' Set the newly created and populated Recordset to

' the SourceRecordset property of the

' RDS.DataControl to bind to visual controls

Set DC1.SourceRecordset = NewRS

End Sub

</script>

<table datasrc="#DC1" align="center">

<thead>

<tr id="ColHeaders" class="thead2">

<th>Name</th>

<th>Age</th>

<th>D.O.B.</th>

</tr>

</thead>

<tbody class="tbody">

<tr>

<td><input datafld="Name" size=15 id=text1 name=text1> </td>

<td><input datafld="Age" size=25 id=text2 name=text2> </td>

<td><input datafld="DateOfBirth" size=25 id=text3 name=text3> </td>

</tr>

</tbody>

</table>

<input type = "button" onclick = "GetRS()" value="Go!">

</body>

</html>

<!-- EndCreateRecordsetVBS -->

请参阅

CreateRecordset 方法 (RDS) | Recordset 对象


DataControl 对象范例 (VBScript)

下列代码显示在设计时设置 RDS.DataControl 参数并将其绑定到数据识别控件上的方式。请将此代码剪切并粘贴到标准 HTML 文档的 <Body> 和 </Body> 标记之间，并将其命名为 DataControlDesignVBS.asp。ASP 脚本将标识用户服务器。

<!-- BeginDataControlDesignVBS -->

<%@ Language=VBScript %>

<HTML>

<HEAD>

<META name="VI60_DefaultClientScript" content=VBScript>

<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">

<title>RDS DataControl</title>

<%' local style sheet used for display%>

<STYLE>

<!--

BODY {

font-family: 'Verdana','Arial','Helvetica',sans-serif;

BACKGROUND-COLOR:white;

COLOR:black;

}

.thead {

background-color: #008080;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.thead2 {

background-color: #800000;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.tbody {

text-align: center;

background-color: #f7efde;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

}

-->

</STYLE>

</HEAD>

<BODY>

<H2>RDS API Code Examples</H2>

<HR>

<H3>Remote Data Service</H3>

<TABLE DATASRC=#RDS>

<TBODY>

<TR>

<TD><SPAN DATAFLD="FirstName"></SPAN></TD>

<TD><SPAN DATAFLD="LastName"></SPAN></TD>

</TR>

</TBODY>

</TABLE>

<!-- Remote Data Service with Parameters set at Design Time -->

<OBJECT classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33"

ID=RDS>

<PARAM NAME="SQL" VALUE="Select * from Employees for browse">

<PARAM NAME="SERVER" VALUE="http://<%=Request.ServerVariables("SERVER_NAME")%>">

<PARAM NAME="CONNECT" VALUE="Provider='sqloledb';Integrated Security='SSPI';Initial Catalog='Northwind'">

</OBJECT>

</BODY>

</HTML>

<!-- EndDataControlDesignVBS -->

以下范例显示在运行时设置必要的 RDS.DataControl 参数的方式。要测试本范例，请将此代码剪切并粘贴到标准 HTML 文档的 <Body> 和 </Body> 标记之间，并将其命名为 DataControlRuntimeVBS.asp。ASP 脚本将标识用户服务器。

<!-- BeginDataControlRuntimeVBS -->

<%@ Language=VBScript %>

<html>

<head>

<meta name="VI60_DefaultClientScript" content=VBScript>

<meta name="GENERATOR" content="Microsoft Visual Studio 6.0">

<title>Data Control Object Example (VBScript)</title>

<%' local style sheet used for display%>

<style>

<!--

body {

font-family: 'Verdana','Arial','Helvetica',sans-serif;

BACKGROUND-COLOR:white;

COLOR:black;

}

.thead {

background-color: #008080;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.thead2 {

background-color: #800000;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.tbody {

text-align: center;

background-color: #f7efde;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

}

-->

</style>

</head>

<body>

<h1>Data Control Object Example (VBScript)</h1>

<H2>RDS API Code Examples</H2>

<HR>

<H3>Remote Data Service Run Time</H3>

<TABLE DATASRC=#RDS>

<TBODY>

<TR>

<TD><SPAN DATAFLD="au_lname"></SPAN></TD>

<TD><SPAN DATAFLD="au_fname"></SPAN></TD>

</TR>

</TBODY>

</TABLE>

<% ' RDS.DataControl with no parameters set at design time %>

<OBJECT classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" ID=RDS HEIGHT=1 WIDTH=1></OBJECT>

<FORM name="frmInput">

<HR>

<Input Size="70" Name="txtServer" Value="http://<%=Request.ServerVariables("SERVER_NAME")%>"><BR>

<Input Size="100" Name="txtConnect" Value="Provider='sqloledb';Data Source=<%=Request.ServerVariables("SERVER_NAME")%>;Initial Catalog='Pubs';Integrated Security='SSPI';">

<BR>

<Input Size="70" Name="txtSQL" Value="Select * from Authors">

<HR>

<INPUT TYPE="BUTTON" NAME="Run" VALUE="Run"><BR>

<H4>Show grid with these values or change them to see data from another ODBC data source on your server</H4>

</FORM>

<Script Language="VBScript">

' Set parameters of RDS.DataControl at Run Time

Sub Run_OnClick

RDS.Server = document.frmInput.txtServer.Value

RDS.Connect = document.frmInput.txtConnect.Value

RDS.SQL = document.frmInput.txtSQL.Value

RDS.Refresh

End Sub

</Script>

</body>

</html>

<!-- EndDataControlRuntimeVBS -->

请参阅

DataControl 对象 (RDS)


DataSpace 对象和 CreateObject 方法范例 (VBScript)

下列范例显示如何将 RDS.DataSpace 的 CreateObject 方法与默认业务对象（RDSServer.DataFactory）配合使用。要测试本范例，请将此代码剪切并粘贴到标准 HTML 文档的 <Body> 和 </Body> 标记之间，然后将其命名为 DataSpaceVBS.asp。ASP 脚本将标识用户服务器。

<!-- BeginDataSpaceVBS -->

<html>

<head>

<!--use the following META tag instead of adovbs.inc-->

<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<meta name="VI60_DefaultClientScript" content=VBScript>

<meta name="GENERATOR" content="Microsoft Visual Studio 6.0">

<title>DataSpace Object and CreateObject Method Example (VBScript)</title>

<style>

<!--

body {

font-family: 'Verdana','Arial','Helvetica',sans-serif;

BACKGROUND-COLOR:white;

COLOR:black;

}

.thead {

background-color: #008080;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.thead2 {

background-color: #800000;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.tbody {

text-align: center;

background-color: #f7efde;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

}

-->

</style>

</head>

<body>

<h1>DataSpace Object and CreateObject Method Example (VBScript)</h1>

<H2>RDS API Code Examples</H2>

<HR>

<H3>Using Query Method of RDSServer.DataFactory</H3>

<!-- RDS.DataSpace ID rdsDS-->

<OBJECT ID="rdsDS" WIDTH=1 HEIGHT=1

CLASSID="CLSID:BD96C556-65A3-11D0-983A-00C04FC29E36">

</OBJECT>

<!-- RDS.DataControl with parameters set at run time -->

<OBJECT classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33"

ID=RDS WIDTH=1 HEIGHT=1>

</OBJECT>

<TABLE DATASRC=#RDS>

<TBODY>

<TR>

<TD><SPAN DATAFLD="FirstName"></SPAN></TD>

<TD><SPAN DATAFLD="LastName"></SPAN></TD>

</TR>

</TBODY>

</TABLE>

<HR>

<INPUT TYPE=BUTTON NAME="Run" VALUE="Run">

<H4>Click Run -

The <i>CreateObject</i> Method of the RDS.DataSpace Object Creates an instance of the RDSServer.DataFactory.

The <i>Query</i> Method of the RDSServer.DataFactory is used to bring back a Recordset.</H4>

<Script Language="VBScript">

Dim rdsDF

Dim strServer

Dim strCnxn

Dim strSQL

strServer = "http://<%=Request.ServerVariables("SERVER_NAME")%>"

strCnxn = "Provider='sqloledb';Data Source=" & _

"<%=Request.ServerVariables("SERVER_NAME")%>" & ";" & _

"Integrated Security='SSPI';Initial Catalog='Northwind';"

strSQL = "Select FirstName, LastName from Employees"

Sub Run_OnClick()

Dim rs

' Create Data Factory

Set rdsDF = rdsDS.CreateObject("RDSServer.DataFactory", strServer)

'Get Recordset

Set rs = rdsDF.Query(strCnxn, strSQL)

' Use RDS.DataControl to bind Recordset to data-aware Table above

RDS.SourceRecordset = rs

End Sub

</Script>

</body>

</html>

<!-- EndDataSpaceVBS -->

以下范例显示如何使用 CreateObject 方法来创建自定义业务对象 VbBusObj.VbBusObjCls 的实例。该范例还使用 Active Server Page 脚本来标识 Web 服务器的名称。

要查看完整的范例，请打开范例应用程序选择器，在“客户端层”列中选择“VBScript in Internet Explorer”，并在“中间层”列中选择“Custom Visual Basic Business Object”。

Sub Window_OnLoad()
   strServer = "http://<%=Request.ServerVariables("SERVER_NAME")%>"
   Set BO = ADS1.CreateObject("VbBusObj.VbBusObjCls", strServer)
   txtConnect.Value = "dsn=Pubs;uid=MyUserId;pwd=MyPassword;"
   txtGetRecordset.Value = "Select * From authors for Browse"
End Sub

请参阅

CreateObject 方法 (RDS) | DataSpace 对象 (RDS)


DataFactory 对象、Query 方法和 CreateObject 方法范例 (VBScript)

本范例使用 RDS.DataSpace 对象的 CreateObject 方法创建 RDSServer.DataFactory 对象。要测试本范例，请将此代码剪切并粘贴到标准 HTML 文档的 <Body> 和 </Body> 标记之间，并将其命名为 DataFactoryVBS.asp。ASP 脚本将标识用户服务器。

<!-- BeginDataFactoryVBS -->

<HTML>

<HEAD>

<!--use the following META tag instead of adovbs.inc-->

<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<META name="VI60_DefaultClientScript" Content="VBScript">

<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">

<TITLE>DataFactory Object, Query Method, and

CreateObject Method Example (VBScript)</TITLE>

<style>

<!--

body {

font-family: 'Verdana','Arial','Helvetica',sans-serif;

BACKGROUND-COLOR:white;

COLOR:black;

}

.thead {

background-color: #008080;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.thead2 {

background-color: #800000;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.tbody {

text-align: center;

background-color: #f7efde;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

}

-->

</style>

</HEAD>

<BODY>

<h1>DataFactory Object, Query Method, and

CreateObject Method Example (VBScript)</h1>

<H2>RDS API Code Examples</H2>

<HR>

<H3>Using Query Method of RDSServer.DataFactory</H3>

<!-- RDS.DataSpace ID RDS1-->

<OBJECT ID="RDS1" WIDTH=1 HEIGHT=1

CLASSID="CLSID:BD96C556-65A3-11D0-983A-00C04FC29E36">

</OBJECT>

<!-- RDS.DataControl with parameters

set at run time -->

<OBJECT classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33"

ID=RDS WIDTH=1 HEIGHT=1>

</OBJECT>

<TABLE DATASRC=#RDS>

<TBODY>

<TR>

<TD><SPAN DATAFLD="FirstName"></SPAN></TD>

<TD><SPAN DATAFLD="LastName"></SPAN></TD>

</TR>

</TBODY>

</TABLE>

<HR>

<INPUT TYPE=BUTTON NAME="Run" VALUE="Run">

<BR>

<H4>Click Run -

The <i>CreateObject</i> Method of the RDS.DataSpace Object Creates

an instance of the RDSServer.DataFactory;

The <i>Query</i> Method of the RDSServer.DataFactory is used

to bring back a Recordset. </H4>

<Script Language="VBScript">

Dim rdsDF

Dim strServer

Dim strCnxn

Dim strSQL

strServer = "http://<%=Request.ServerVariables("SERVER_NAME")%>"

strCnxn = "Provider='sqloledb';Integrated Security='SSPI';Initial Catalog='Northwind';"

strSQL = "Select FirstName, LastName from Employees"

Sub Run_OnClick()

' Create RDSServer.DataFactory Object

Dim rs

' Get Recordset

Set DF = RDS1.CreateObject("RDSServer.DataFactory", strServer)

Set rs = DF.Query(strCnxn, strSQL)

' Set parameters of RDS.DataControl at Run Time

RDS.Server = strServer

RDS.SQL = strSQL

RDS.Connect = strCnxn

RDS.Refresh

End Sub

</Script>

</BODY>

</HTML>

<!-- EndDataFactoryVBS -->

请参阅

CreateObject 方法 (RDS) | DataFactory 对象 (RDSServer) | DataSpace 对象 (RDS) | Query 方法 (RDS)


ExecuteOptions 和 FetchOptions 属性范例 (VBScript)

下列代码显示在设计时设置 ExecuteOptions 和 FetchOptions 属性的方式。如果不进行设置，那么 ExecuteOptions 将默认为 adcExecSync。此设置指示在调用 RDS.Refresh 方法时，该方法将在当前调用的线程上执行（即同步操作）。请将下列代码剪切并粘贴到记事本或其他文本编辑器中，并将其保存为 ExecuteOptionsDesignVBS.asp。

<!-- BeginExecuteOptionsDesignVBS -->

<%@ Language=VBScript %>

<html>

<head>

<meta name="VI60_DefaultClientScript" content=VBScript>

<meta name="GENERATOR" content="Microsoft Visual Studio 6.0">

<title>Design-time ExecuteOptions and FetchOptions Properties Example</title>

<style>

<!--

body {

font-family: 'Verdana','Arial','Helvetica',sans-serif;

BACKGROUND-COLOR:white;

COLOR:black;

}

.thead {

background-color: #008080;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.thead2 {

background-color: #800000;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.tbody {

text-align: center;

background-color: #f7efde;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

}

-->

</style>

</head>

<body>

<h2>Design-time <br> ExecuteOptions and FetchOptions Properties Example</h2>

<OBJECT CLASSID="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" ID=RDS height=1 width=1>

<PARAM NAME="SQL" VALUE="SELECT FirstName, LastName FROM Employees ORDER BY LastName">

<PARAM NAME="Connect" VALUE="Provider='sqloledb';Data Source=<%=Request.ServerVariables("SERVER_NAME")%>;Integrated Security='SSPI';Initial Catalog='Northwind'">

<PARAM NAME="Server" VALUE="http://<%=Request.ServerVariables("SERVER_NAME")%>">

<PARAM NAME="ExecuteOptions" VALUE="1">

<PARAM NAME="FetchOptions" VALUE="3">

</OBJECT>

<TABLE DATASRC=#RDS>

<TBODY>

<TR class="thead2">

<TH>First Name</TH>

<TH>Last Name</TH>

</TR>

<TR class="tbody">

<TD><SPAN DATAFLD="FirstName"></SPAN></TD>

<TD><SPAN DATAFLD="LastName"></SPAN></TD>

</TR>

</TBODY>

</TABLE>

</body>

</html>

<!-- EndExecuteOptionsDesignVBS -->

下列范例显示以 VBScript 代码在运行时设置 ExecuteOptions 和 FetchOptions 属性的方式。有关这些属性的实用范例，请参阅 Refresh 方法。请将下列代码剪切并粘贴到记事本或其他文本编辑器中，并将其保存为 ExecuteOptionsRuntimeVBS.asp。

<!-- BeginExecuteOptionsRuntimeVBS -->

<%@ Language=VBScript %>

<html>

<head>

<meta name="VI60_DefaultClientScript" content=VBScript>

<meta name="GENERATOR" content="Microsoft Visual Studio 6.0">

<title>Run-time ExecuteOptions and FetchOptions Properties Example</title>

<style>

<!--

body {

font-family: 'Verdana','Arial','Helvetica',sans-serif;

BACKGROUND-COLOR:white;

COLOR:black;

}

.thead {

background-color: #008080;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.thead2 {

background-color: #800000;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.tbody {

text-align: center;

background-color: #f7efde;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

}

-->

</style>

</head>

<body>

<h2>Run-time <br> ExecuteOptions and FetchOptions Properties Example</h2>

<OBJECT CLASSID="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" ID=RDS height=1 width=1>

<PARAM NAME="SQL" VALUE="SELECT FirstName, LastName FROM Employees ORDER BY LastName">

<PARAM NAME="Connect" VALUE="Provider='sqloledb';Data Source=<%=Request.ServerVariables("SERVER_NAME")%>;Integrated Security='SSPI';Initial Catalog='Northwind'">

<PARAM NAME="Server" VALUE="http://<%=Request.ServerVariables("SERVER_NAME")%>">

</OBJECT>

<TABLE DATASRC=#RDS>

<TBODY>

<TR class="thead2">

<TH>First Name</TH>

<TH>Last Name</TH>

</TR>

<TR class="tbody">

<TD><SPAN DATAFLD="FirstName"></SPAN></TD>

<TD><SPAN DATAFLD="LastName"></SPAN></TD>

</TR>

</TBODY>

</TABLE>

<Script Language="VBScript">

Const adcExecSync = 1

Const adcFetchAsynch = 3

Sub ExecuteHow

' set RDS properties at run-time

RDS1.ExecuteOptions = adcExecSync

RDS1.FetchOptions = adcFetchAsynch

RDS.Refresh

End Sub

</Script>

</body>

</html>

<!-- EndExecuteOptionsRuntimeVBS -->

请参阅

ExecuteOptions 属性 (RDS) | FetchOptions 属性 (RDS)


FilterColumn、FilterCriterion、FilterValue、SortColumn 和 SortDirection 属性以及 Reset 方法范例 (VBScript)

下列代码说明如何在设计时设置 RDS.DataControl Server 参数并用数据源将其绑定到数据识别 HTML 表。请将下列代码剪切并粘贴到记事本或其他文本编辑器中，并将其保存为 FilterColumnVBS.asp。

<!-- BeginFilterColumnVBS -->

<%@ Language=VBScript %>

<HTML>

<HEAD>

<META name="VI60_DefaultClientScript" Content="VBScript">

<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">

<TITLE>FilterColumn, FilterCriterion, FilterValue, SortColumn, and SortDirection

Properties and Reset Method Example (VBScript)</TITLE>

</HEAD>

<BODY>

<h1>FilterColumn, FilterCriterion, FilterValue, SortColumn, and SortDirection

Properties and Reset Method Example (VBScript)</h1>

<OBJECT classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" ID=RDS HEIGHT=1 WIDTH=1>

<PARAM NAME="SQL" VALUE="Select FirstName, LastName, Title, ReportsTo, Extension from Employees">

<PARAM NAME="Connect" VALUE="Provider='sqloledb';Data Source=<%=Request.ServerVariables("SERVER_NAME")%>;Integrated Security='SSPI';Initial Catalog='Northwind'">

<PARAM NAME="Server" VALUE="http://<%=Request.ServerVariables("SERVER_NAME")%>">

</OBJECT>

Sort Column: <SELECT NAME="cboSortColumn">

<OPTION VALUE=""></OPTION>

<OPTION VALUE=ID>ID</OPTION>

<OPTION VALUE=FirstName>FirstName</OPTION>

<OPTION VALUE=LastName>LastName</OPTION>

<OPTION VALUE=Title>Title</OPTION>

<OPTION VALUE=Title>ReportsTo</OPTION>

<OPTION VALUE=Phone>Extension</OPTION>

</SELECT>

<br>

Sort Direction: <SELECT NAME="cboSortDir">

<OPTION VALUE=""></OPTION>

<OPTION VALUE=TRUE>Ascending</OPTION>

<OPTION VALUE=FALSE>Descending</OPTION>

</SELECT>

<HR WIDTH="25%">

Filter Column: <SELECT NAME="cboFilterColumn">

<OPTION VALUE=""></OPTION>

<OPTION VALUE=FirstName>FirstName</OPTION>

<OPTION VALUE=LastName>LastName</OPTION>

<OPTION VALUE=Title>Title</OPTION>

<OPTION VALUE=Room>ReportsTo</OPTION>

<OPTION VALUE=Phone>Extension</OPTION>

</SELECT>

<br>

Filter Criterion: <SELECT NAME="cboCriterion">

<OPTION VALUE=""></OPTION>

<OPTION VALUE="=">=</OPTION>

<OPTION VALUE="&gt;">&gt;</OPTION>

<OPTION VALUE="&lt;">&lt;</OPTION>

<OPTION VALUE="&gt;=">&gt;=</OPTION>

<OPTION VALUE="&lt;=">&lt;=</OPTION>

<OPTION VALUE="&lt;&gt;">&lt;&gt;</OPTION>

</SELECT>

<br>

Filter Value: <INPUT NAME="txtFilterValue">

<HR WIDTH="25%">

<INPUT TYPE=BUTTON NAME=Clear VALUE="CLEAR ALL"> &nbsp;

<INPUT TYPE=BUTTON NAME=SortFilter VALUE="APPLY">

<HR>

<TABLE DATASRC=#RDS ID="DataTable">

<THEAD>

<TR>

<TH>FirstName</TH>

<TH>LastName</TH>

<TH>Title</TH>

<TH>Reports To</TH>

<TH>Extension</TH>

</TR>

</THEAD>

<TBODY>

<TR>

<TD><SPAN DATAFLD="FirstName"></SPAN></TD>

<TD><SPAN DATAFLD="LastName"></SPAN></TD>

<TD><SPAN DATAFLD="Title"></SPAN></TD>

<TD><SPAN DATAFLD="ReportsTo"></SPAN></TD>

<TD><SPAN DATAFLD="Extension"></SPAN></TD>

</TR>

</TBODY>

</TABLE>

<Script Language="VBScript">

<!--

Const adFilterNone = 0

Sub SortFilter_OnClick

Dim vCriterion

Dim vSortDir

Dim vSortCol

Dim vFilterCol

' The value of SortColumn will be the

' value of what the user picks in the

' cboSortColumn box.

vSortCol = cboSortColumn.options(cboSortColumn.selectedIndex).value

If(vSortCol <> "") then

RDS.SortColumn = vSortCol

End If

' The value of SortDirection will be the

' value of what the user specifies in the

' cboSortdirection box.

If (vSortCol <> "") then

vSortDir = cboSortDir.options(cboSortDir.selectedIndex).value

If (vSortDir = "") then

MsgBox "You must select a direction for the sort."

Exit Sub

Else

If vSortDir = "Ascending" Then vSortDir = "TRUE"

If vSortDir = "Descending" Then vSortDir = "FALSE"

RDS.SortDirection = vSortDir

End If

End If

' The value of FilterColumn will be the

' value of what the user specifies in the

' cboFilterColumn box.

vFilterCol = cboFilterColumn.options(cboFilterColumn.selectedIndex).value

If(vFilterCol <> "") then

RDS.FilterColumn = vFilterCol

End If

' The value of FilterCriterion will be the

' text value of what the user specifies in the

' cboCriterion box.

vCriterion = cboCriterion.options(cboCriterion.selectedIndex).value

If (vCriterion <> "") Then

RDS.FilterCriterion = vCriterion

End If

' txtFilterValue is a rich text box

' control. The value of FilterValue will be the

' text value of what the user specifies in the

' txtFilterValue box.

If (txtFilterValue.value <> "") Then

RDS.FilterValue = txtFilterValue.value

End If

' Execute the sort and filter on a client-side

' Recordset based on the specified sort and filter

' properties. Calling Reset refreshes the result set

' that is displayed in the data-bound controls to

' display the filtered, sorted recordset.

RDS.Reset

End Sub

Sub Clear_onClick()

'clear the HTML input controls

cboSortColumn.selectedIndex = 0

cboSortDir.selectedIndex = 0

cboFilterColumn.selectedIndex = 0

cboCriterion.selectedIndex = 0

txtFilterValue.value = ""

'clear the filter

RDS.FilterCriterion = ""

RDS.Reset(FALSE)

End Sub

-->

</Script>

</BODY>

</HTML>

<!-- EndFilterColumnVBS -->

请参阅

DataControl 对象 (RDS) | FilterColumn 属性 (RDS) | FilterCriterion 属性 (RDS) | FilterValue 属性 (RDS) | Reset 方法 (RDS) | SortColumn 属性 (RDS) | SortDirection 属性 (RDS)


ReadyState 属性范例 (VBScript)

下列范例显示在运行时以 VBScript 代码读取 RDS.DataControl 对象的 ReadyState 属性的方式。ReadyState 为只读属性。

要测试本范例，请将此代码剪切并粘贴到标准 HTML 文档中的 <Body> 和 </Body> 标记之间，并将其命名为 RDSReadySt.asp。使用 Find 定位 Adovbs.inc 文件，并将其放置在要使用的目录中。ASP 脚本将标识用户服务器。

<!-- BeginReadyStateVBS -->

<%@ Language=VBScript %>

<% 'use the following META tag instead of adovbs.inc%>

<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<html>

<head>

<meta name="VI60_DefaultClientScript" content=VBScript>

<meta name="GENERATOR" content="Microsoft Visual Studio 6.0">

<title>RDS.DataControl ReadyState Property</title>

<style>

<!--

body {

font-family: 'Verdana','Arial','Helvetica',sans-serif;

BACKGROUND-COLOR:white;

COLOR:black;

}

.thead {

background-color: #008080;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.thead2 {

background-color: #800000;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.tbody {

text-align: center;

background-color: #f7efde;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

}

-->

</style>

</head>

<body>

<H1>RDS.DataControl ReadyState Property</H1>

<H2>RDS API Code Examples </H2>

<HR>

<!-- RDS.DataControl with parameters set at design time -->

<OBJECT classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" ID=RDS>

<PARAM NAME="SQL" VALUE="Select * from Orders">

<PARAM NAME="SERVER" VALUE="http://<%=Request.ServerVariables("SERVER_NAME")%>">

<PARAM NAME="CONNECT" VALUE="Provider='sqloledb';Integrated Security='SSPI';Initial Catalog='Northwind'">

<PARAM NAME="ExecuteOptions" VALUE="2">

<PARAM NAME="FetchOptions" VALUE="3">

</OBJECT>

<TABLE DATASRC=#RDS>

<TBODY>

<TR>

<TD><SPAN DATAFLD="OrderID"></SPAN></TD>

</TR>

</TBODY>

</TABLE>

<Script Language="VBScript">

Sub Window_OnLoad

Select Case RDS.ReadyState

case 2 'adcReadyStateLoaded

MsgBox "Executing Query"

case 3 'adcReadyStateInteractive

MsgBox "Fetching records in background"

case 4 'adcReadyStateComplete

MsgBox "All records fetched"

End Select

End Sub

</Script>

</body>

</html>

<!-- EndReadyStateVBS -->

请参阅

DataControl 对象 (RDS) | ReadyState 属性 (RDS)


Recordset 和 SourceRecordset 属性范例 (VBScript)

下列范例说明如何在运行时设置必要的 RDSServer.DataFactory 默认业务对象的参数。

要测试本范例，请将此代码剪切并粘贴到标准 HTML 文档的 <Body> 和 </Body> 标记之间，并将其命名为 RecordsetVBS.asp。ASP 脚本将标识用户服务器。

<!-- BeginRecordSetVBS -->

<%@ Language=VBScript %>

<html>

<head>

<meta name="VI60_DefaultClientScript" content=VBScript>

<meta name="GENERATOR" content="Microsoft Visual Studio 6.0">

<title>Recordset and SourceRecordset Properties Example (VBScript)</title>

<style>

<!--

body {

font-family: 'Verdana','Arial','Helvetica',sans-serif;

BACKGROUND-COLOR:white;

COLOR:black;

}

.thead {

background-color: #008080;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.thead2 {

background-color: #800000;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.tbody {

text-align: center;

background-color: #f7efde;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

}

-->

</style>

</head>

<body>

<h1>Recordset and SourceRecordset Properties Example (VBScript)</h1>

<Center>

<H2>RDS API Code Examples</H2>

<HR>

<H3>Using SourceRecordset and Recordset with RDSServer.DataFactory</H3>

<!-- RDS.DataSpace ID RDS1 -->

<OBJECT ID="RDS1" WIDTH=1 HEIGHT=1

CLASSID="CLSID:BD96C556-65A3-11D0-983A-00C04FC29E36">

</OBJECT>

<!-- RDS.DataControl with parameters set at Run Time -->

<OBJECT classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33"

ID=RDC WIDTH=1 HEIGHT=1>

</OBJECT>

<TABLE DATASRC=#RDC>

<TR>

<TD> <INPUT DATAFLD="FirstName" SIZE=15> </TD>

<TD> <INPUT DATAFLD="LastName" SIZE=15></TD>

</TR>

</TABLE>

<HR>

<Input Size=70 Name="txtServer" Value="http://<%=Request.ServerVariables("SERVER_NAME")%>"><BR>

<Input Size=70 Name="txtConnect" Value="Provider='sqloledb';Integrated Security='SSPI';Initial Catalog='Northwind'"><BR>

<Input Size=70 Name="txtSQL" Value="SELECT FirstName, LastName FROM Employees">

<HR>

<INPUT TYPE=BUTTON NAME="Run" VALUE="Run"><BR>

</Center>

<Script Language="VBScript">

Dim rdsDF

Dim strServer

strServer = "http://<%=Request.ServerVariables("SERVER_NAME")%>"

Sub Run_OnClick()

Dim rs

' Create RDSServer.DataFactory Object

Set rdsDF = RDS1.CreateObject("RDSServer.DataFactory", strServer)

' Get Recordset

Set rs = rdsDF.Query(txtConnect.Value,txtSQL.Value)

' Set parameters of RDS.DataControl at run time

RDC.Server = txtServer.Value

RDC.SQL = txtSQL.Value

RDC.Connect = txtConnect.Value

RDC.Refresh

End Sub

</Script>

</body>

</html>

<!-- EndRecordsetVBS -->

请参阅

DataFactory 对象 (RDSServer) | Recordset 和 SourceRecordset 属性 (RDS)


Refresh 方法范例 (VBScript)

以下范例显示在运行时设置必要的 RDS.DataControl 参数的方式。使用 Refresh 方法检索 Recordset 的方式由 ExecuteOptions 和 FetchOptions 属性的设置确定。要测试本范例，请将下列代码剪切并粘贴到标准的 ASP 文档，并将其命名为 RefreshVBS.asp。使用 Find 定位 Adovbs.inc 文件，并将其放置在要使用的目录中。ASP 脚本将标识用户服务器。

<!-- BeginRefreshVBS -->

<%@ Language=VBScript %>

<!--use the following META tag instead of adovbs.inc-->

<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<html>

<head>

<meta name="VI60_DefaultClientScript" content=VBScript>

<meta name="GENERATOR" content="Microsoft Visual Studio 6.0">

<title>Refresh Method Example (VBScript)</title>

<style>

<!--

body {

font-family: 'Verdana','Arial','Helvetica',sans-serif;

BACKGROUND-COLOR:white;

COLOR:black;

}

.thead {

background-color: #008080;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.thead2 {

background-color: #800000;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.tbody {

text-align: center;

background-color: #f7efde;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

}

-->

</style>

</head>

<body>

<h1>Refresh Method Example (VBScript)</h1>

<H2>RDS API Code Examples </H2>

<HR>

<TABLE DATASRC=#RDC>

<TR>

<TD> <INPUT DATAFLD="FirstName" SIZE=15> </TD>

<TD> <INPUT DATAFLD="LastName" SIZE=15> </TD>

<TD> <INPUT DATAFLD="Title" SIZE=15> </TD>

<TD> <INPUT DATAFLD="HireDate" SIZE=15> </TD>

</TR>

</TABLE>

<!-- RDS.DataControl with no parameters set at design time -->

<OBJECT classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33"

ID=RDC HEIGHT=1 WIDTH=1>

</OBJECT>

<HR>

Server: <Input Size=70 Name="txtServer" Value="http://<%=Request.ServerVariables("SERVER_NAME")%>"><BR>

Connect: <Input Size=70 Name="txtConnect" Value="Provider='sqloledb';Integrated Security='SSPI';Initial Catalog='Northwind'"><BR>

SQL: <Input Size=70 Name="txtSQL" Value="Select * from Employees">

<HR>

<TABLE BORDER=1 WIDTH="60%">

<TR>

<TD COLSPAN=3 BGCOLOR=silver>

Choose if you want the Recordset brought back Synchronously on the

current calling thread or Asynchronously on another thread.

</TD>

</TR>

<TR>

<TD>Synchronously: <BR>

<Input Type="Radio" Name="optExecuteOptions" Checked OnClick="SetExO('adcExecSync')">

</TD>

<TD>Asynchronously: <BR>

<Input Type="Radio" Name="optExecuteOptions" OnClick="SetExO('adcExecAsync')">

</TD>

<TD>&nbsp;</TD>

</TR>

<TR>

<TD COLSPAN=3 BGCOLOR=silver>

Fetch Up Front, Background Fetch with Blocking or Background Fetch

without Blocking

</TD>

<TR>

<TD>Up Front:<BR>

<Input Type="Radio" Name="optFetchOptions" OnClick="SetFO('adcFetchUpFront')">

</TD>

<TD>Background w/ Blocking:<BR>

<Input Type="Radio" Name="optFetchOptions" Checked OnClick="SetFO('adcFetchBackground')">

</TD>

<TD>Background w/o Blocking:<BR>

<Input Type="Radio" Name="optFetchOptions" OnClick="SetFO('adcFetchAsync')">

</TD>

</TR>

</TABLE>

<INPUT TYPE=BUTTON NAME="Run" VALUE="Run"><BR>

<Script Language="VBScript">

<!--

Dim EO 'ExecuteOptions

Dim FO 'FetchOptions

EO = "adcExecSync" 'Default value

FO = "adcFetchBackground" 'Default value

Sub SetExO(NewEO)

EO = NewEO

End Sub

Sub SetFO(NewFO)

FO = NewFO

End Sub

' Set parameters of RDS.DataControl at Run Time

Sub Run_OnClick

RDC.Server = txtServer.Value

RDC.SQL = txtSQL.Value

RDC.Connect = txtConnect.Value

If EO = "adcExecSync" Then 'Determine which ExecuteOption chosen

RDC.ExecuteOptions = adcExecSync

MsgBox "Recordset brought in on current calling thread Syncronously"

Else

RDC.ExecuteOptions = adcExecAsync

MsgBox "Recordset brought in on another thread Asyncronously"

End If

If FO = "adcFetchBackground" Then 'Determine ‘which FetchOption chosen

RDC.FetchOptions = adcFetchBackground

MsgBox "Control goes back to user after first batch of records returned"

ElseIf FO = " adcFetchUpFront" Then

RDC.FetchOptions = adcFetchUpFront

MsgBox "All records returned before control goes back to user"

Else

RDC.FetchOptions = adcFetchAsync

MsgBox "Control goes back to user immediately"

End If

RDC.Refresh

End Sub

-->

</Script>

</body>

</html>

<!-- EndRefreshVBS -->

请参阅

DataControl 对象 (RDS) | ExecuteOptions 属性 (RDS) | FetchOptions 属性 (RDS) | Recordset 对象 | Refresh 方法


Server 属性范例 (VBScript)

下列代码说明如何在设计时设置 RDS.DataControl 参数并用 SQLOLEDB 提供者将其绑定到数据识别控件上。请将此代码剪切并粘贴到标准 ASP 文档中，并将其命名为 ServerDesignVBS.asp。ASP 脚本将标识用户服务器。

<!-- BeginServerDesignVBS -->

<%@ Language=VBScript %>

<html>

<head>

<meta name="VI60_DefaultClientScript" content=VBScript>

<meta name="GENERATOR" content="Microsoft Visual Studio 6.0">

<title>Server Property Example (VBScript)</title>

<style>

<!--

body {

font-family: 'Verdana','Arial','Helvetica',sans-serif;

BACKGROUND-COLOR:white;

COLOR:black;

}

.thead {

background-color: #008080;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.thead2 {

background-color: #800000;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.tbody {

text-align: center;

background-color: #f7efde;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

}

-->

</style>

</head>

<body>

<h1>Server Property Example (VBScript)</h1>

<TABLE DATASRC=#RDS>

<TR>

<TD> <SPAN DATAFLD="FirstName"></SPAN> </TD>

<TD> <SPAN DATAFLD="LastName"></SPAN> </TD>

<TD> <SPAN DATAFLD="Title"></SPAN> </TD>

<TD> <SPAN DATAFLD="Type"></SPAN> </TD>

<TD> <SPAN DATAFLD="Email"></SPAN> </TD>

</TR>

</TABLE>

<!-- Remote Data Service with Parameters set at Design Time -->

<OBJECT classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33"

ID=RDS HEIGHT=1 WIDTH=1>

<PARAM NAME="SQL" VALUE="Select * from Employees">

<PARAM NAME="SERVER" VALUE="http://<%=Request.ServerVariables("SERVER_NAME")%>">

<PARAM NAME="CONNECT" VALUE="Provider='sqloledb';Integrated Security='SSPI';Initial Catalog='Northwind'">

</OBJECT>

</body>

</html>

<!-- EndServerDesignVBS -->

以下范例显示在运行时设置必要的 RDS.DataControl 参数的方式。要测试本范例，请将此代码剪切并粘贴到标准 ASP 文档中，并将其命名为 ServerRuntimeVBS.asp。ASP 脚本将标识用户服务器。

<!-- BeginServerRuntimeVBS -->

<%@ Language=VBScript %>

<html>

<head>

<meta name="VI60_DefaultClientScript" content=VBScript>

<meta name="GENERATOR" content="Microsoft Visual Studio 6.0">

<title>Server Property Example (VBScript)</title>

<style>

<!--

body {

font-family: 'Verdana','Arial','Helvetica',sans-serif;

BACKGROUND-COLOR:white;

COLOR:black;

}

.thead {

background-color: #008080;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.thead2 {

background-color: #800000;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.tbody {

text-align: center;

background-color: #f7efde;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

}

-->

</style>

</head>

<body>

<h1>Server Property Example (VBScript)</h1>

<H2>RDS API Code Examples</H2>

<H3>Remote Data Service Server Property Set at Run Time</H3>

<!-- RDS.DataControl with no parameters set at design time -->

<OBJECT classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33"

ID=RDC HEIGHT=1 WIDTH=1>

</OBJECT>

<TABLE DATASRC=#RDC>

<TR>

<TD> <SPAN DATAFLD="FirstName"></SPAN> </TD>

<TD> <SPAN DATAFLD="LastName"></SPAN> </TD>

<TD> <SPAN DATAFLD="Title"></SPAN> </TD>

<TD> <SPAN DATAFLD="Type"></SPAN> </TD>

<TD> <SPAN DATAFLD="Email"></SPAN> </TD>

</TR>

</TABLE>

<HR>

<Input Size=70 Name="txtServer" Value="HTTP://<%= Request.ServerVariables("SERVER_NAME")%>">

<BR>

<Input Size=70 Name="txtConnect" Value="Provider='sqloledb';Integrated Security='SSPI';Initial Catalog='Northwind'">

<BR>

<Input Size=70 Name="txtSQL" Value="Select * from Employees">

<HR>

<INPUT TYPE=BUTTON NAME="Run" VALUE="Run"><BR>

<Script Language="VBScript">

<!--

' Set parameters of RDS.DataControl at Run Time

Sub Run_OnClick

RDC.Server = txtServer.Value

RDC.SQL = txtSQL.Value

RDC.Connect = txtConnect.Value

RDC.Refresh

End Sub

-->

</Script>

</body>

</html>

<!-- EndServerRuntimeVBS -->

DataControl 对象 (RDS) | Server 属性 (RDS)


SQL 属性范例 (VBScript)

下列代码说明如何在设计时设置 RDS.DataControl SQL 参数并使用 Microsoft SQL Server 附带的名为 Pubs 的数据库将其绑定到数据识别控件上。要测试该范例，请将下列代码复制到用户 Web 服务器上名为 SQLDesignVBS.asp 的标准 ASP 文档中。

<!-- BeginSQLDesignVBS -->

<%@ Language=VBScript %>

<html>

<head>

<meta name="VI60_DefaultClientScript" content=VBScript>

<meta name="GENERATOR" content="Microsoft Visual Studio 6.0">

<title>SQL Property Example (VBScript)</title>

<style>

<!--

body {

font-family: 'Verdana','Arial','Helvetica',sans-serif;

BACKGROUND-COLOR:white;

COLOR:black;

}

.thead {

background-color: #008080;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.thead2 {

background-color: #800000;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.tbody {

text-align: center;

background-color: #f7efde;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

}

-->

</style>

</head>

<body>

<h1>SQL Property Example (VBScript)</h1>

<!-- RDS.DataControl -->

<OBJECT classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" ID=RDC HEIGHT=1 WIDTH=1>

<PARAM NAME="SQL" VALUE="Select FirstName, LastName from Employees">

<PARAM NAME="SERVER" VALUE="http://<%=Request.ServerVariables("SERVER_NAME")%>">

<PARAM NAME="CONNECT" VALUE="Provider='sqloledb';Initial Catalog='Northwind';Integrated Security='SSPI';">

</OBJECT>

<!-- Data Table -->

<TABLE DATASRC=#RDC BORDER=1>

<TR>

<TD> <SPAN DATAFLD="FirstName"></SPAN> </TD>

<TD> <SPAN DATAFLD="LastName"></SPAN> </TD>

</TR>

</TABLE>

</body>

</html>

<!-- EndSQLDesignVBS -->

以下范例显示在运行时设置必要的 RDS.DataControl 参数的方式。要测试本范例，请将此代码剪切并粘贴到标准 ASP 文档中，并将其命名为 SQLRuntimeVBS.asp。ASP 脚本将标识用户服务器。

<!-- BeginServerRuntimeVBS -->

<%@ Language=VBScript %>

<html>

<head>

<meta name="VI60_DefaultClientScript" content=VBScript>

<meta name="GENERATOR" content="Microsoft Visual Studio 6.0">

<title>Server Property Example (VBScript)</title>

<style>

<!--

body {

font-family: 'Verdana','Arial','Helvetica',sans-serif;

BACKGROUND-COLOR:white;

COLOR:black;

}

.thead {

background-color: #008080;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.thead2 {

background-color: #800000;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.tbody {

text-align: center;

background-color: #f7efde;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

}

-->

</style>

</head>

<body>

<h1>Server Property Example (VBScript)</h1>

<H2>RDS API Code Examples</H2>

<H3>Remote Data Service Server Property Set at Run Time</H3>

<!-- RDS.DataControl with no parameters set at design time -->

<OBJECT classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33"

ID=RDC HEIGHT=1 WIDTH=1>

</OBJECT>

<TABLE DATASRC=#RDC>

<TR>

<TD> <SPAN DATAFLD="FirstName"></SPAN> </TD>

<TD> <SPAN DATAFLD="LastName"></SPAN> </TD>

<TD> <SPAN DATAFLD="Title"></SPAN> </TD>

<TD> <SPAN DATAFLD="Type"></SPAN> </TD>

<TD> <SPAN DATAFLD="Email"></SPAN> </TD>

</TR>

</TABLE>

<HR>

<Input Size=70 Name="txtServer" Value="HTTP://<%= Request.ServerVariables("SERVER_NAME")%>">

<BR>

<Input Size=70 Name="txtConnect" Value="Provider='sqloledb';Integrated Security='SSPI';Initial Catalog='Northwind'">

<BR>

<Input Size=70 Name="txtSQL" Value="Select * from Employees">

<HR>

<INPUT TYPE=BUTTON NAME="Run" VALUE="Run"><BR>

<Script Language="VBScript">

<!--

' Set parameters of RDS.DataControl at Run Time

Sub Run_OnClick

RDC.Server = txtServer.Value

RDC.SQL = txtSQL.Value

RDC.Connect = txtConnect.Value

RDC.Refresh

End Sub

-->

</Script>

</body>

</html>

<!-- EndServerRuntimeVBS -->

请参阅

DataControl 对象 (RDS) | SQL 属性 (RDS)


SubmitChanges 方法范例 (VBScript)

下列代码段显示在 RDS.DataControl 对象中使用 SubmitChanges 方法的方式。

要测试本范例，请将此代码剪切并粘贴到标准的 ASP 文档中，并将其命名为 SubmitChangesCtrlVBS.asp。ASP 脚本将标识用户服务器。

<!-- BeginCancelUpdateVBS -->

<%@Language=VBScript%>

<%'Option Explicit%>

<% 'use the following META tag instead of adovbs.inc%>

<!--METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->

<HTML>

<HEAD>

<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">

<TITLE></TITLE>

</HEAD>

<BODY>

<CENTER>

<H1>Remote Data Service</H1>

<H2>SubmitChanges and CancelUpdate Methods</H2>

<% ' to integrate/test this code replace the Server property value and

' the Data Source value in the Connect property with appropriate values%>

<HR>

<OBJECT ID=RDS classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33" HEIGHT=1 WIDTH=1></OBJECT>

<SCRIPT Language="VBScript">

'set RDS properties for control just created

RDS.Server = "http://<%=Request.ServerVariables("SERVER_NAME")%>"

RDS.SQL = "Select * from Employees"

RDS.Connect = "Provider='sqloledb';Integrated Security='SSPI';Initial Catalog='Northwind';"

RDS.Refresh

</SCRIPT>

<TABLE DATASRC=#RDS>

<THEAD>

<TR ID="ColHeaders">

<TH>ID</TH>

<TH>FName</TH>

<TH>LName</TH>

<TH>Title</TH>

<TH>Hire Date</TH>

<TH>Birth Date</TH>

<TH>Extension</TH>

<TH>Home Phone</TH>

</TR>

</THEAD>

<TBODY>

<TR>

<TD> <INPUT DATAFLD="EmployeeID" size=4> </TD>

<TD> <INPUT DATAFLD="FirstName" size=10> </TD>

<TD> <INPUT DATAFLD="LastName" size=10> </TD>

<TD> <INPUT DATAFLD="Title" size=10> </TD>

<TD> <INPUT DATAFLD="HireDate" size=10> </TD>

<TD> <INPUT DATAFLD="BirthDate" size=10> </TD>

<TD> <INPUT DATAFLD="Extension" size=10> </TD>

<TD> <INPUT DATAFLD="HomePhone" size=8> </TD>

</TR>

</TBODY>

</TABLE>

<HR>

<INPUT TYPE=button NAME="SubmitChange" VALUE="Submit Changes">

<INPUT TYPE=button NAME="CancelChange" VALUE="Cancel Update">

<BR>

<H4>Alter a current entry on the grid. Move off that Row. <BR>

Submit the Changes to your DBMS or cancel the updates. </H4>

</CENTER>

<SCRIPT Language="VBScript">

Sub SubmitChange_OnClick

msgbox "Changes will be made"

RDS.SubmitChanges

RDS.Refresh

End Sub

Sub CancelChange_OnClick

msgbox "Changes will be cancelled"

RDS.CancelUpdate

RDS.Refresh

End Sub

-->

</SCRIPT>

</BODY>

</HTML>

<!-- EndCancelUpdateVBS -->

请参阅

DataControl 对象 (RDS) | SubmitChanges 方法 (RDS)


URL 属性范例 (VBScript)

下列代码演示如何在客户端设置 URL 属性，以指定一个 .asp 文件依次处理对数据源的更改提交。

<!-- BeginURLClientVBS -->

<%@ Language=VBScript %>

<html>

<head>

<meta name="VI60_DefaultClientScript" content=VBScript>

<meta name="GENERATOR" content="Microsoft Visual Studio 6.0">

<title>URL Property Example (VBScript)</title>

<style>

<!--

body {

font-family: 'Verdana','Arial','Helvetica',sans-serif;

BACKGROUND-COLOR:white;

COLOR:black;

}

.thead {

background-color: #008080;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.thead2 {

background-color: #800000;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

color: white;

}

.tbody {

text-align: center;

background-color: #f7efde;

font-family: 'Verdana','Arial','Helvetica',sans-serif;

font-size: x-small;

}

-->

</style>

</head>

<body onload=Getdata()>

<h1>URL Property Example (VBScript)</h1>

<OBJECT classid=clsid:BD96C556-65A3-11D0-983A-00C04FC29E33 height=1 id=ADC width=1>

</OBJECT>

<table datasrc="#ADC" align="center">

<thead>

<tr id="ColHeaders" class="thead2">

<th>FirstName</th>

<th>LastName</th>

<th>Extension</th>

</tr>

</thead>

<tbody class="tbody">

<tr>

<td><input datafld="FirstName" size=15> </td>

<td><input datafld="LastName" size=25> </td>

<td><input datafld="Extension" size=15> </td>

</tr>

</tbody>

</table>

<script Language="VBScript">

Sub Getdata()

msgbox "getdata"

ADC.URL = "http://<%=Request.ServerVariables("SERVER_NAME")%>/URLServerVBS.asp"

ADC.Refresh

End Sub

</script>

</body>

</html>

<!-- EndURLClientVBS -->

存在于 URLServerVBS.asp 中的服务器端代码将向数据源提交更新的 Recordset。

<!-- BeginURLServerVBS -->

<%@ Language=VBScript %>

<%

' XML output req's

Response.ContentType = "text/xml"

const adPersistXML = 1

' recordset vars

Dim strSQL, rsEmployees

Dim strCnxn, Cnxn

strCnxn = "Provider='sqloledb';Data Source=" & _

Request.ServerVariables("SERVER_NAME") & ";" & _

"Integrated Security='SSPI';Initial Catalog='Northwind';"

Set Cnxn = Server.CreateObject("ADODB.Connection")

Set rsEmployees = Server.CreateObject("ADODB.Recordset")

strSQL = "SELECT FirstName, LastName, Extension FROM Employees"

Cnxn.Open strCnxn

rsEmployees.Open strSQL, Cnxn

' output as XML

rsEmployees.Save Response, adPersistXML

' Clean up

rsEmployees.Close

Cnxn.Close

Set rsEmployees = Nothing

Set Cnxn = Nothing

%>

<!-- EndURLServerVBS -->

请参阅

URL 属性 (RDS)


Microsoft Visual C++ 中的 RDS 代码范例

通过下列代码范例来学习用 Microsoft Visual C++ 编程时如何使用 RDS 属性。

注意 请将整个代码范例（从开始到结束）粘贴到代码编辑器中。如果只使用部分范例或者丢失了段落格式，范例可能无法正确运行。
  • Handler 属性范例
  • InternetTimeout 属性范例


Handler 属性范例 (VC++)

本范例演示 RDS DataControl 对象的 Handler 属性。（有关详细信息，请参阅 DataFactory 自定义。）

假设在服务器上的参数文件 Msdfmap.ini 中有下列部分：

[connect AuthorDataBase]
Access=ReadWrite
Connect="DSN=Pubs"
[sql AuthorById]
SQL="SELECT * FROM Authors WHERE au_id = ?"

用户代码如下。分配给 SQL 属性的命令将与 AuthorById 标识符匹配，并将检索作者 Michael O'Leary 的行。虽然用户代码中的 Connect 属性指定 Northwind 数据源，但是该数据源将被 Msdfmap.ini 中的 connect 部分覆盖。将 DataControl 对象的 Recordset 属性分配给断开连接的 Recordset 对象只是为了便于编码。

// BeginHandlerCpp

#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \

no_namespace rename("EOF", "EndOfFile")

#import "C:\Program Files\Common Files\System\MSADC\msadco.dll"

#include <ole2.h>

#include <stdio.h>

#include <conio.h>

// Function declarations

inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};

void HandlerX(void);

void PrintProviderError(_ConnectionPtr pConnection);

void PrintComError(_com_error &e);

//////////////////////////////////////////////////////////

// //

// Main Function //

// //

//////////////////////////////////////////////////////////

void main()

{

HRESULT hr = S_OK;

hr = ::CoInitialize(NULL);

if (SUCCEEDED(hr))

{

HandlerX();

printf("Press any key to continue...");

getch();

::CoUninitialize();

}

}

//////////////////////////////////////////////////////////

// //

// HandlerX Function //

// //

//////////////////////////////////////////////////////////

void HandlerX(void)

{

HRESULT hr = S_OK;

// Define ADO object pointers.

// Initialize pointers on define.

// These are in the ADODB:: namespace.

_RecordsetPtr pRst = NULL;

//Define RDS object pointers.

RDS::IBindMgrPtr dc;

try

{

TESTHR(hr = dc.CreateInstance(__uuidof(RDS::DataControl)));

dc->Handler = "MSDFMAP.Handler";

dc->Server = "http://MyServer";

dc->Connect = "Data Source=AuthorDatabase";

dc->SQL = "AuthorById('267-41-2394')";

// Retrieve the record.

dc->Refresh();

// Use another Recordset as a convenience.

pRst = dc->GetRecordset();

printf("Author is %s %s",(LPSTR) (_bstr_t) pRst->Fields->GetItem("au_fname")->Value,\

(LPSTR) (_bstr_t) pRst->Fields->GetItem("au_lname")->Value);

pRst->Close();

} // End Try statement.

catch (_com_error &e)

{

PrintProviderError(pRst->GetActiveConnection());

PrintComError(e);

}

}

//////////////////////////////////////////////////////////

// //

// PrintProviderError Function //

// //

//////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)

{

// Print Provider Errors from Connection object.

// pErr is a record object in the Connection's Error collection.

ErrorPtr pErr = NULL;

long nCount = 0;

long i = 0;

if( (pConnection->Errors->Count) > 0)

{

nCount = pConnection->Errors->Count;

// Collection ranges from 0 to nCount -1.

for(i = 0; i < nCount; i++)

{

pErr = pConnection->Errors->GetItem(i);

printf("\t Error number: %x\t%s", pErr->Number, pErr->Description);

}

}

}

//////////////////////////////////////////////////////////

//

// PrintComError Function //

// //

//////////////////////////////////////////////////////////

void PrintComError(_com_error &e)

{

_bstr_t bstrSource(e.Source());

_bstr_t bstrDescription(e.Description());

// Print Com errors.

printf("Error\n");

printf("\tCode = %08lx\n", e.Error());

printf("\tCode meaning = %s\n", e.ErrorMessage());

printf("\tSource = %s\n", (LPCSTR) bstrSource);

printf("\tDescription = %s\n", (LPCSTR) bstrDescription);

}

// EndHandlerCpp

请参阅

DataControl 对象 (RDS) | Handler 属性 (RDS)


InternetTimeout 属性范例 (VC++)

本范例演示 InternetTimeout 属性，DataControl 和 DataSpace 对象具有该属性。在此例中，在 DataControl 对象上演示 InternetTimeout 属性，并将超时设置为 20 秒。

// BeginInternetTimeoutCpp

#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \

no_namespace rename("EOF", "EndOfFile")

#import "C:\Program Files\Common Files\System\MSADC\msadco.dll"

#include <ole2.h>

#include <stdio.h>

#include <conio.h>

// Function declarations

inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};

void InternetTimeOutX(void);

void PrintProviderError(_ConnectionPtr pConnection);

void PrintComError(_com_error &e);

//////////////////////////////////////////////////////////

// //

// Main Function //

// //

//////////////////////////////////////////////////////////

void main()

{

if(FAILED(::CoInitialize(NULL)))

return;

InternetTimeOutX();

::CoUninitialize();

}

//////////////////////////////////////////////////////////

// //

// InternetTimeOutX Function //

// //

//////////////////////////////////////////////////////////

void InternetTimeOutX(void)

{

HRESULT hr = S_OK;

// Define ADO object pointers.

// Initialize pointers on define.

// These are in the ADODB:: namespace.

_RecordsetPtr pRst = NULL;

//Define RDS object pointers

RDS::IBindMgrPtr dc ;

try

{

TESTHR(dc.CreateInstance(__uuidof(RDS::DataControl)));

dc->Server = "http://MyServer";

dc->Connect = "Data Source='AuthorDatabase'";

dc->SQL = "SELECT * FROM Authors";

// Wait at least 20 seconds.

dc->InternetTimeout = 20000;

dc->Refresh();

// Use another Recordset as a convenience

pRst = dc->GetRecordset();

while(!(pRst->EndOfFile))

{

printf("%s %s",(LPSTR) (_bstr_t) pRst->Fields->

GetItem("au_fname")->Value,

(LPSTR) (_bstr_t) pRst->Fields->

GetItem("au_lname")->Value);

pRst->MoveNext();

}

pRst->Close();

}

catch (_com_error &e)

{

PrintProviderError(pRst->GetActiveConnection());

PrintComError(e);

}

}

//////////////////////////////////////////////////////////

// //

// PrintProviderError Function //

// //

//////////////////////////////////////////////////////////

void PrintProviderError(_ConnectionPtr pConnection)

{

// Print Provider Errors from Connection object.

// pErr is a record object in the Connection's Error collection.

ErrorPtr pErr = NULL;

if( (pConnection->Errors->Count) > 0)

{

long nCount = pConnection->Errors->Count;

// Collection ranges from 0 to nCount -1.

for(long i = 0; i < nCount; i++)

{

pErr = pConnection->Errors->GetItem(i);

printf("\t Error number: %x\t%s", pErr->Number,

pErr->Description);

}

}

}

//////////////////////////////////////////////////////////

// //

// PrintComError Function //

// //

//////////////////////////////////////////////////////////

void PrintComError(_com_error &e)

{

_bstr_t bstrSource(e.Source());

_bstr_t bstrDescription(e.Description());

// Print Com errors.

printf("Error\n");

printf("\tCode = %08lx\n", e.Error());

printf("\tCode meaning = %s\n", e.ErrorMessage());

printf("\tSource = %s\n", (LPCSTR) bstrSource);

printf("\tDescription = %s\n", (LPCSTR) bstrDescription);

}

// EndInternetTimeoutCpp

请参阅

InternetTimeout 属性 (RDS)


Microsoft Visual J++ 中的 RDS 代码范例

通过下列代码范例来学习用 Microsoft Visual J++ 编程时如何使用 RDS 属性。

注意 请将整个代码范例（从开始到结束）粘贴到代码编辑器中。如果只使用部分范例或者丢失了段落格式，范例可能无法正确运行。
  • Handler 属性范例
  • InternetTimeout 属性范例


Handler 属性范例 (VJ++)

本范例演示 RDS DataControl 对象的 Handler 属性。（有关详细信息，请参阅 DataFactory 自定义。）

假设在服务器上的参数文件 Msdfmap.ini 中有下列部分：

[connect AuthorDataBase]
Access=ReadWrite
Connect="DSN=Pubs"
[sql AuthorById]
SQL="SELECT * FROM Authors WHERE au_id = ?"

用户代码如下。分配给 SQL 属性的命令将与 AuthorById 标识符匹配，并将检索作者 Michael O'Leary 的行。虽然用户代码中的 Connect 属性指定 Northwind 数据源，但是该数据源将被 Msdfmap.ini 中的 connect 部分覆盖。将 DataControl 对象的 Recordset 属性分配给断开连接的 Recordset 对象只是为了便于编码。

// BeginHandlerJ

import com.ms.wfc.data.*;

import com.ms.wfc.data.rds.*;

import java.io.* ;

public class HandlerX

{

// The main entry point for the application.

public static void main (String[] args)

{

HandlerX();

System.exit(0);

}

// HandlerX function

static void HandlerX()

{

// Define ADO Objects.

Recordset rstAuthors = null;

// Declarations.

BufferedReader in =

new BufferedReader (new InputStreamReader(System.in));

int intCount = 0;

int intDisplaysize = 15;

try

{

IBindMgr dc = (IBindMgr) new DataControl();

dc.setServer("MyServer");

dc.setConnect("Data Source=Northwind");

dc.setSQL("AuthorById(267-41-2394)");

dc.Refresh(); // Retrieve the record.

// Use another recordset as a convenience.

rstAuthors = (Recordset)dc.getRecordset();

System.out.println("Author is '" +

rstAuthors.getField("au_fname").getString() +

" " +

rstAuthors.getField("au_lname").getString() +

"'");

System.out.println("\nPress <Enter> to continue..");

in.readLine();

}

catch( AdoException ae )

{

// Notify user of any errors that result from ADO.

// As passing a Recordset, check for null pointer first.

if (rstAuthors != null)

{

PrintProviderError(rstAuthors.getActiveConnection());

}

else

{

System.out.println("Exception: " + ae.getMessage());

}

}

// System read requires this catch.

catch( java.io.IOException je)

{

PrintIOError(je);

}

catch(java.lang.UnsatisfiedLinkError e)

{

System.out.println("Exception: " + e.getMessage());

}

catch(java.lang.NullPointerException ne)

{

System.out.println(

"Exception: Attempt to use null where an object is required.");

}

finally

{

// Cleanup objects before exit.

if (rstAuthors != null)

if (rstAuthors.getState() == 1)

rstAuthors.close();

}

}

// PrintProviderError Function

static void PrintProviderError( Connection Cnn1 )

{

// Print Provider errors from Connection object.

// ErrItem is an item object in the Connection’s Errors collection.

com.ms.wfc.data.Error ErrItem = null;

long nCount = 0;

int i = 0;

nCount = Cnn1.getErrors().getCount();

// If there are any errors in the collection, print them.

if( nCount > 0);

{

// Collection ranges from 0 to nCount - 1

for (i = 0; i< nCount; i++)

{

ErrItem = Cnn1.getErrors().getItem(i);

System.out.println("\t Error number: " + ErrItem.getNumber()

+ "\t" + ErrItem.getDescription() );

}

}

}

// PrintIOError Function

static void PrintIOError( java.io.IOException je)

{

System.out.println("Error \n");

System.out.println("\tSource = " + je.getClass() + "\n");

System.out.println("\tDescription = " + je.getMessage() + "\n");

}

}

// EndHandlerJ

请参阅

DataControl 对象 (RDS) | Handler 属性 (RDS)


InternetTimeout 属性范例 (VJ++)

本范例演示 DataControl 和 DataSpace 对象的 InternetTimeout 属性。在此例中，在 DataControl 对象上演示 InternetTimeout 属性，并将超时设置为 20 秒。

// BeginInternetTimeoutJ

// The WFC class includes the ADO objects.

import com.ms.wfc.data.*;

import com.ms.wfc.data.rds.*;

import java.io.* ;

public class InternetTimeoutX

{

// The main entry point for the application.

public static void main (String[] args)

{

InternetTimeoutX();

System.exit(0);

}

// InternetTimeoutX function

static void InternetTimeoutX()

{

// Define ADO Objects.

Recordset rstAuthors = null;

// Declarations.

BufferedReader in =

new BufferedReader (new InputStreamReader(System.in));

int intCount = 0;

int intDisplaysize = 15;

try

{

IBindMgr dc = (IBindMgr) new DataControl();

dc.setServer("http://MyServer");

dc.setConnect("DSN=pubs");

dc.setSQL("SELECT * FROM Authors");

dc.setInternetTimeout(20000); // Wait at least 20 seconds.

dc.Refresh();

rstAuthors = (Recordset)dc.getRecordset();

while(!rstAuthors.getEOF())

{

System.out.println(rstAuthors.getField

("au_fname").getString() + " " +

rstAuthors.getField("au_lname").getString());

intCount++;

if(intCount % intDisplaysize == 0)

{

System.out.println("\nPress <Enter> to continue..");

in.readLine();

intCount = 0;

}

rstAuthors.moveNext();

}

System.out.println("\nPress <Enter> to continue..");

in.readLine();

}

catch( AdoException ae )

{

// Notify user of any errors that result from ADO.

// As passing a Recordset, check for null pointer first.

if (rstAuthors != null)

{

PrintProviderError(rstAuthors.getActiveConnection());

}

else

{

System.out.println("Exception: " + ae.getMessage());

}

}

// System read requires this catch.

catch( java.io.IOException je)

{

PrintIOError(je);

}

catch(java.lang.UnsatisfiedLinkError e)

{

System.out.println("Exception: " + e.getMessage());

}

catch(java.lang.NullPointerException ne)

{

System.out.println(

"Exception: Attempt to use null where an object is required.");

}

finally

{

// Cleanup objects before exit.

if (rstAuthors != null)

if (rstAuthors.getState() == 1)

rstAuthors.close();

}

}

// PrintProviderError Function

static void PrintProviderError( Connection Cnn1 )

{

// Print Provider errors from Connection object.

// ErrItem is an item object in the Connection’s Errors collection.

com.ms.wfc.data.Error ErrItem = null;

long nCount = 0;

int i = 0;

nCount = Cnn1.getErrors().getCount();

// If there are any errors in the collection, print them.

if( nCount > 0);

{

// Collection ranges from 0 to nCount - 1

for (i = 0; i< nCount; i++)

{

ErrItem = Cnn1.getErrors().getItem(i);

System.out.println("\t Error number: " + ErrItem.getNumber()

+ "\t" + ErrItem.getDescription() );

}

}

}

// PrintIOError Function

static void PrintIOError( java.io.IOException je)

{

System.out.println("Error \n");

System.out.println("\tSource = " + je.getClass() + "\n");

System.out.println("\tDescription = " + je.getMessage() + "\n");

}

}

// EndInternetTimeoutJ

请参阅

InternetTimeout 属性 (RDS)


ADO MD API 参考

ADO MD 文档的这一节包含每个 ADO MD 对象、集合、方法和属性的主题，同时还适时提供范例代码。有关详细信息，请在索引中搜索特定主题或参阅下面的主题：

  • ADO MD 对象
  • ADO MD 集合
  • ADO MD 属性
  • ADO MD 方法
  • ADO MD 枚举常量
  • ADO MD 范例

请参阅

ADO MD 代码范例 | ADO MD 集合 | ADO MD 枚举常量 | ADO MD 方法 | ADO MD 对象模型 | ADO MD 对象 | ADO MD 属性


ADO MD 对象模型

下面的图表说明如何在 ADO MD 中表示这些对象及其相互关系。

每个 Axis 和 Cell 对象都有 Positions 集合。

每个 Level 和 Position 对象都有 Members 集合。

每个 Axis、Cell、Cellset、CubeDef、Dimension、Hierarchy、Level 和 Member 对象都有标准 ADO Properties 集合。

请参阅

ADO MD API 参考 | ADO MD 代码范例 | ADO MD 集合 | ADO MD 枚举常量 | ADO MD 方法 | ADO MD 对象 | ADO MD 属性 | Microsoft ADO MD 程序员参考 | 多维模式和数据概述 | 使用多维数据


ADO MD 对象

Axis | 表示单元集的位置轴或过滤轴，包含一个或多个维的选定成员。
Catalog | 包含多维数据提供者 (MDP) 特有的多维模式信息（即立方和基本维、分级结构、级别和成员）。
Cell | 表示位于轴坐标交叉点上的数据，包含在单元集中。
Cellset | 表示多维查询的结果。它是从立方或其他单元集中选择的单元的集合。
CubeDef | 表示多维模式中的立方，包含一组相关维。
Dimension | 表示多维立方中的一个维，包含一个或多个成员的分级结构。
Hierarchy | 表示合计或“卷起”维的成员的一种方式。维可以按照一个或多个分级结构进行合计。
Level | 包含一组成员，其中每个成员在分级结构中均有相同的等级。
Member | 表示立方中某级别的成员、某级别成员的子成员或位于单元集的轴上某位置的成员。
Position | 表示定义轴上某点的一组不同维的一个或多个成员。

同时，Catalog 对象与包括在标准 ADO 库中的 ADO Connection 对象相连接：

对象 | 说明
Connection | 表示到数据源的打开的连接。

这些对象之间的关系在 ADO MD 对象模型中说明。

许多 ADO MD 对象可以包含在一个相应的集合中。例如，CubeDef 对象可以包含在 Catalog 的 CubeDefs 集合中。有关详细信息，请参阅 ADO MD 集合。

请参阅

ADO MD API 参考 | ADO MD 代码范例 | ADO MD 集合 | ADO MD 枚举常量 | ADO MD 方法 | ADO MD 对象模型 | ADO MD 属性


Axis 对象 (ADO MD)

ADO 2.5 MD API 参考

Axis 对象

表示单元集的位置轴或过滤轴，包含一个或多个维的选定成员。

说明

Axis 对象可以包含在 Axes 集合中，或者由 Cellset 的 FilterAxis 属性返回。

通过 Axis 对象的集合和属性，可以：

  • 用 Name 属性标识 Axis。
  • 用 Positions 集合迭代 Axis 上的每个位置。
  • 用 DimensionCount 属性获取 Axis 上的维数。
  • 用标准 ADO Properties 集合获取 Axis 的提供者特有的属性。

请参阅

VBScript 范例

属性、方法和事件 | Axes 集合 | Positions 集合 | Properties 集合


属性、方法和事件

ADO 2.5 MD API 参考

Axis 对象的属性、方法和事件

属性/集合

DimensionCount 属性

Name 属性

Positions 集合

Properties 集合

方法

无。

事件

无。

请参阅

应用于：Axis 对象


Catalog 对象 (ADO MD)

ADO 2.5 MD API 参考

Catalog 对象

包含多维数据提供者 (MDP) 特有的多维模式信息（即立方和基本维、分级结构、级别和成员）。

说明

通过 Catalog 对象的集合和属性，可以：

  • 通过将 ActiveConnection 属性设置为标准 ADO Connection 对象或有效的连接字符串来打开目录。
  • 用 Name 属性标识 Catalog。
  • 用 CubeDefs 集合迭代目录中的立方。

请参阅

Visual Basic 范例

属性、方法和事件 | Connection 对象 | CubeDefs 集合


属性、方法和事件

ADO 2.5 MD API 参考

Catalog 对象的属性、方法和事件

属性/集合

ActiveConnection 属性

CubeDefs 集合

Name 属性

方法

无。

事件

无。

请参阅

应用于：Catalog 对象


Cell 对象 (ADO MD)

ADO 2.5 MD API 参考

Cell 对象

表示位于轴坐标交叉点上的数据，包含在单元集中。

说明

Cell 对象由 Cellset 对象的 Item 属性返回。

通过 Cell 对象的集合和属性，可以：

  • 用 Value 属性返回 Cell 中的数据。
  • 用 FormattedValue 属性返回表示 Value 属性的格式化显示的字符串。
  • 用 Ordinal 属性返回 Cellset 中的 Cell 的序号值。
  • 用 Positions 集合确定 CubeDef 中的 Cell 的位置。
  • 用标准 Properties 集合检索其他有关 Cell 的信息。

Properties 集合中包含提供者提供的属性。下表列出了可用的属性。实际属性列表根据提供者的实现可能有所不同。有关可用属性的更完整的列表，请参阅提供者的文档。

名称 | 描述
BackColor | 显示单元时使用的背景色。
FontFlags | 位掩码在字体上的详细效果。
FontName | 显示单元值时使用的字体。
FontSize | 显示单元值时使用的字体大小。
ForeColor | 显示单元时使用的前景色。
FormatString | 格式化字符串中的值。

请参阅

VBScript 范例

属性、方法和事件 | Cellset 对象 | Positions 集合 | Properties 集合


属性、方法和事件

ADO 2.5 MD API 参考

Cell 对象的属性、方法和事件

属性/集合

FormattedValue 属性

Ordinal 属性 (Cell)

Positions 集合

Properties 集合

Value 属性

方法

无。

事件

无。

请参阅

应用于：Cell 对象


Cellset 对象 (ADO MD)

ADO 2.5 MD API 参考

Cellset 对象

表示多维查询的结果。它是从立方或其他单元集中选择的单元的集合。

说明

使用直接的、类似数组的访问检索 Cellset 中的数据，可以“深入”到特定成员，以获取该成员的数据。例如，下面的代码将返回名为 cst 的单元集第一个轴上第一位置中的第一成员的标题：

cst.Axes(0).Positions(0).Members(0).Caption

在单元集内没有当前单元的概念。相反，Item 属性从单元集中检索特定的 Cell 对象。Item 属性的参数确定检索哪个单元。可以指定单元的唯一序号值。还可以使用单元集每个轴上的单元的位置号来检索单元。有关检索单元的详细信息，请参阅 Item 属性。

通过 Cellset 对象的集合、方法和属性，可以：

  • 通过设置打开的连接的 ActiveConnection 属性，使之与 Cellset 对象相关联。
  • 用 Open 方法执行和检索多维查询的结果。
  • 用 Item 属性检索 Cellset 中的 Cell。
  • 用 Axes 集合返回定义 Cellset 的 Axis 对象。
  • 用 FilterAxis 属性检索用于过滤 Cellset 中数据的维的信息。
  • 用 Source 属性返回或指定用于定义 Cellset 的查询。
  • 用 State 属性返回 Cellset 的当前状态（已打开、已关闭、正在执行或正在连接）。
  • 用 Close 方法关闭打开的 Cellset。
  • 用标准 ADO Properties 集合检索有关 Cellset 的提供者特有的信息。

请参阅

Visual Basic 范例

属性、方法和事件 | Axes 集合 | Cell 对象 | Connection 对象 | Properties 集合


属性、方法和事件

ADO 2.5 MD API 参考

Cellset 对象的属性、方法和事件

属性/集合

ActiveConnection 属性

Axes 集合

FilterAxis 属性

Item 属性 (Cellset)

Properties 集合

Source 属性

State 属性

方法

Close 方法

Open 方法

事件

无。

请参阅

应用于：Cellset 对象


CubeDef 对象 (ADO MD)

ADO 2.5 MD API 参考

CubeDef 对象

表示多维模式中的立方，包含一组相关维。

说明

通过 CubeDef 对象的集合和属性，可以：

  • 用 Name 属性标识 CubeDef。
  • 用 Description 属性返回描述立方的字符串。
  • 用 Dimensions 集合返回构成立方的维。
  • 用标准 ADO Properties 集合获取关于 CubeDef 的其他信息。

Properties 集合包含由提供者提供的属性。下表列出了可用的属性。实际属性列表根据提供者的实现可能有所不同。有关可用属性的更完整的列表，请参阅提供者的文档。

名称 | 说明
CatalogName | 此立方所属的目录的名称。
CreatedOn | 创建立方的日期和时间。
CubeGUID | 立方 GUID。
CubeName | 立方的名称。
CubeType | 立方的类型。
DataUpdatedBy | 上次更新数据的人的用户 ID。
Description | 有意义的立方说明。
LastSchemaUpdate | 上次更新模式的日期和时间。
SchemaName | 此立方所属的模式的名称。
SchemaUpdatedBy | 上次更新模式的人的用户 ID。

请参阅

VBScript 范例

属性、方法和事件 | Catalog 对象 | CubeDefs 集合 | Dimensions 集合 | Properties 集合


属性、方法和事件

ADO 2.5 MD API 参考

CubeDef 对象的属性、方法和事件

属性/集合

Description 属性

Dimensions 集合

Name 属性

Properties 集合

事件

无。

请参阅

应用于：CubeDef 对象

© 1998-2002 Microsoft Corporation。保留所有权利。


Dimension 对象 (ADO MD)

ADO 2.5 MD API 参考

Dimension 对象

表示多维立方中的一个维，包含成员的一个或多个分级结构。

说明

通过 Dimension 对象的集合和属性，可以：

  • 用 Name 和 UniqueName 属性标识 Dimension。
  • 用 Description 属性返回描述 Dimension 的有意义的字符串。
  • 用 Hierarchies 集合返回构成 Dimension 的 Hierarchy 对象。
  • 用标准 ADO Properties 集合获取 Dimension 对象的其他信息。

Properties 集合包含由提供者提供的属性。下表列出了可用的属性。实际属性列表根据提供者的实现可能有所不同。有关可用属性的更完整的列表，请参阅提供者的文档。

名称 | 说明
CatalogName | 此立方所属的目录的名称。
CubeName | 立方的名称。
DefaultHierarchy | 默认分级结构的唯一名称。
Description | 有意义的立方说明。
DimensionCaption | 与维相关联的标签或标题。
DimensionCardinality | 维中成员的数目。
DimensionGUID | 维的 GUID。
DimensionName | 维的名称。
DimensionOrdinal | 维组中维的序号，这些维构成立方。
DimensionType | 维类型。
DimensionUniqueName | 维的明确名称。
SchemaName | 此立方所属的模式的名称。

请参阅

VBScript 范例

属性、方法和事件 | CubeDef 对象 | Dimensions 集合 | Hierarchies 集合 | Properties 集合


属性、方法和事件

ADO 2.5 MD API 参考

Dimension 对象的属性、方法和事件

属性/集合

Description 属性

Hierarchies 集合

Name 属性

Properties 集合

UniqueName 属性

方法

无。

事件

无。

请参阅

应用于：Dimension 对象


Hierarchy 对象 (ADO MD)

ADO 2.5 MD API 参考

Hierarchy 对象

表示合计或“卷起”维的成员的一种方式。维可以按照一个或多个分级结构进行合计。

说明

通过 Hierarchy 对象的集合和属性，可以：

  • 用 Name 和 UniqueName 属性标识 Hierarchy。
  • 用 Description 属性返回描述 Hierarchy 的有意义的字符串。
  • 用 Levels 集合返回构成 Hierarchy 的 Level 对象。
  • 用标准 ADO Properties 集合获取 Hierarchy 对象的其他信息。

Properties 集合包含由提供者提供的属性。下表列出了可用的属性。实际属性列表根据提供者的实现可能有所不同。有关可用属性的更完整的列表，请参阅提供者的文档。

名称 | 说明
AllMember | 在分级结构中位于最高卷起级别的成员。
CatalogName | 此立方所属的目录的名称。
CubeName | 立方的名称。
DefaultMember | 此分级结构的默认成员的唯一名称。
Description | 有意义的分级结构说明。
DimensionType | 此分级结构所属的维的类型。
DimensionUniqueName | 维的明确名称。
HierarchyCaption | 与分级结构相关联的标签或标题。
HierarchyCardinality | 分级结构中成员的数目。
HierarchyGUID | 分级结构的 GUID。
HierarchyName | 分级结构的名称。
HierarchyUniqueName | 分级结构的明确名称。
SchemaName | 此立方所属的模式的名称。

请参阅

VBScript 范例

属性、方法和事件 | Dimension 对象 | Hierarchies 集合 | Levels 集合 | Properties 集合


属性、方法和事件

ADO 2.5 MD API 参考

Hierarchy 对象的属性、方法和事件

属性/集合

Description 属性

Levels 集合

Name 属性

Properties 集合

UniqueName 属性

方法

无。

事件

无。

请参阅

应用于：Hierarchy 对象


Level 对象 (ADO MD)

ADO 2.5 MD API 参考

Level 对象

包含一组成员，其中每个成员在分级结构中均有相同的等级。

说明

通过 Level 对象的集合和属性，可以：

  • 用 Name 和 UniqueName 属性标识 Level。
  • 用 Caption 属性返回显示 Level 时使用的字符串。
  • 用 Description 属性返回描述 Level 的有意义的字符串。
  • 用 Members 集合返回构成 Level 的 Member 对象。
  • 用 Depth 属性返回从 Level 的根算起的级别号。
  • 用标准 ADO Properties 集合获取 Level 对象的其他信息。

Properties 集合包含由提供者提供的属性。下表列出了可用的属性。实际属性列表根据提供者的实现可能有所不同。有关可用属性的更完整的列表，请参阅提供者的文档。

名称 | 说明
CatalogName | 此立方所属的目录的名称。
CubeName | 立方的名称。
Description | 有意义的级别说明。
DimensionUniqueName | 维的明确名称。
HierarchyUniqueName | 分级结构的明确名称。
LevelCaption | 与级别相关联的标签或标题。
LevelCardinality | 级别中的成员数目。
LevelGUID | 级别的 GUID。
LevelName | 级别的名称。
LevelNumber | 级别和分级结构的根之间的距离。
LevelType | 级别的类型。
LevelUniqueName | 级别的明确名称。
SchemaName | 此立方所属的模式的名称。

请参阅

VBScript 范例

属性、方法和事件 | Hierarchy 对象 | Levels 集合 | Members 集合 | Properties 集合


属性、方法和事件

ADO 2.5 MD API 参考

Level 对象的属性、方法和事件

属性/集合

Caption 属性

Depth 属性

Description 属性

Members 集合

Name 属性

Properties 集合

UniqueName 属性

方法

无。

事件

无。

请参阅

应用于：Level 对象


Member 对象 (ADO MD)

ADO 2.5 MD API 参考

Member 对象

表示立方中某级别的成员、某级别成员的子成员或位于单元集的轴上某位置的成员。

说明

Member 的属性根据使用环境的不同而有差别。CubeDef 中 Level 的 Member 具有 Children 属性，该属性返回分级结构中比当前 Member 低一个级别的 Member。对于 Position 的 Member，Children 集合始终为空。同样，Type 属性仅适用于 Level 的 Members。

Position 的 Member 具有两个属性：DrilledDown 和 ParentSameAsPrev，它们在显示 Cellset 时十分有用。如果在 Level 的 Member 上访问这些属性，将出现错误。

通过 Level 的 Member 对象的集合和属性，可以：

  • 用 Name 和 UniqueName 属性标识 Member。
  • 用 Caption 属性返回显示 Member 时使用的字符串。
  • 用 Description 属性返回描述度量或公式 Member 的有意义的字符串。
  • 用 Type 属性确定 Member 的性质。
  • 用 LevelDepth 和 LevelName 属性获取关于 Member 的 Level 的信息。
  • 用 Parent 和 Children 属性获得 Hierarchy 中的相关的 Members。
  • 用 ChildCount 属性对 Member 的子成员进行计数。
  • 用标准 ADO Properties 集合获取 Level 对象的其他信息。

通过 Axis 上的 Position 的 Member 的集合和属性，可以：

  • 用 Name 和 UniqueName 属性标识 Member。
  • 用 Caption 属性返回显示 Member 时使用的字符串。
  • 用 Description 属性返回描述度量或公式 Member 的有意义的字符串。
  • 用 LevelDepth 和 LevelName 属性获取关于 Member 的 Level 的信息。
  • 用 ChildCount 属性对 Member 的子进行计数。
  • 用 DrilledDown 属性确定在 Axis 上是否至少有一个子成员紧跟在此 Member 后面。
  • 用 ParentSameAsPrev 属性确定此 Member 的父是否与前一个 Member 的父相同。
  • 用标准 ADO Properties 集合获取 Level 对象的其他信息。

Properties 集合包含由提供者提供的属性。下表列出了可用的属性。实际属性列表根据提供者的实现可能有所不同。有关可用属性的更完整的列表，请参阅提供者的文档。

名称 | 说明
CatalogName | 此立方所属的目录的名称。
ChildrenCardinality | 此成员拥有的子成员数目。
CubeName | 立方的名称。
Description | 成员的有意义的说明。
DimensionUniqueName | 维的明确名称。
HierarchyUniqueName | 分级结构的明确名称。
LevelNumber | 级别和分级结构的根之间的距离。
LevelUniqueName | 级别的明确名称。
MemberCaption | 与成员相关联的标签或标题。
MemberGUID | 成员的 GUID。
MemberName | 成员的名称。
MemberOrdinal | 成员的序号。
MemberType | 成员的类型。
MemberUniqueName | 成员的明确名称。
ParentCount | 此成员所具有的父成员数目的计数。
ParentLevel | 成员的父成员的级别号。
ParentUniqueName | 成员的父成员的明确名称。
SchemaName | 此立方所属的模式的名称。

请参阅

Visual Basic 范例

属性、方法和事件 | Members 集合 | Properties 集合


属性、方法和事件

ADO 2.5 MD API 参考

Member 对象的属性、方法和事件

属性/集合

Caption 属性

ChildCount 属性

Children 属性

Description 属性

DrilledDown 属性

LevelDepth 属性

LevelName 属性

Name 属性

Parent 属性

ParentSameAsPrev 属性

Properties 集合

Type 属性

UniqueName 属性

方法

无。

事件

无。

请参阅

应用于：Member 对象


Position 对象 (ADO MD)

ADO 2.5 MD API 参考

Position 对象

表示定义轴上某点的一组不同维的一个或多个成员。

说明

通过 Position 对象的属性和集合，可以：

  • 使用 Ordinal 属性返回 Axis 上的 Position 的序号位置。
  • 使用 Members 集合返回构成 Axis 上位置的成员。

请参阅

VBScript 范例

属性、方法和事件 | Axis 对象 | Cell 对象 | Members 集合 | Positions 集合


属性、方法和事件

ADO 2.5 MD API 参考

Position 对象的属性、方法和事件

属性/集合

Members 集合

Ordinal 属性 (Position)

方法

无。

事件

无。

请参阅

应用于：Position 对象


ADO MD 集合

Axes | 包含定义单元集的 Axis 对象。
CubeDefs | 包含表示多维目录中的立方的 CubeDef 对象。
Dimensions | 包含构成立方的 Dimension 对象。
Hierarchies | 包含维的 Hierarchy 对象的集合。
Levels | 包含构成分级结构的 Level 对象。
Members | 包含来自某个级别或轴上的某个位置的 Member 对象。
Positions | 包含定义轴上的点的 Position 对象。

请参阅

ADO MD API 参考 | ADO MD 代码范例 | ADO MD 枚举常量 | ADO MD 方法 | ADO MD 对象模型 | ADO MD 对象 | ADO MD 属性


Axes 集合 (ADO MD)

ADO 2.5 MD API 参考

Axes 集合

包含定义单元集的 Axis 对象。

说明

Cellset 对象包含 Axes 集合。一旦打开 Cellset，此集合将至少包含一个 Axis。有关如何使用 Axis 对象的详细说明，请参阅 Axis 对象。

注意 Cellset 的过滤轴不包含在 Axes 集合中。有关详细信息，请参阅 FilterAxis 属性。

Axes 是标准 ADO 集合。用集合的属性和方法，可以：

  • 用 Count 属性获取集合中的对象数目。
  • 用默认的 Item 属性返回集合中的对象。
  • 用 Refresh 方法从提供者更新集合中的对象。

请参阅

Visual Basic 范例

属性、方法和事件 | Axis 对象


Axes 集合的属性、方法和事件

Properties

Count 属性

Item 属性

方法

Refresh 方法

事件

无。

请参阅

应用于：Axes 集合


CubeDefs 集合 (ADO MD)

ADO 2.5 MD API 参考

CubeDefs 集合

包含表示多维目录中的立方的 CubeDef 对象。

说明

CubeDefs 是标准的 ADO 集合。用集合的属性和方法，可以：

  • 用 Count 属性获取集合中的对象数目。
  • 用默认的 Item 属性返回集合中的对象。
  • 用 Refresh 方法从提供者更新集合中的对象。

请参阅

Visual Basic 范例

属性、方法和事件 | Catalog 对象 | CubeDef 对象


CubeDefs 集合的属性、方法和事件

Properties

Count 属性

Item 属性

方法

Refresh 方法

事件

无。

请参阅

应用于：CubeDefs 集合


Dimensions 集合 (ADO MD)

ADO 2.5 MD API 参考

Dimensions 集合

包含构成立方的 Dimension 对象。

说明

Dimensions 是标准的 ADO 集合。用集合的属性和方法，可以：

  • 用 Count 属性获取集合中的对象数目。
  • 用默认的 Item 属性返回集合中的对象。
  • 用 Refresh 方法从提供者更新集合中的对象。

请参阅

Visual Basic 范例

属性、方法和事件 | CubeDef 对象 | Dimension 对象


Dimensions 集合的属性、方法和事件

Properties

Count 属性

Item 属性

方法

Refresh 方法

事件

无。

请参阅

应用于：Dimensions 集合


Hierarchies 集合 (ADO MD)

ADO 2.5 MD API 参考

Hierarchies 集合

包含维的 Hierarchy 对象的集合。

说明

Hierarchies 是标准的 ADO 集合。用集合的属性和方法，可以：

  • 用 Count 属性获取集合中的对象数目。
  • 用默认的 Item 属性返回集合中的对象。
  • 用 Refresh 方法从提供者更新集合中的对象。

请参阅

Visual Basic 范例

属性、方法和事件 | Dimension 对象 | Hierarchy 对象

© 1998-2003 Microsoft Corporation. 保留所有权利。


Hierarchies 集合的属性、方法和事件

属性

Count 属性

Item 属性

方法

Refresh 方法

事件

无。

请参阅

应用于：Hierarchies 集合


Levels 集合 (ADO MD)

ADO 2.5 MD API 参考

Levels 集合

包含构成分级结构的 Level 对象。

说明

Levels 是标准的 ADO 集合。用集合的属性和方法，可以：

  • 用 Count 属性获取集合中的对象数目。
  • 用默认的 Item 属性返回集合中的对象。
  • 用 Refresh 方法从提供者更新集合中的对象。

请参阅

Visual Basic 范例

属性、方法和事件 | Hierarchy 对象 | Level 对象


Levels 集合的属性、方法和事件

属性

Count 属性

Item 属性

方法

Refresh 方法

事件

无。

请参阅

应用于：Levels 集合


Members 集合 (ADO MD)

ADO 2.5 MD API 参考

Members 集合

包含来自某个级别或轴上的某个位置的 Member 对象。

说明

Members 集合用于包含下列成员类型：

  • 构成立方中的级别的成员。这些成员包含在 Level 对象的 Members 集合中。例如，使用多维模式和数据概述中的范例，Countries 级别的四个成员为 Canada、USA、UK 和 Germany。
  • 分级结构中特定成员的子成员。这些成员由父 Member 对象的 Children 属性返回。例如，再用同一个范例，Canada 成员的两个子成员为 Canada-East 和 Canada-West。
  • 定义单元集的轴上特定位置的成员。以使用多维数据中的单元集为例，X 轴上第一位置处的两个成员为 Valentine 和 Seattle。这些成员包含在 Position 对象的 Members 集合中。

Members 是标准的 ADO 集合。用集合的属性和方法，可以：

  • 用 Count 属性获取集合中的对象数目。
  • 用默认的 Item 属性返回集合中的对象。
  • 用 Refresh 方法从提供者更新集合中的对象。

请参阅

VBScript 范例

属性、方法和事件 | Member 对象


Members 集合的属性、方法和事件

Properties

Count 属性

Item 属性

方法

Refresh 方法

事件

无。

请参阅

应用于：Members 集合


Positions 集合 (ADO MD)

ADO 2.5 MD API 参考

Positions 集合

包含定义轴上的点的 Position 对象。

说明

Positions 是标准的 ADO 集合。用集合的属性和方法，可以：

  • 用 Count 属性获取集合中的对象数目。
  • 用默认的 Item 属性返回集合中的对象。
  • 用 Refresh 方法从提供者更新集合中的对象。

请参阅

Visual Basic 范例

属性、方法和事件 | Axis 对象 | Cell 对象 | Position 对象


Positions 集合的属性、方法和事件

属性

Count 属性

Item 属性

方法

Refresh 方法

事件

无。

请参阅

应用于：Positions 集合


ADO MD 属性

ActiveConnection | 指示当前单元集或目录当前所属的 ADO Connection 对象。
Caption | 指示显示 Level 或 Member 对象时要使用的文本标题。
ChildCount | 指示在分级结构中当前 Member 对象为其父的成员数目。
Children | 返回在分级结构中当前 Member 是其父的 Members 的集合。
Count | 指示集合中对象的数目。
Depth | 指示 Level 和分级结构的根级别之间的级别数目。
Description | 返回当前对象的文本说明。
DimensionCount | 指示轴上的维数。
DrilledDown | 指示轴上是否有子成员紧跟在该成员后面。
FilterAxis | 指示当前单元集的过滤器信息。
Item | 使用其坐标来检索单元集中的单元。
Item | 按名称或序号返回集合的特定成员。
FormattedValue | 指示单元值的格式化显示。
LevelDepth | 指示分级结构的根和成员之间的级别数目。
LevelName | 指示成员的级别名称。
Name | 指示对象的名称。
Ordinal (Cell) | 通过其在单元集中的位置唯一标识单元。
Ordinal (Position) | 唯一标识轴上的位置。
Parent | 指示分级结构中当前成员的父成员。
ParentSameAsPrev | 指示此位置成员的父是否与前一个成员的父相同。
Source | 指示单元集中数据的源。
State | 指示单元集的当前状态。
Type | 指示当前成员的类型。
UniqueName | 指示当前对象的确切名称。
Value | 指示当前单元的值。

请参阅

ADO MD API 参考 | ADO MD 代码范例 | ADO MD 集合 | ADO MD 枚举常量 | ADO MD 方法 | ADO MD 对象模型 | ADO MD 对象


ActiveConnection 属性 (ADO MD)

ADO 2.5 MD API 参考

ActiveConnection 属性

指示当前单元集或目录当前所属的 ADO Connection 对象。

设置和返回值

设置或返回 Variant，它包含定义连接或 Connection 对象的字符串。默认值为空。

说明

可将此属性设置为有效 ADO Connection 对象或有效连接字符串。如果将此属性设置为连接字符串，提供者将使用此定义创建新的 Connection 对象并打开连接。

如果用 Open 方法的 ActiveConnection 参数打开 Cellset 对象，ActiveConnection 属性将继承该参数的值。

将 Catalog 对象的 ActiveConnection 属性设置为 Nothing 可以释放相关联的数据，包括 CubeDefs 集合中的数据和所有相关的 Dimension、Hierarchy、Level 和 Member 对象中的数据。关闭用于打开 Catalog 的 Connection 对象与将 ActiveConnection 属性设置为 Nothing 效果相同。

更改 Catalog 对象的 ActiveConnection 属性引用的连接的默认数据库将会使 Catalog 的内容无效。

如果试图更改打开的 Cellset 对象的 ActiveConnection 属性，将产生错误。

注意 在 Visual Basic 中，在将 ActiveConnection 属性设置为 Connection 对象时请使用 Set 关键字。如果省略了 Set 关键字，那么实际是把 ActiveConnection 属性设置为等于 Connection 对象的默认属性 ConnectionString。该代码有效。但会创建到数据源的附加连接，而这样做可能会对性能产生不利影响。

在使用 MSOLAP 数据提供者时，请将连接字符串中的数据源设置为服务器名称，并将初始目录设置为数据源的目录名称。要连接到已与服务器断开连接的立方文件，请将此位置设置为到 .CUB 文件的完整路径。两种情况下都请将提供者设置为提供者名称。例如，下面的字符串通过 MSOLAP Provider 连接到名为 Bobs Video Store 的目录，该目录位于名为 Servername 的服务器上：

"Data Source=Servername;Initial Catalog=Bobs Video Store;Provider=msolap"

下面的字符串连接到位于 C:\MSDASDK\samples\oledb\olap\data\bobsvid.cub 的本地立方文件：

"Location=C:\MSDASDK\samples\oledb\olap\data\bobsvid.cub;Provider=msolap"

请参阅

Visual Basic 范例

Connection 对象 | Open 方法

应用于：Catalog 对象 | Cellset 对象


Caption 属性 (ADO MD)

ADO 2.5 MD API 参考

Caption 属性

指示显示 Level 或 Member 对象时要使用的文本标题。

返回值

返回只读的 String。

请参阅

Visual Basic 范例

Description 属性

应用于：Level 对象 | Member 对象


ChildCount 属性 (ADO MD)

ADO 2.5 MD API 参考

ChildCount 属性

指示在分级结构中当前 Member 对象为其父的成员数目。

返回值

返回只读的 Long 整数。

说明

用 ChildCount 属性返回 Member 所拥有的子的估算数目。Member 的实际子可由 Children 属性返回。

对于 Position 对象的 Member 对象，返回的最大数目为 65536。如果子的实际数目超过 65536，仍返回 65536。因此，应用程序应将数值为 65536 的 ChildCount 解释为等于或大于 65536 个子。

对于 Level 对象的 Member 对象，请用 Children 集合上的 ADO 集合 Count 属性来确定子的确切数目。如果集合中子的数目很大，那么确定子的确切数目可能会比较慢。

请参阅

Children 属性 | Count 属性 | Members 集合

应用于：Member 对象


Children 属性 (ADO MD)

ADO 2.5 MD API 参考

Children 属性

返回在分级结构中当前 Member 为其父的 Members 集合。

返回值

返回只读的 Members 集合。

说明

Children 属性包含以当前 Member 作为分级结构的父的 Members 集合。在 Members 集合中，叶级别 Member 对象没有子成员。本属性只在属于 Level 对象的 Member 对象中受支持。当从属于 Position 对象的 Member 对象引用此属性时，将产生错误。

请参阅

ChildCount 属性

应用于：Member 对象


Depth 属性 (ADO MD)

ADO 2.5 MD API 参考

Depth 属性

指示 Level 和分级结构的根之间的级别数。

返回值

返回只读的整数。

说明

位于分级结构的根处的 Level 的 Depth 值为零 (0)。

请参阅

LevelDepth 属性

应用于：Level 对象


Description 属性 (ADO MD)

ADO 2.5 MD API 参考

Description 属性

返回当前对象的文本说明。

返回值

返回只读的 String。

说明

对于 Member 对象，Description 仅适用于度量和公式成员。对于所有其他类型的成员，Description 均返回空字符串 ("")。有关各种成员类型的详细信息，请参阅 Type 属性。

本属性只在属于 Level 对象的 Member 对象中受支持。当从属于 Position 对象的 Member 对象引用此属性时，将产生错误。

请参阅

应用于：CubeDef 对象 | Dimension 对象 | Hierarchy 对象 | Level 对象 | Member 对象


DimensionCount 属性 (ADO MD)

ADO 2.5 MD API 参考

DimensionCount 属性

指示轴上的维数。

返回值

返回只读的 Long 整数。

请参阅

VBScript 范例

Dimension 对象

应用于：Axis 对象


DrilledDown 属性 (ADO MD)

ADO 2.5 MD API 参考

DrilledDown 属性

指示轴上是否有子成员紧跟在该成员后面。

返回值

返回只读的 Boolean 值。如果轴上的当前成员没有子成员，DrilledDown 将返回 True。如果轴上的当前成员有一个或多个子成员，DrilledDown 将返回 False。

说明

用 DrilledDown 属性确定在轴上是否至少有一个该成员的子成员紧随其后。此信息在显示成员时很有用。

本属性只在属于 Position 对象的 Member 对象中受支持。当从属于 Level 对象的 Member 对象引用此属性时，将产生错误。

请参阅

ParentSameAsPrev 属性

应用于：Member 对象


FilterAxis 属性 (ADO MD)

ADO 2.5 MD API 参考

FilterAxis 属性

指示有关当前单元集的过滤器信息。

返回值

返回只读的 Axis 对象。

说明

用 FilterAxis 属性返回关于用于切割数据的维的信息。Axis 的 DimensionCount 属性返回切割器的维数。这个轴通常只有一行。

由 FilterAxis 返回的 Axis 不包含在 Cellset 对象的 Axes 集合中。

请参阅

Axis 对象 | Dimension 对象 | DimensionCount 属性

应用于：Cellset 对象


FormattedValue 属性 (ADO MD)

ADO 2.5 MD API 参考

FormattedValue 属性

指示单元值的格式化显示。

返回值

返回只读的 String。

说明

使用 FormattedValue 属性获取 Cell 对象 Value 属性的格式化的显示值。例如，如果单元值为 1056.87，并且此值表示美元数，那么 FormattedValue 为 $1,056.87。

请参阅

Visual Basic 范例

Value 属性

应用于：Cell 对象


Item 属性 (ADO MD Cellset)

ADO 2.5 MD API 参考

Item 属性 (Cellset)

使用其坐标来检索单元集中的单元。

语法

Set Cell = Cellset.Item ( Positions )

参数

Positions
唯一指定单元的 Variant Array 值。Positions 可以是：
  • 位置编号数组
  • 成员名称数组
  • 序号位置

说明

使用 Item 属性返回 Cellset 对象内的 Cell 对象。如果 Item 属性未找到与 Positions 参数相对应的单元，将产生错误。

Item 属性是 Cellset 对象的默认属性。下列语法形式可互换：

Cellset.Item ( Positions )
Cellset ( Positions )

Positions 参数指定要返回的单元。可以按序号位置或每个轴上的位置来指定单元。当按每个轴上的位置指定单元时，可以指定位置的数字值或每个位置的成员名称。

序号位置是唯一标识 Cellset 中一个单元的数字。从概念上讲，在 Cellset 中对单元进行编号就如同把 Cellset 当作一个 p 维数组，其中 p 是轴的数目。单元按以行为主的顺序定址。下面是计算单元序号的公式：

如果将成员名称作为字符串传递给 Item，那么成员必须按数字轴标识符的升序列出。在轴中，成员必须按嵌套维的升序列出，即首先是最外面的维的成员，然后是内部维的成员。每个维都应以单独的字符串表示，成员字符串的列表应以逗号分隔开。

注意 数据提供者可能不支持按成员名称检索单元。有关详细信息，请参阅提供者文档。

请参阅

Cell 对象

应用于：Cellset 对象


LevelDepth 属性 (ADO MD)

ADO 2.5 MD API 参考

LevelDepth 属性

指示分级结构的根与成员之间的级别数。

返回值

返回只读的 Long 整数。

说明

用 LevelDepth 属性确定 Member 对象与分级结构的根级别之间的距离。根级别处的成员的 LevelDepth 为 0。这与 Level 对象的 Depth 属性相对应。

请参阅

Depth 属性 | Level 对象

应用于：Member 对象


LevelName 属性 (ADO MD)

ADO 2.5 MD API 参考

LevelName 属性

指示成员的级别名称。

返回值

返回只读的 String。

说明

用 LevelName 属性检索成员所属的级别的名称。这与 Level 对象的 Name 属性相对应。

请参阅

Level 对象 | Name 属性

应用于：Member 对象


Name 属性 (ADO MD)

ADO 2.5 MD API 参考

Name 属性

指示对象的名称。

返回值

返回只读的 String。

说明

可以按序号引用来检索对象的 Name 属性，然后便可以直接按名称引用该对象。例如，如果 cdf.CubeDefs(0).Name 为“Bobs Video Store”，则可以按 cdf.CubeDefs("Bobs Video Store") 方式引用 CubeDef。

请参阅

Visual Basic 范例

Caption 属性 | Description 属性 | UniqueName 属性

应用于：Axis 对象 | Catalog 对象 | CubeDef 对象 | Dimension 对象 | Hierarchy 对象 | Level 对象 | Member 对象


Ordinal 属性 (ADO MD Cell)

ADO 2.5 MD API 参考

Ordinal 属性 (Cell)

通过其在单元集中的位置唯一标识单元。

返回值

返回只读的 Long 整数。

说明

单元的序号值唯一标识单元集内的单元。从概念上讲，在单元集中对单元进行编号就如同把单元集当作一个 p 维数组，其中 p 是轴的数目。单元按以行为主的顺序从零开始编号。下面是计算单元序号的公式：

单元的序号值可以同 Cellset 对象的 Item 属性一起使用，以快速检索 Cell。

请参阅

VBScript 范例

Cellset 对象 | Item 属性 (Cellset) | Ordinal 属性 (Position)

应用于：Cell 对象


Ordinal 属性 (ADO MD Position)

ADO 2.5 MD API 参考

Ordinal 属性 (Position)

唯一标识轴上的位置。

返回值

返回只读的 Long 整数。

说明

Position 对象的 Ordinal 对应于 Positions 集合中的 Position 索引。

通过配合使用每个轴上 Position 的 Ordinal 和 Cellset 对象的 Item 属性可以快速地检索单元。

请参阅

Cellset 对象 | Item 属性 (Cellset) | Ordinal 属性 (Cell)

应用于：Position 对象


Parent 属性 (ADO MD)

ADO 2.5 MD API 参考

Parent 属性

指示分级结构中当前成员的父成员。

返回值

返回只读的 Member 对象。

说明

位于分级结构的顶级别（根）位置的成员没有父。本属性只在属于 Level 对象的 Member 对象中受支持。当从属于 Position 对象的 Member 对象引用此属性时，将产生错误。

请参阅

Children 属性

应用于：Member 对象


ParentSameAsPrev 属性 (ADO MD)

ADO 2.5 MD API 参考

ParentSameAsPrev 属性

指示此位置成员的父是否与其前面一个成员的父相同。

返回值

返回只读的 Boolean 值。

说明

本属性只在属于 Position 对象的 Member 对象中受支持。当从属于 Level 对象的 Member 对象引用此属性时，将产生错误。

请参阅

DrilledDown 属性

应用于：Member 对象


Source 属性 (ADO MD)

ADO 2.5 MD API 参考

Source 属性

指示单元集中数据的源。

设置和返回值

设置或返回 Variant。对于关闭的 Cellset 对象，该值可读/写；而对于打开的 Cellset 对象，该值为只读。该 Variant 应包含有效的 String，如 MDX 查询。

请参阅

Visual Basic 范例

ActiveConnection 属性 | Open 方法

应用于：Cellset 对象


State 属性 (ADO MD)

ADO 2.5 MD API 参考

State 属性

指示单元集的当前状态。

返回值

返回只读的 Long 整数，指示 Cellset 对象的当前状态。下列值为有效值：adStateClosed (0) 和 adStateOpen (1)。

说明

要使用 ObjectStateEnum 常量名称，必须在工程中引用 ADO 类型库。有关详细信息，请参阅将 ADO MD 与 ADO 配合使用。

请参阅

Close 方法 | Open 方法

应用于：Cellset 对象


Type 属性 (ADO MD)

ADO 2.5 MD API 参考

Type 属性

指示当前成员的类型。

返回值

返回只读的 MemberTypeEnum 值。

说明

本属性只在从属于 Level 对象的 Member 对象中受支持。当从属于 Position 对象的 Member 对象引用此属性时，将产生错误。

请参阅

应用于：Member 对象


UniqueName 属性 (ADO MD)

ADO 2.5 MD API 参考

UniqueName 属性

指示当前对象的确切名称。

返回值

返回只读的 String。

请参阅

Name 属性

应用于：Dimension 对象 | Hierarchy 对象 | Level 对象 | Member 对象


Value 属性 (ADO MD)

ADO 2.5 MD API 参考

Value 属性

指示当前单元的值。

返回值

返回只读的 Variant。

请参阅

FormattedValue 属性

应用于：Cell 对象


ADO MD 方法

Close | 关闭打开的单元集。
Open | 检索多维查询的结果并将结果返回到单元集。

请参阅

ADO MD API 参考 | ADO MD 代码范例 | ADO MD 集合 | ADO MD 枚举常量 | ADO MD 对象模型 | ADO MD 对象 | ADO MD 属性

© 1998-2002 Microsoft Corporation。保留所有权利。


Close 方法 (ADO MD)

ADO 2.5 MD API 参考

Close 方法

关闭打开的单元集。

语法

Cellset.Close

说明

使用 Close 方法关闭 Cellset 对象将释放关联的数据，包括任何相关 Cell、Axis、Position 或 Member 对象中的数据。关闭 Cellset 并不将其从内存中删除，随后可以更改其属性设置并再次打开。要从内存中彻底清除对象，请将对象变量设置为 Nothing。

稍后可以使用同一个或其他源字符串调用 Open 方法重新打开 Cellset。当 Cellset 对象关闭时，凡是引用基本数据或元数据的操作，如检索属性或调用方法，都会产生错误。

请参阅

Axis 对象 | Cell 对象 | Member 对象 | Open 方法 | Position 对象 | State 属性

应用于：Cellset 对象


Open 方法 (ADO MD)

ADO 2.5 MD API 参考

Open 方法

检索多维查询的结果并将结果返回到单元集。

语法

Cellset.Open Source, ActiveConnection

Parameters

Source
可选。Variant，计算有效的多维查询，例如 Multidimensional Expression (MDX) 查询。Source 参数对应于 Source 属性。有关 MDX 的详细信息，请参阅 Microsoft Data Access Components SDK 中的 OLE DB for OLAP 文档。
ActiveConnection
可选。Variant，计算指定有效的 ADO Connection 对象变量名或连接的定义的字符串。ActiveConnection 参数指定打开 Cellset 对象的连接。如果传递此参数的连接定义，ADO 将用指定的参数打开新连接。ActiveConnection 参数对应于 ActiveConnection 属性。

说明

如果省略了 Open 方法的任何一个参数，并且在试图打开 Cellset 之前没有设置与此参数对应的属性值，那么该方法将产生错误。

请参阅

Visual Basic 范例

ActiveConnection 属性 | Close 方法 | Connection 对象 | Source 属性 | State 属性

应用于：Cellset 对象


ADO MD 枚举常量

为了帮助调试，ADO MD 枚举常量列出了每个常量的值。但是，此值仅供参考。在不同的 ADO MD 版本中，它可能会有变化。代码只应取决于枚举常量的名称，而不是实际值。

下面是已定义的枚举常量。

  • MemberTypeEnum

请参阅

ADO MD API 参考 | ADO MD 代码范例 | ADO MD 集合 | ADO MD 方法 | ADO MD 对象模型 | ADO MD 对象 | ADO MD 属性


MemberTypeEnum

指定 Member 对象的 Type 属性设置。

常量 | 值 | Description
adMemberAll | 4 | 指示 Member 对象表示该级别的所有成员。
adMemberFormula | 3 | 指示使用公式表达式计算 Member 对象。
adMemberMeasure | 2 | 指示 Member 对象属于 Measures 维并且表示数量属性。
adMemberRegular | 1 | 默认值。指示 Member 对象表示业务项的实例。
adMemberUnknown | 0 | 不能确定成员的类型。


ADO MD 代码范例

通过下列代码范例来学习如何使用 ADO MD 对象、方法和属性。这些范例是与 Microsoft SQL Server OLAP Services for SQL Server 7.0 一起安装的范例应用程序的子集。

这些范例使用 MSOLAP OLE DB 提供者，运行于 Microsoft SQL Server OLAP Services 本地主机。但是，由于这些范例将显示基本的 ADO MD 编程技术，因此它们应该很容易适应其他数据源或提供者。

  • Visual Basic 中的 ADO MD 代码范例
  • Visual Basic Scripting Edition 中的 ADO MD 代码范例

请参阅

ADO MD API 参考 | ADO MD 集合 | ADO MD 枚举常量 | ADO MD 方法 | ADO MD 对象模型 | ADO MD 对象 | ADO MD 属性


Visual Basic 中的 ADO MD 代码范例

以下范例需要安装了 Service Pack 3 的 Microsoft Visual Basic 5.0 或 Visual Basic 6.0。

注意 请将整个代码范例（从开始到结束）粘贴到代码编辑器中。如果只使用部分范例或者丢失了段落格式，范例可能无法正确运行。
  • Cellset 范例
  • Catalog 范例


Cellset 范例 (VB)

此 Visual Basic 工程演示使用 ADO MD 访问立方数据的基本过程。它显示列标头和行标头的成员标题，然后显示单元集中特定单元的格式化值。

Sub cmdCellSettoDebugWindow_Click()
    On Error GoTo Error_cmdCellSettoDebugWindow_Click

    Dim cat As New ADOMD.Catalog
    Dim cst As New ADOMD.CellSet
    Dim strServer As String
    Dim strSource As String
    Dim strColumnHeader As String
    Dim strRowText As String
    Dim i As Integer
    Dim j As Integer
    Dim k As Integer

    Screen.MousePointer = vbHourglass

    '*-----------------------------------------------------------------------
    '* Set Server to Local Host
    '*-----------------------------------------------------------------------
    strServer = "localhost"

    '*-----------------------------------------------------------------------
    '* Set MDX query string Source
    '*-----------------------------------------------------------------------
    strSource = "SELECT {[Measures].members} ON COLUMNS," & _
        "NON EMPTY [Store].[Store City].members ON ROWS FROM Sales"

    '*-----------------------------------------------------------------------
    '* Set Active Connection
    '*-----------------------------------------------------------------------
    cat.ActiveConnection = "Data Source=" & strServer & ";Provider=msolap;"

    '*-----------------------------------------------------------------------
    '* Set Cell Set source to MDX query string
    '*-----------------------------------------------------------------------
    cst.Source = strSource

    '*-----------------------------------------------------------------------
    '* Set Cell Sets active connection to current connection
    '*-----------------------------------------------------------------------
    Set cst.ActiveConnection = cat.ActiveConnection

    '*-----------------------------------------------------------------------
    '* Open Cell Set
    '*-----------------------------------------------------------------------
    cst.Open

    '*-----------------------------------------------------------------------
    '* Allow space for Row Header Text
    '*-----------------------------------------------------------------------
    strColumnHeader = vbTab & vbTab & vbTab & vbTab & vbTab & vbTab

    '*-----------------------------------------------------------------------
    '* Loop through Column Headers
    '*-----------------------------------------------------------------------
    For i = 0 To cst.Axes(0).Positions.Count - 1
        strColumnHeader = strColumnHeader & _
            cst.Axes(0).Positions(i).Members(0).Caption & vbTab & _
            vbTab & vbTab & vbTab
    Next
    Debug.Print vbTab & strColumnHeader & vbCrLf

    '*-----------------------------------------------------------------------
    '* Loop through Row Headers and Provide data for each row
    '*-----------------------------------------------------------------------
    strRowText = ""
    For j = 0 To cst.Axes(1).Positions.Count - 1
        strRowText = strRowText & _
            cst.Axes(1).Positions(j).Members(0).Caption & vbTab & _
                vbTab & vbTab & vbTab
        For k = 0 To cst.Axes(0).Positions.Count - 1
            strRowText = strRowText & cst(k, j).FormattedValue & _
                vbTab & vbTab & vbTab & vbTab
        Next
        Debug.Print strRowText & vbCrLf
        strRowText = ""
    Next

    Screen.MousePointer = vbDefault

    Exit Sub

Error_cmdCellSettoDebugWindow_Click:
   Beep
   Screen.MousePointer = vbDefault
   Set cat = Nothing
   Set cst = Nothing
   MsgBox "The Following Error has occurred:" & vbCrLf & _
      Err.Description, vbCritical, " Error!"
   Exit Sub
End Sub


Catalog 范例 (VB)

此 Visual Basic 工程使用 MDX 创建新立方。然后，在 Microsoft Word 文档中说明立方的结构。

Sub cmdCreateDocForCube_Click()
    On Error GoTo Error_cmdCreateDocForCube_Click

    Dim cn As ADODB.Connection
    Dim s As String
    Dim strProvider As String
    Dim strDataSource As String
    Dim strSourceDSN As String
    Dim strSourceDSNSuffix As String
    Dim strCreateCube As String
    Dim strInsertInto As String

    '*-----------------------------------------------------------------------
    '* The following code builds a cube file then documents the properties
    '* with an OLE Connection to Word 8.0
    '*-----------------------------------------------------------------------

    '*-----------------------------------------------------------------------
    '* Add Provider to the connection string.
    '*-----------------------------------------------------------------------
    strProvider = "PROVIDER=MSOLAP"

    '*-----------------------------------------------------------------------
    '* Add DataSource, the name of the file we will create.
    '*-----------------------------------------------------------------------

    strDataSource = "DATA SOURCE=c:\DocumentCube.cub"

    '*-----------------------------------------------------------------------
    '* Add Source DSN, the connection string for where the data comes from.
    '* We need to quote the value so it is parsed as one value.
    '* This can either be an ODBC connection string or an OLE DB connection
    '* string. (As returned by the Data Source Locator component.)
    '*-----------------------------------------------------------------------
    strSourceDSN = "SOURCE_DSN=FoodMart 2000"

    '*-----------------------------------------------------------------------
    '* Add CREATE CUBE.  This defines the structure of the cube, but not the
    '* data in it. The BNF for is documented in the OLE DB for OLAP
    '* Programmer's Reference. Note that we can quote names with either
    '* double quotes or square brackets.
    '*-----------------------------------------------------------------------
    strCreateCube = "CREATECUBE=CREATE CUBE Sample( "
    strCreateCube = strCreateCube & "DIMENSION [Product],"
    strCreateCube = strCreateCube & "LEVEL [All Products]  TYPE ALL,"
    strCreateCube = strCreateCube & "LEVEL [Product Family] ,"
    strCreateCube = strCreateCube & "LEVEL [Product Department] ,"
    strCreateCube = strCreateCube & "LEVEL [Product Category] ,"
    strCreateCube = strCreateCube & "LEVEL [Product Subcategory] ,"
    strCreateCube = strCreateCube & "LEVEL [Brand Name] ,"
    strCreateCube = strCreateCube & "LEVEL [Product Name] ,"
    strCreateCube = strCreateCube & "DIMENSION [Store],"
    strCreateCube = strCreateCube & "LEVEL [All Stores]  TYPE ALL,"
    strCreateCube = strCreateCube & "LEVEL [Store Country] ,"
    strCreateCube = strCreateCube & "LEVEL [Store State] ,"
    strCreateCube = strCreateCube & "LEVEL [Store City] ,"
    strCreateCube = strCreateCube & "LEVEL [Store Name] ,"
    strCreateCube = strCreateCube & "DIMENSION [Store Type],"
    strCreateCube = strCreateCube & _
        "LEVEL [All Store Type]  TYPE ALL,"
    strCreateCube = strCreateCube & "LEVEL [Store Type] ,"
    strCreateCube = strCreateCube & "DIMENSION [Time] TYPE TIME,"
    strCreateCube = strCreateCube & "HIERARCHY [Column],"
    strCreateCube = strCreateCube & "LEVEL [All Time]  TYPE ALL,"
    strCreateCube = strCreateCube & "LEVEL [Year]  TYPE YEAR,"
    strCreateCube = strCreateCube & "LEVEL [Quarter]  TYPE QUARTER,"
    strCreateCube = strCreateCube & "LEVEL [Month]  TYPE MONTH,"
    strCreateCube = strCreateCube & "LEVEL [Week]  TYPE WEEK,"
    strCreateCube = strCreateCube & "LEVEL [Day]  TYPE DAY,"
    strCreateCube = strCreateCube & "HIERARCHY [Formula],"
    strCreateCube = strCreateCube & _
        "LEVEL [All Formula Time]  TYPE ALL,"
    strCreateCube = strCreateCube & "LEVEL [Year]  TYPE YEAR,"
    strCreateCube = strCreateCube & "LEVEL [Quarter]  TYPE QUARTER,"
    strCreateCube = strCreateCube & _
        "LEVEL [Month]  TYPE MONTH OPTIONS (SORTBYKEY) ,"
    strCreateCube = strCreateCube & "DIMENSION [Warehouse],"
    strCreateCube = strCreateCube & _
        "LEVEL [All Warehouses]  TYPE ALL,"
    strCreateCube = strCreateCube & "LEVEL [Country] ,"
    strCreateCube = strCreateCube & "LEVEL [State Province] ,"
    strCreateCube = strCreateCube & "LEVEL [City] ,"
    strCreateCube = strCreateCube & "LEVEL [Warehouse Name] ,"
    strCreateCube = strCreateCube & "MEASURE [Store Invoice] "
    strCreateCube = strCreateCube & "Function Sum "
    strCreateCube = strCreateCube & "Format '#.#',"
    strCreateCube = strCreateCube & "MEASURE [Supply Time] "
    strCreateCube = strCreateCube & "Function Sum "
    strCreateCube = strCreateCube & "Format '#.#',"
    strCreateCube = strCreateCube & "MEASURE [Warehouse Cost] "
    strCreateCube = strCreateCube & "Function Sum "
    strCreateCube = strCreateCube & "Format '#.#',"
    strCreateCube = strCreateCube & "MEASURE [Warehouse Sales] "
    strCreateCube = strCreateCube & "Function Sum "
    strCreateCube = strCreateCube & "Format '#.#',"
    strCreateCube = strCreateCube & "MEASURE [Units Shipped] "
    strCreateCube = strCreateCube & "Function Sum "
    strCreateCube = strCreateCube & "Format '#.#',"
    strCreateCube = strCreateCube & "MEASURE [Units Ordered] "
    strCreateCube = strCreateCube & "Function Sum "
    strCreateCube = strCreateCube & "Format '#.#')"
    '*-----------------------------------------------------------------------
    '* Add INSERT INTO.  This defines where the data comes from, and how it
    '* maps into the already-defined cube structure.  Note that the SELECT
    '* clause might just be passed through to the relational database.
    '* So I could pass in a stored procedure, for example.  If we needed to,
    '* we could quote this whole thing.  Note that the columns in the SELECT
    '* can be in any order.  One merely has to adjust the ordering of the
    '* list of level/measure names to match the SELECT ordering.
    '*-----------------------------------------------------------------------
    strInsertInto = strInsertInto & _
        "INSERTINTO=INSERT INTO Sample( " & _
        "Product.[Product Family], Product.[Product Department],"
    strInsertInto = strInsertInto & _
        "Product.[Product Category], Product.[Product Subcategory],"
    strInsertInto = strInsertInto & _
        "Product.[Brand Name], Product.[Product Name],"
    strInsertInto = strInsertInto & _
        "Store.[Store Country], Store.[Store State], Store.[Store City],"
    strInsertInto = strInsertInto & _
        "Store.[Store Name], [Store Type].[Store Type], [Time].[Column],"
    strInsertInto = strInsertInto & _
        "[Time].Formula.Year, [Time].Formula.Quarter, " & _
        "[Time].Formula.Month.[Key],"
    strInsertInto = strInsertInto & _
        "[Time].Formula.Month.Name, Warehouse.Country, " & _
        "Warehouse.[State Province],"
    strInsertInto = strInsertInto & _
        "Warehouse.City, Warehouse.[Warehouse Name], " & _
        "Measures.[Store Invoice],"
    strInsertInto = strInsertInto & _
        "Measures.[Supply Time], Measures.[Warehouse Cost], " & _
        "Measures.[Warehouse Sales],"
    strInsertInto = strInsertInto & _
        "Measures.[Units Shipped], Measures.[Units Ordered] )"
    '*-----------------------------------------------------------------------
    '* Add some options to the INSERT INTO if we need to.  These can control
    '* if the SELECT clause is analyzed or just passed through, and if the
    '* storage mode is MOLAP or ROLAP (DEFER_DATA).
    '* strInsertInto = strInsertInto & " OPTIONS ATTEMPT_ANALYSIS"
    '*-----------------------------------------------------------------------

    '*-----------------------------------------------------------------------
    '* Add the SELECT clause of the INSERT INTO statement.  Note that it is
    '* merely concatenated onto the end of the INSERT INTO statement.  OLAP
    '* Services will pass this through to the source database if unable to
    '* parse it.  Note that for OLAP Services to analyze the SELECT clause,
    '* each column must be qualified with the table name.
    '*-----------------------------------------------------------------------

    strInsertInto = strInsertInto & _
        "SELECT product_class.product_family AS Col1,"
    strInsertInto = strInsertInto & _
        "product_class.product_department AS Col2,"
    strInsertInto = strInsertInto & "product_class.product_category AS Col3,"
    strInsertInto = strInsertInto & _
        "product_class.product_subcategory AS Col4,"
    strInsertInto = strInsertInto & "product.brand_name AS Col5,"
    strInsertInto = strInsertInto & "product.product_name AS Col6,"
    strInsertInto = strInsertInto & "store.store_country AS Col7,"
    strInsertInto = strInsertInto & "store.store_state AS Col8,"
    strInsertInto = strInsertInto & "store.store_city AS Col9,"
    strInsertInto = strInsertInto & "store.store_name AS Col10,"
    strInsertInto = strInsertInto & "store.store_type AS Col11,"
    strInsertInto = strInsertInto & "time_by_day.the_date AS Col12,"
    strInsertInto = strInsertInto & "time_by_day.the_year AS Col13,"
    strInsertInto = strInsertInto & "time_by_day.quarter AS Col14,"
    strInsertInto = strInsertInto & "time_by_day.month_of_year AS Col15,"
    strInsertInto = strInsertInto & "time_by_day.the_month AS Col16,"
    strInsertInto = strInsertInto & "warehouse.warehouse_country AS Col17,"
    strInsertInto = strInsertInto & _
        "warehouse.warehouse_state_province AS Col18,"
    strInsertInto = strInsertInto & "warehouse.warehouse_city AS Col19,"
    strInsertInto = strInsertInto & "warehouse.warehouse_name AS Col20,"
    strInsertInto = strInsertInto & _
        "inventory_fact_1997.store_invoice AS Col21,"
    strInsertInto = strInsertInto & _
        "inventory_fact_1997.supply_time AS Col22,"
    strInsertInto = strInsertInto & _
        "inventory_fact_1997.warehouse_cost AS Col23,"
    strInsertInto = strInsertInto & _
        "inventory_fact_1997.warehouse_sales AS Col24,"
    strInsertInto = strInsertInto & _
        "inventory_fact_1997.units_shipped AS Col25,"
    strInsertInto = strInsertInto & _
        "inventory_fact_1997.units_ordered AS Col26 "
    strInsertInto = strInsertInto & _
        "From [inventory_fact_1997], [product], [product_class], " & _
        "[time_by_day], [store], [warehouse] "
    strInsertInto = strInsertInto & _
        "Where [inventory_fact_1997].[product_id] = [product]." & _
        "[product_id] And "
    strInsertInto = strInsertInto & _
        "[product].[product_class_id] = [product_class]." & _
        "[product_class_id] And "
    strInsertInto = strInsertInto & _
        "[inventory_fact_1997].[time_id] = [time_by_day].[time_id] And "
    strInsertInto = strInsertInto & _
        "[inventory_fact_1997].[store_id] = [store].[store_id] And "
    strInsertInto = strInsertInto & _
        "[inventory_fact_1997].[warehouse_id] = [warehouse].[warehouse_id]"

    '*-----------------------------------------------------------------------
    '* Create the cube by passing connection string to Open.
    '*-----------------------------------------------------------------------

    Set cn = New ADODB.Connection
    s = strProvider & ";" & strDataSource & ";" & strSourceDSN & ";" & _
        strCreateCube & ";" & strInsertInto & ";"
    Screen.MousePointer = vbHourglass
    cn.Open s

    '*-----------------------------------------------------------------------
    '* Cube file is written to hard drive a Word Document can be produced by
    '* automating Word with VB
    '*-----------------------------------------------------------------------

    Dim cat As New ADOMD.Catalog
    Dim cdf As ADOMD.CubeDef
    Dim i As Integer
    Dim di As Integer
    Dim hi As Integer
    Dim le As Integer
    Dim mem As Integer
    Dim docWord As Word.Document
    Dim rngCurrent As Word.Range
    Dim SenCount As Integer
    Dim strServer As String
    Dim strSource As String
    Dim strCubeName As String
    Dim appWord As Object
    '*-----------------------------------------------------------------------
    '* Connection is made to cube file
    '*-----------------------------------------------------------------------
    cat.ActiveConnection = "DATA SOURCE=c:\DocumentCube.cub;Provider=msolap;"

    '*-----------------------------------------------------------------------
    '* Cube Definition is set to Name of Cube in cube file
    '*-----------------------------------------------------------------------
    Set cdf = cat.CubeDefs("Sample")

    '*-----------------------------------------------------------------------
    '* Object is created to hold Word
    '*-----------------------------------------------------------------------
    Set appWord = CreateObject("Word.Application")

    '*-----------------------------------------------------------------------
    '* Create the document variable
    '*-----------------------------------------------------------------------
    Set docWord = appWord.Documents.Add()

    Set rngCurrent = docWord.Content

    SenCount = 0

    '*-----------------------------------------------------------------------
    '* Cube Title and Header written to Document
    '*-----------------------------------------------------------------------
    With rngCurrent
        .InsertAfter "Report for Sample Cube"
        .InsertAfter vbCrLf
        SenCount = SenCount + 1
        docWord.Paragraphs(SenCount).Range.Bold = True
        docWord.Paragraphs(SenCount).Range.Underline = wdUnderlineSingle
        docWord.Paragraphs(SenCount).Range.Italic = False
        docWord.Paragraphs(SenCount).Range.Font.Size = 18

        '*-----------------------------------------------------------------------
        '* Properties of Cube are written to Document
        '*-----------------------------------------------------------------------
        Debug.Print "Properties of Cube are written to Document"
        For i = 0 To cdf.Properties.Count - 1
            .InsertAfter "(" & i & ") " & cdf.Properties(i).Name & ": " & _
                cdf.Properties(i).Value
            .InsertAfter vbCrLf
            SenCount = SenCount + 1
            docWord.Paragraphs(SenCount).Range.Bold = False
            docWord.Paragraphs(SenCount).Range.Italic = True
            docWord.Paragraphs(SenCount).Range.Font.Size = 8
        Next i

        '*-----------------------------------------------------------------------
        '* Dimension Name(s) written to Document
        '*-----------------------------------------------------------------------
        Debug.Print "Dimension Name(s) written to Document"
        For di = 0 To cdf.Dimensions.Count - 1
            .InsertAfter "Dimension: " & cdf.Dimensions(di).Name
            .InsertAfter vbCrLf
            SenCount = SenCount + 1
            docWord.Paragraphs(SenCount).Range.Bold = True
            docWord.Paragraphs(SenCount).Range.Italic = False
            docWord.Paragraphs(SenCount).Range.Font.Size = 14

            '*-----------------------------------------------------------------------
            '* Properties of Dimension are written to Document
            '*-----------------------------------------------------------------------
            Debug.Print "Properties of Dimension are written to Document"
            For i = 0 To cdf.Dimensions(di).Properties.Count - 1
                .InsertAfter "(" & i & ") " & _
                    cdf.Dimensions(di).Properties(i).Name & ": " & _
                    cdf.Dimensions(di).Properties(i).Value
                .InsertAfter vbCrLf
                SenCount = SenCount + 1
                docWord.Paragraphs(SenCount).Range.Bold = False
                docWord.Paragraphs(SenCount).Range.Italic = True
                docWord.Paragraphs(SenCount).Range.Font.Size = 8
            Next i

            '*-----------------------------------------------------------------------
            '* Hierarchy Name(s) written to Document
            '*-----------------------------------------------------------------------
            Debug.Print "Hierarchy Name(s) written to Document"
            For hi = 0 To cdf.Dimensions(di).Hierarchies.Count - 1
                .InsertAfter vbTab & "Hierarchy: " & _
                    cdf.Dimensions(di).Hierarchies(hi).Name
                .InsertAfter vbCrLf
                SenCount = SenCount + 1
                docWord.Paragraphs(SenCount).Range.Bold = True
                docWord.Paragraphs(SenCount).Range.Italic = False
                docWord.Paragraphs(SenCount).Range.Font.Size = 12

                '*-----------------------------------------------------------------------
                '* Properties of Hierarchy are written to Document
                '*-----------------------------------------------------------------------
                Debug.Print "Properties of Hierarchy are written to Document"
                For i = 0 To cdf.Dimensions(di).Hierarchies(hi).Properties.Count - 1
                    .InsertAfter vbTab & "(" & i & ") " & _
                        cdf.Dimensions(di).Hierarchies(hi).Properties(i).Name & _
                        ": " & cdf.Dimensions(di).Hierarchies(hi).Properties(i).Value
                    .InsertAfter vbCrLf
                    SenCount = SenCount + 1
                    docWord.Paragraphs(SenCount).Range.Bold = False
                    docWord.Paragraphs(SenCount).Range.Italic = True
                    docWord.Paragraphs(SenCount).Range.Font.Size = 8
                Next i

                '*-----------------------------------------------------------------------
                '* Level Name(s) written to Document
                '*-----------------------------------------------------------------------
                Debug.Print "Level Name(s) written to Document"
                For le = 0 To cdf.Dimensions(di).Hierarchies(hi).Levels.Count - 1
                    .InsertAfter vbTab & vbTab & "Level: " & _
                        cdf.Dimensions(di).Hierarchies(hi).Levels(le).Name & _
                        " with a Member Count of: " & _
                        cdf.Dimensions(di).Hierarchies(hi).Levels(le).Members.Count
                    .InsertAfter vbCrLf
                    SenCount = SenCount + 1
                    docWord.Paragraphs(SenCount).Range.Bold = True
                    docWord.Paragraphs(SenCount).Range.Italic = False
                    docWord.Paragraphs(SenCount).Range.Font.Size = 10

                    '*-----------------------------------------------------------------------
                    '* Properties of Level are written to Document
                    '*-----------------------------------------------------------------------
                    Debug.Print "Properties of Level are written to Document"
                    For i = 0 To _
                       cdf.Dimensions(di).Hierarchies(hi).Levels(le).Properties.Count - 1
                        .InsertAfter vbTab & vbTab & "(" & i & ") " & _
                             cdf.Dimensions(di).Hierarchies(hi).Levels(le).Properties(i).Name & ": " & _
                             cdf.Dimensions(di).Hierarchies(hi).Levels(le).Properties(i).Value
                        .InsertAfter vbCrLf
                        SenCount = SenCount + 1
                        docWord.Paragraphs(SenCount).Range.Bold = False
                        docWord.Paragraphs(SenCount).Range.Italic = True
                        docWord.Paragraphs(SenCount).Range.Font.Size = 8
                    Next i

                Next le
            Next hi
        Next di

        '*-----------------------------------------------------------------------
        '* Set Word Document to visible
        '*-----------------------------------------------------------------------
        Debug.Print "Set Word Document to visible"
        appWord.Visible = True
    End With

    Screen.MousePointer = vbDefault

    '*-----------------------------------------------------------------------
    '* Set Word Object to nothing to drop OLE connection
    '*-----------------------------------------------------------------------
    Set appWord = Nothing
Exit Sub

Error_cmdCreateDocForCube_Click:
    cn.Cancel
    Set cn = Nothing
    Screen.MousePointer = vbDefault
    MsgBox Err.Description
End Sub


Visual Basic Scripting Edition 中的 ADO MD 代码范例

以下范例需要 Microsoft Active Server Pages (ASP) for Microsoft Internet Information Server 4.0。

注意 请将整个代码范例（从开始到结束）粘贴到代码编辑器中。如果只使用部分范例或者丢失了段落格式，范例可能无法正确运行。
  • Axis 范例
  • Members 范例
  • CubeDef 范例


Axis 范例 (VBScript)

此 Active Server Page 显示 MDX 查询字符串中的 OLAP 数据，并将所得到的单元集写入 HTML 表结构。

<%@ Language=VBScript %>
<%
'************************************************************************
'*** Active Server Page displays OLAP data from default
'*** MDX Query string and writes resulting cell set to HTML table
'*** structure.
'************************************************************************
Response.Buffer=True
Response.Expires=0
%>
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</HEAD>
<BODY bgcolor=Ivory>
<FONT FACE=Verdana>

<%

Dim cat,cst,i,j,strSource,csw,intDC0,intDC1,intPC0,intPC1

'************************************************************************
'*** Set Connection Objects for Multidimensional Catalog and Cellset
'************************************************************************
Set cat = Server.CreateObject("ADOMD.Catalog")
Set cst = Server.CreateObject("ADOMD.CellSet")

'************************************************************************
'*** Use default settings of a known OLAP Server
'*** for Server Name for Connection Set Server Name Session Object
'*** to default value
'************************************************************************
'*** Must set OLAPServerName to OLAP Server that is
'*** present on network
'************************************************************************
   OLAPServerName = "Please set to present OLAP Server"
   cat.ActiveConnection = "Data Source='" & OLAPServerName & _
      "';Initial Catalog='FoodMart';Provider='msolap';"

'************************************************************************
'*** Use default MDX Query string of a known query that works
'*** with default server Set MDXQuery Session Object to default value
'************************************************************************
   strSource = strSource & "SELECT "
   strSource = strSource & "{[Measures].members} ON COLUMNS,"
   strSource = strSource & _
      "NON EMPTY [Store].[Store City].members ON ROWS"
   strSource = strSource & " FROM Sales"

'************************************************************************
'*** Set Cell Set Source property to strSource to be passed on cell set '*** open method
'************************************************************************
    cst.Source = strSource

'************************************************************************
'*** Set Cell Sets Active connection to use the current Catalogs Active
'*** connection
'************************************************************************
Set cst.ActiveConnection = cat.ActiveConnection

'************************************************************************
'*** Using Open method, Open cell set
'************************************************************************
cst.Open

'************************************************************************
'*** Set Dimension Counts minus 1 for Both Axes to intDC0, intDC1
'*** Set Position Counts minus 1 for Both Axes to intPC0, intPC1
'************************************************************************
intDC0 = cst.Axes(0).DimensionCount-1
intDC1 = cst.Axes(1).DimensionCount-1

intPC0 = cst.Axes(0).Positions.Count - 1
intPC1 = cst.Axes(1).Positions.Count - 1

'************************************************************************
'*** Create HTML Table structure to hold MDX Query return Record set
'************************************************************************
      Response.Write "<Table width=100% border=1>"

'************************************************************************
'*** Loop to create Column header
'************************************************************************
      For h=0 to intDC0
         Response.Write "<TR>"

'************************************************************************
'*** Loop to create spaces in front of Column headers
'*** to align with Row header
'************************************************************************
         For c=0 to intDC1
            Response.Write "<TD></TD>"
         Next

'************************************************************************
'*** Iterate through Axes(0) Positions writing member captions to table
'*** header
'************************************************************************
         For i = 0 To intPC0
            Response.Write "<TH>"
            Response.Write "<FONT size=-2>"
            Response.Write cst.Axes(0).Positions(i).Members(h).Caption
            Response.Write "</FONT>"
            Response.Write "</TH>"
         Next
         Response.Write "</TR>"
      Next
'************************************************************************
'*** Use Array values for row header formatting to provide
'*** spaces under beginning row header titles
'************************************************************************
      For j = 0 To intPC1
         Response.Write "<TR>"
         For h=0 to intDC1
            Response.Write "<TD><B>"
            Response.Write "<FONT size=-2>"
            Response.Write cst.Axes(1).Positions(j).Members(h).Caption
            Response.Write "</FONT>"
            Response.Write "</B></TD>"
         Next
         For k = 0 To intPC0
            Response.Write "<TD align=right bgcolor="
            Response.Write csw
            Response.Write ">"
            Response.Write "<FONT size=-2>"
            Response.Write cst(k, j).FormattedValue
            Response.Write "</FONT>"
            Response.Write "</TD>"
         Next
         Response.Write "</TR>"
      Next
      Response.Write "</Table>"

%>
</FONT>
</BODY>
</HTML>


Members 范例 (VBScript)

此范例用 MDX 查询字符串检索 OLAP 数据，并用多维单元集的列跨越功能将所得到的单元集写入 HTML 表结构。

<%@ Language=VBScript %>
<%
'************************************************************************
'*** Active Server Page displays OLAP data from default or provided
'*** MDX Query string and writes resulting cell set to HTML table
'*** structure. This ASP provides colspan features for multiple
'*** dimension cell sets.
'************************************************************************
Response.Buffer=True
Response.Expires=0
%>
<html>
<head>
</head>
<body bgcolor="Ivory">
<font FACE="Verdana">

<%

Dim cat,cst,i,j,strSource,csw,LevelValue,intDC0,intDC1,intPC0, intPC1
'************************************************************************
'*** Gather Server Name and MDX Query Strings from text box and
'*** text area and assign them to Session Objects of same name
'************************************************************************
Session("ServerName")=Request.Form("strServerName")
Session("InitialCatalog")=Request.Form("strInitialCatalog")
Session("MDXQuery")=Request.Form("MDXQuery")

'************************************************************************
'*** Set Connection Objects for Multi dimensional Catalog and Cell Set
'************************************************************************
Set cat = Server.CreateObject("ADOMD.Catalog")
Set cst = Server.CreateObject("ADOMD.CellSet")

'************************************************************************
'*** Check to see if the Session Object Server Name is present
'*** If present then: Create Active Connection using Server Name
'*** and MSOLAP as connection Provider
'*** If not present then: Use default settings of a known OLAP Server
'*** for Server Name for Connection Set Server Name Session Object
'*** to default value
'************************************************************************
If Len(Session("ServerName")) > 0 Then
   cat.ActiveConnection = "Data Source='" & Session("ServerName") & _
      "';Initial Catalog='" & Session("InitialCatalog") & _
      "';Provider='msolap';"
Else

'************************************************************************
'*** Must set OLAPServerName to OLAP Server that is
'*** present on network
'************************************************************************
   OLAPServerName = "Please set to present OLAP Server"
   cat.ActiveConnection = "Data Source=" & OLAPServerName & _
      ";Initial Catalog=FoodMart;Provider=msolap;"
   Session("ServerName") = OLAPServerName
   Session("InitialCatalog") = "FoodMart"
End if
'************************************************************************
'*** Check to see if the Session Object MDXQuery is present
'*** If present then: Set strSource using MDXQuery Session Object
'*** If not present then: Use default MDX Query string of a known query
'*** that works with default server Set MDXQuery Session Object to
'*** default value
'************************************************************************
If Len(Session("MDXQuery")) < 5 Then
   strSource = strSource & "SELECT "
   strSource = strSource & "CROSSJOIN({[Store].[Store Country].MEMBERS},"
   strSource = strSource & "{[Measures].[Store " & _
      "Invoice],[Measures].[Supply Time]}) ON COLUMNS,"
   strSource = strSource & "CROSSJOIN({[Time].[Year].MEMBERS},"
   strSource = strSource & "CROSSJOIN({[Store Type].[Store " & _
      "Type].Members},{[Product].[Product Family].members})) ON ROWS"
   strSource = strSource & " FROM Warehouse"
Else
   strSource = Session("MDXQuery")
End if

'************************************************************************
'*** Set Cell Set Source property to strSource to be passed on cell set
'*** open method
'************************************************************************
   cst.Source = strSource

'************************************************************************
'*** Set Cell Sets Active connection to use the current Catalogs Active
'*** connection
'************************************************************************
Set cst.ActiveConnection = cat.ActiveConnection

'************************************************************************
'*** Using Open method, Open cell set
'************************************************************************
cst.Open

'************************************************************************
'*** Standard HTML to collect Server Name and MDX Query Information
'*** Note that post action posts back to same page to process
'*** thus using state of Session Variables to change look of page
'************************************************************************
%>
<form action="ASPADOComplex.asp" method="POST" id="form1" name="form1">
<table>
<tr><td align="left">
<b>Olap Server name:</b><br><input type="text" id="strServerName" name="strServerName" value="<%=Session("ServerName")%>" size="20">
<br>
<b>Catalog name:</b><br><input type="text" id="strInitialCatalog" name="strInitialCatalog" value="<%=Session("InitialCatalog")%>" size="20">
</td><td align="center">
<b>MDX Query:</b><br>
<textarea rows="7" cols="70" id="textareaMDX" name="MDXQuery" wrap="soft">
<%=Session("MDXQuery")%>
</textarea>
</td></tr>
</table>
<table>
<tr><td>
<input type="submit" value="Submit MDX Query" id="submit1" name="submit1">
</td><td>
<input type="reset" value="Reset" id="reset1" name="reset1">
</td></tr>
</table>
</form>
<p align="left">
<font color="Black" size="-3">
<%=strSource%>
</font>
</p>
<%
'************************************************************************
'*** Set Dimension Counts minus 1 for Both Axes to intDC0, intDC1
'*** Set Position Counts minus 1 for Both Axes to intPC0, intPC1
'************************************************************************
intDC0 = cst.Axes(0).DimensionCount-1
intDC1 = cst.Axes(1).DimensionCount-1

intPC0 = cst.Axes(0).Positions.Count - 1
intPC1 = cst.Axes(1).Positions.Count - 1

'************************************************************************
'*** Create HTML Table structure to hold MDX Query return Record set
'************************************************************************
Response.Write "<Table width=100% border=1>"

'************************************************************************
'*** Loop to create Column header for all Dimensions based
'*** on Count of Dimensions for Axes(0)
'************************************************************************
For h=0 to intDC0
   Response.Write "<TR>"

'************************************************************************
'*** Loop to create spaces in front of Column headers
'*** to align with Row headers
'************************************************************************
   For c=0 to intDC1
      Response.Write "<TD></TD>"
   Next

'************************************************************************
'*** Check current dimension to see if equal to Last Dimension
'*** If True: Write Table header titles normally to HTML output with out
'*** ColSpan value
'*** If False: Write Table header titles with ColSpan values to HTML
'*** output
'************************************************************************
   If h = intDC0 then

'************************************************************************
'*** Iterate through Axes(0) Positions writing member captions to table
'*** header
'************************************************************************
      For i = 0 To intPC0
         Response.Write "<TH>"
         Response.Write "<FONT size=-2>"
         Response.Write cst.Axes(0).Positions(i).Members(h).Caption
         Response.Write "</FONT>"
         Response.Write "</TH>"
      Next
   Else

'************************************************************************
'*** Iterate through Axes(0) Positions writing member captions to table
'*** header taking into account for the span of columns for duplicate
'*** member captions
'************************************************************************
      CaptionCount = 1
      LastCaption = cst.Axes(0).Positions(0).Members(h).Caption
      Response.Write "<TH"
      For t=1 to intPC0

'************************************************************************
'*** Check to see if LastCaption is equal to current members caption
'*** If True: Add one to CaptionCount to increase Colspan value
'*** If False: Write Table header titles with ColSpan values to HTML
'*** output using current CaptionCount for Colspan and LastCaption for
'*** header string
'************************************************************************
         If LastCaption = _
            cst.Axes(0).Positions(t).Members(h).Caption then
            CaptionCount = CaptionCount+1

'************************************************************************
'*** Check if at last position
'*** If True: Write HTML to finish table row using current
'*** CaptionCount and LastCaption
'************************************************************************
            If t = intPC0 then
               Response.Write " colspan=" & CaptionCount & _
                  "><FONT size=-2>" & LastCaption & "</FONT></TH>"
            End if

         Else
            Response.Write " colspan=" & CaptionCount & _
               "><FONT size=-2>" & LastCaption & "</FONT></TH><TH"
            CaptionCount = 1
            LastCaption=cst.Axes(0).Positions(t).Members(h).Caption
         End if
      Next
         End if
         Response.Write "</TR>"
      Next

'************************************************************************
'*** Iterate through Axes(1) Positions first writing member captions
'*** to table row headers then writing cell set data to table structure
'************************************************************************
      Dim aryRows()
      Dim intArray,Marker
      intArray=0

'************************************************************************
'*** Set value of Array for row header formatting
'************************************************************************
      For a=1 To intDC1
         intArray = intArray+(intPC1+1)
      Next
      intArray = intArray-1
      ReDim aryRows(intArray)
      Marker=0

'************************************************************************
'*** Use Array values for row header formatting to provide
'*** spaces under beginning row header titles
'************************************************************************
      For j = 0 To intPC1
         Response.Write "<TR>"
         For h=0 to intDC1
            If h=intDC1 then
               Response.Write "<TD><B>"
               Response.Write "<FONT size=-2>"
               Response.Write cst.Axes(1).Positions(j).Members(h).Caption
               Response.Write "</FONT>"
               Response.Write "</B></TD>"
            Else
               aryRows(Marker) = _
                  cst.Axes(1).Positions(j).Members(h).Caption
               If Marker < intDC1 then
                  Response.Write "<TD><B>"
                  Response.Write "<FONT size=-2>"
                  Response.Write _
                     cst.Axes(1).Positions(j).Members(h).Caption
                  Response.Write "</FONT>"
                  Response.Write "</B></TD>"
                  Marker = Marker + 1
               Else
                  If aryRows(Marker) = aryRows(Marker - intDC1) then
                     Response.Write "<TD>&nbsp;</TD>"
                     Marker = Marker + 1
                  Else
                     Response.Write "<TD><B>"
                     Response.Write "<FONT size=-2>"
                     Response.Write _
                        cst.Axes(1).Positions(j).Members(h).Caption
                     Response.Write "</FONT>"
                     Response.Write "</B></TD>"
                     Marker = Marker + 1
                  End if
               End if
            End if
         Next

'************************************************************************
'*** Alternates Cell background color
'************************************************************************
         If (j+1) Mod 2 = 0 Then
            csw = "#cccccc"
         Else
            csw = "#ccffff"
         End If
         For k = 0 To intPC0
            Response.Write "<TD align=right bgcolor="
            Response.Write csw
            Response.Write ">"
            Response.Write "<FONT size=-2>"

'************************************************************************
'*** FormattedValue property pulls data
'************************************************************************
            Response.Write cst(k, j).FormattedValue
            Response.Write "</FONT>"
            Response.Write "</TD>"
         Next
         Response.Write "</TR>"
      Next
      Response.Write "</Table>"

%>
</font>
</body>
</html>


CubeDef 范例 (VBScript)

此范例在 Web 页上显示立方元数据。

<%@ Language=VBScript %>
<%
Response.Buffer=True
'Response.Expires=0
%>
<html>
<head>
<meta NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</head>
<body>

<%
Server.ScriptTimeout=360
Dim cat,cdf,di,hi,le,mem,strServer,strSource,strCubeName

'************************************************************************
'*** Set Session Variables
'************************************************************************
Session("CubeName") = Request.Form("strCubeName")
Session("CatalogName") = Request.Form("strCatalogName")
Session("ServerName") = Request.Form("strServerName")
Session("chkDim") = Request.Form("chkDimension")
Session("chkHier") =  Request.Form("chkHierarchy")
Session("chkLev") =  Request.Form("chkLevel")

'************************************************************************
'*** Create Catalog Object
'************************************************************************************
Set cat = Server.CreateObject("ADOMD.Catalog")

If Len(Session("ServerName")) > 0 Then
   cat.ActiveConnection = "Data Source='" & Session("ServerName") & "';Initial Catalog='" & Session("CatalogName") & "';Provider='msolap';"
Else
'************************************************************************************
'*** Must set OLAPServerName to OLAP Server that is
'*** present on network
'************************************************************************
OLAPServerName = "Please set to present OLAP Server"
   cat.ActiveConnection = "Data Source=" & OLAPServerName & _
      ";Initial Catalog=FoodMart;Provider=msolap;"
   Session("ServerName") = OLAPServerName
   Session("InitialCatalog") = "FoodMart"
End if

If Len(Session("CubeName")) > 0 Then
   Set cdf = cat.CubeDefs(Session("CubeName"))
Else
   Set cdf = cat.CubeDefs("Sales")
   Session("CubeName")="Sales"
End if

'************************************************************************
'*** Collect Information in HTML Form
'************************************************************************
%>
<form action="ASPADOCubeDoc.asp" method="post" id="form1" name="form1">
<table>
   <tr>
      <td>
      <b>Olap Server name:  </b><br><input type="text" id="strServerName" name="strServerName" value="<%=Session("ServerName")%>" size="20"><br>

      <b>Catalog Name:  </b><br><input type="text" id="strCatalogName" name="strCatalogName" value="<%=Session("CatalogName")%>" size="20"><br>

      <b>Cube Name:  </b><br><input type="text" id="strCubeName" name="strCubeName" value="<%=Session("CubeName")%>" size="20">
      </td>
      <td <TD>
         <b>Add Property Detail:  </b><br>
         Dimension Detail: <input type="checkbox" id="chkDimension" name="chkDimension"><br>

         Hierarchy Detail: <input type="checkbox" id="chkHierarchy" name="chkHierarchy"><br>

         Level Detail: <input type="checkbox" id="chkLevel" name="chkLevel">
      </td>
   </tr>
</table>
<input type="submit" value="Cube Information" id="submit1" name="submit1"><input type="reset" value="Reset" id="reset1" name="reset1">
</form>
<%

'************************************************************************
'*** Start of Report
'************************************************************************
Response.Write "<H3>Report for " & Session("CubeName") & " Cube</H3>"
Response.Write "<OL TYPE='i'>"

'************************************************************************
'*** Show properties of Cube
'************************************************************************
            For i = 0 To cdf.Properties.Count - 1
               Response.Write "<LI>"
               Response.Write "<FONT size=-2>" & cdf.Properties(i).Name & ": " & cdf.Properties(i).Value & "</FONT>"
            Next
            Response.Write "</OL>"
            Response.Write "<UL TYPE='SQUARE'>"
 '************************************************************************
'*** Loop to display Dimension Name and Properties if Check box is
'*** Checked
'************************************************************************
      For di = 0 To cdf.Dimensions.Count - 1
         Response.Write "<LI>"
         Response.Write "<FONT size=4><B>Dimension: " & _
            cdf.Dimensions(di).Name & "</B></FONT>"
         If Request.Form("chkDimension") = "on" Then
            Response.Write "<OL TYPE='1'>"
            For i = 0 To cdf.Dimensions(di).Properties.Count - 1
               Response.Write "<LI>"
               Response.Write "<FONT size=-2>" & _
                  cdf.Dimensions(di).Properties(i).Name & ": " & _
                  cdf.Dimensions(di).Properties(i).Value & "</FONT>"
            Next
            Response.Write "</OL>"
         End If
         Response.Write "<UL TYPE= 'Circle'>"
'************************************************************************
'*** Loop to display Hierarchy Name and Properties if Check box is
'*** Checked
'************************************************************************
         For hi = 0 To cdf.Dimensions(di).Hierarchies.Count - 1
            Response.Write "<LI>"
            Response.Write "<FONT size=3><B>Hierarchy: " & _
               cdf.Dimensions(di).Hierarchies(hi).Name & "</B></FONT>"
            If Request.Form("chkHierarchy") = "on" Then
               Response.Write "<OL TYPE='1'>"
               For i = 0 To _
                  cdf.Dimensions(di).Hierarchies(hi).Properties.Count - 1
                  Response.Write "<LI>"
                  Response.Write "<FONT size=-2>" & _
                     cdf.Dimensions(di).Hierarchies(hi).Properties(i)._
                     Name & ": " & _
                     cdf.Dimensions(di).Hierarchies(hi).Properties(i)._
                     Value & "</FONT>"
               Next
               Response.Write "</OL>"
            End If
            Response.Write "<UL TYPE='Disc'>"
'************************************************************************
'*** Loop to display Level Name and Properties if Check box is Checked
'************************************************************************
      For le = 0 To cdf.Dimensions(di).Hierarchies(hi).Levels.Count - 1
               Response.Write "<LI>"
               Response.Write "<FONT size=2><B>Level: " & _
                  cdf.Dimensions(di).Hierarchies(hi).Levels(le).Name & _
                  " with a Member Count of: " & _
                  cdf.Dimensions(di).Hierarchies(hi).Levels(le)._
                  Properties("LEVEL_CARDINALITY") & "</B></FONT>"
               If Request.Form("chkLevel") = "on" Then
                  Response.Write "<OL TYPE='1'>"
                  For i = 0 To
                     cdf.Dimensions(di).Hierarchies(hi).Levels(le)._
                     Properties.Count - 1
                     Response.Write "<LI>"
                     Response.Write "<FONT size=-2>" & _
                        cdf.Dimensions(di).Hierarchies(hi).Levels(le)._
                        Properties(i).Name & ": " & _
                        cdf.Dimensions(di).Hierarchies(hi).Levels(le)._
                        Properties(i).Value & "</FONT>"
                  Next
                  Response.Write "</OL>"
               End If
            Next
            Response.Write "</UL>"
         Next
         Response.Write "</UL>"
      Next
      Response.Write "</UL>"
%>
</body>
</html>


ADOX API 参考

本节 ADOX 文档包含每个 ADOX 对象、集合、方法和属性的主题，同时还适时提供了范例代码。有关详细信息，请在索引中搜索特定主题或参阅下面的主题：

  • ADOX 对象
  • ADOX 集合
  • ADOX 属性
  • ADOX 方法
  • ADOX 枚举常量
  • ADOX 代码范例

请参阅

ADO API 参考 | ADO MD API 参考 | ADOX 代码范例 | ADOX 集合 | ADOX 枚举常量 | ADOX 方法 | ADOX 对象模型 | ADOX 对象 | ADOX 属性


ADOX 对象模型

下面的图表说明在 ADOX 中如何表示对象及其相互关系。有关特定对象或集合的详细信息，请参阅特定的参考主题，或参阅 ADOX 对象和 ADOX 集合。

每个 Table、Index 和 Column 对象均具有标准的 ADO Properties 集合。

请参阅

ADOX API 参考 | ADOX 代码范例 | ADOX 集合 | ADOX 枚举常量 | ADOX 方法 | ADOX 对象 | ADOX 属性 | Microsoft ADOX 程序员参考


ADOX 对象

ADOX 对象汇总

对象 | 说明
Catalog | 包含描述数据源的模式目录的集合。
Column | 表示表、索引或键的列。
Group | 表示在安全数据库中具有访问权限的组帐号。
Index | 表示数据库表的索引。
Key | 表示数据库表中的主键、外键或唯一键字段。
Procedure | 表示存储过程。
Table | 表示包括列、索引和键的数据库表。
User | 表示在安全数据库中具有访问权限的用户帐号。
View | 表示已过滤的记录集或虚拟表。

这些对象之间的关系在 ADOX 对象模型中说明。

每个对象都可以包含在对应的集合中。例如，Table 对象可以包含在 Tables 集合中。有关详细信息，请参阅 ADOX 集合或特定集合的主题。

请参阅

ADOX API 参考 | ADOX 集合 | ADOX 对象模型 | Microsoft ADOX 程序员参考


Catalog 对象 (ADOX)

ADOX 2.5 API 参考

Catalog 对象

包含描述数据源的模式目录的集合（Tables、Views、Users、Groups 和 Procedures）。

说明

可以通过添加或删除对象，或通过修改现有对象来修改 Catalog 对象。有些提供者可能不支持所有 Catalog 对象，或者只支持查看模式信息。

使用 Catalog 对象的属性和方法，可以：

  • 通过将 ActiveConnection 属性设置为 ADO Connection 对象或有效的连接字符串来打开目录。
  • 使用 Create 方法创建新的目录。
  • 使用 GetObjectOwner 和 SetObjectOwner 方法确定 Catalog 中的对象的所有者。

请参阅

Catalog 的 ActiveConnection 属性范例 (VB) | Command 和 CommandText 属性范例 (VB) | Connection 的 Close 方法，Table 的 Type 属性范例 (VB) | Create 方法范例 (VB) | Keys 的 Append 方法，Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VB) | Parameters 集合，Command 属性范例 (VB) | ParentCatalog 属性范例 (VB) | Procedures 的 Append 方法范例 (VB) | Procedures 的 Delete 方法范例 (VB) | Procedures 的 Refresh 方法范例 (VB) | Views 和 Fields 集合范例 (VB) | Views 的 Append 方法范例 (VB) | Views 集合，CommandText 属性范例 (VB) | Views 的 Delete 方法范例 (VB) | Views 的 Refresh 方法范例 (VB)

属性、方法和事件 | Groups 集合 | Procedures 集合 | Tables 集合 | Users 集合 | Views 集合


属性、方法和事件

ADOX 2.5 API 参考

Catalog 对象的属性、方法和事件

属性/集合

ActiveConnection 属性

Groups 集合

Procedures 集合

Tables 集合

Users 集合

Views 集合

方法

Create 方法

GetObjectOwner 方法

SetObjectOwner 方法

事件

无。

请参阅

应用于：Catalog 对象


Column 对象 (ADOX)

ADOX 2.5 API 参考

Column 对象

表示表、索引或键的列。

说明

下面的代码创建新的 Column：

Dim obj As New Column

使用 Column 对象的属性和集合，可以：

  • 使用 Name 属性标识列。
  • 使用 Type 属性指定列的数据类型。
  • 使用 Attributes 属性确定列是否为固定长度，或者是否能包含 Null 值。
  • 使用 DefinedSize 属性指定列的最大尺寸。
  • 对于数字数据值，使用 NumericScale 属性指定范围。
  • 对于数字数据值，使用 Precision 属性指定最大精度。
  • 使用 ParentCatalog 属性指定列的父 Catalog。
  • 对于键列，使用 RelatedColumn 属性指定相关表中相关列的名称。
  • 对于索引列，使用 SortOrder 属性指定排序顺序是升序还是降序。
  • 使用 Properties 集合访问提供者特有的属性。
注意 数据提供者可能不支持 Column 对象的所有属性。如果设置了提供者不支持的属性值，将出现错误。对于新的 Column 对象，在向集合中追加此对象时将出现错误。对于现有的对象，在设置此属性时将出现错误。
创建 Column 对象时，可选属性存在适当的默认值并不能保证提供者支持该属性。有关提供者支持的属性的详细信息，请参阅提供者文档。

请参阅

Columns 和 Tables 的 Append 方法，Name 属性范例 (VB) | Connection 的 Close 方法，Table 的 Type 属性范例 (VB) | Keys 的 Append 方法，Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VB) | NumericScale 和 Precision 属性范例 (VB) | ParentCatalog 属性范例 (VB) | SortOrder 属性范例 (VB)

属性、方法和事件 | Columns 集合 | Properties 集合


属性、方法和事件

ADOX 2.5 API 参考

Column 对象的属性、方法和事件

属性/集合

Attributes 属性

DefinedSize 属性

Name 属性

NumericScale 属性

ParentCatalog 属性

Precision 属性

Properties 集合

RelatedColumn 属性

SortOrder 属性

Type 属性 (Column)

方法

无。

事件

无。

请参阅

应用于：Column 对象


Group 对象 (ADOX)

ADOX 2.5 API 参考

Group 对象

表示在安全数据库中具有访问权限的组帐号。

说明

Catalog 的 Groups 集合表示所有目录的组帐号。User 的 Groups 集合仅表示用户所属的组。

使用 Group 对象的属性、集合和方法，可以：

  • 使用 Name 属性标识组。
  • 使用 GetPermissions 和 SetPermissions 方法确定组是否具有读、写或删除的权限。
  • 使用 Users 集合访问组中成员的用户帐号。
  • 使用 Properties 集合访问提供者特有的属性。

请参阅

属性、方法和事件 | Groups 集合 | Users 集合


属性、方法和事件

ADOX 2.5 API 参考

Group 对象的属性、方法和事件

属性/集合

Name 属性

Properties 集合

Users 集合

方法

GetPermissions 方法

SetPermissions 方法

事件

无。

请参阅

应用于：Group 对象


Index 对象 (ADOX)

ADOX 2.5 API 参考

Index 对象

表示数据库表的索引。

说明

下面的代码创建新的 Index：

Dim obj As New Index

使用 Index 对象的属性和集合，可以：

  • 使用 Name 属性标识索引。
  • 使用 Columns 集合访问索引的数据库列。
  • 使用 Unique 属性指定索引键是否必须是唯一键。
  • 使用 PrimaryKey 属性指定索引是否是表的主键。
  • 使用 IndexNulls 属性指定索引字段中有 Null 值的记录是否有索引项目。
  • 使用 Clustered 属性指定索引是否分簇。
  • 使用 Properties 集合访问提供者特有的索引属性。
注意 在向 Index 的 Columns 集合中追加 Column 时，如果已追加到 Tables 集合的 Table 对象中不存在该 Column，将出现错误。
数据提供者可能不支持 Index 对象的所有属性。如果设置了提供者不支持的属性值，将出现错误。对于新的 Index 对象，在向集合中追加此对象时将出现错误。对于现有的对象，在设置此属性时将出现错误。
创建 Index 对象时，可选属性存在适当的默认值并不能保证提供者支持该属性。有关提供者支持的属性的详细信息，请参阅提供者文档。

请参阅

Indexes 的 Append 方法范例 (VB) | IndexNulls 属性范例 (VB) | PrimaryKey 和 Unique 属性范例 (VB) | SortOrder 属性范例 (VB)

属性、方法和事件 | Columns 集合 | Indexes 集合 | Properties 集合


属性、方法和事件

ADOX 2.5 API 参考

Index 对象的属性、方法和事件

属性/集合

Clustered 属性

Columns 集合

IndexNulls 属性

Name 属性

PrimaryKey 属性

Properties 集合

Unique 属性

方法

无。

事件

无。

请参阅

应用于：Index 对象


Key 对象 (ADOX)

ADOX 2.5 API 参考

Key 对象

表示数据库表中的主键、外键或唯一键字段。

说明

下面的代码创建新的 Key：

Dim obj As New Key

使用 Key 对象的属性和集合，可以：

  • 使用 Name 属性标识键。
  • 使用 Type 属性确定键是主键、外键，还是唯一键。
  • 使用 Columns 集合访问键的数据库列。
  • 使用 RelatedTable 属性指定相关表的名称。
  • 使用 DeleteRule 和 UpdateRule 属性确定在删除或更新主键时执行的操作。

请参阅

Keys 的 Append 方法，Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VB)

属性、方法和事件 | Columns 集合 | Keys 集合


属性、方法和事件

ADOX 2.5 API 参考

Key 对象的属性、方法和事件

属性/集合

Columns 集合

DeleteRule 属性

Name 属性

RelatedTable 属性

Type 属性 (Key)

UpdateRule 属性

方法

无。

事件

无。

请参阅

应用于：Key 对象


Procedure 对象 (ADOX)

ADOX 2.5 API 参考

Procedure 对象

表示存储过程。当与 ADO Command 对象结合使用时，Procedure 对象可用于添加、删除或修改存储过程。

说明

Procedure 对象允许创建存储过程，而无须知道或使用提供者的“CREATE PROCEDURE”语法。

使用 Procedure 对象的属性，可以：

  • 使用 Name 属性标识过程。
  • 使用 Command 属性指定可用于创建或执行该过程的 ADO Command 对象。
  • 使用 DateCreated 和 DateModified 属性返回日期信息。

请参阅

Command 和 CommandText 属性范例 (VB) | Parameters 集合，Command 属性范例 (VB) | Procedures 的 Append 方法范例 (VB) | Procedures 的 Delete 方法范例 (VB)

属性、方法和事件 | Procedures 集合


属性、方法和事件

ADOX 2.5 API 参考

Procedure 对象的属性、方法和事件

属性

Command 属性

DateCreated 属性

DateModified 属性

Name 属性

方法

无。

事件

无。

请参阅

应用于：Procedure 对象


Table 对象 (ADOX)

ADOX 2.5 API 参考

Table 对象

表示包括列、索引和键的数据库表。

说明

下面的代码创建新的 Table：

Dim obj As New Table

使用 Table 对象的属性和集合，可以：

  • 使用 Name 属性标识表。
  • 使用 Type 属性确定表的类型。
  • 使用 Columns 集合访问表的数据库列。
  • 使用 Indexes 集合访问表的索引。
  • 使用 Keys 集合访问表的键。
  • 使用 ParentCatalog 属性指定表的父 Catalog。
  • 使用 DateCreated 和 DateModified 属性返回日期信息。
  • 使用 Properties 集合访问提供者特有的表属性。
Note 数据提供者可能不支持 Table 对象的所有属性。如果设置了提供者不支持的属性值，将出现错误。对于新的 Table 对象，在向集合中追加此对象时将出现错误。对于现有的对象，在设置此属性时将出现错误。
创建 Table 对象时，可选属性存在适当的默认值并不能保证提供者支持该属性。有关提供者支持的属性的详细信息，请参阅提供者文档。

请参阅

Catalog 的 ActiveConnection 属性范例 (VB) | Columns 和 Tables 的 Append 方法，Name 属性范例 (VB) | Connection 的 Close 方法，Table 的 Type 属性范例 (VB) | Keys 的 Append 方法，Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VB) | ParentCatalog 属性范例 (VB)

属性、方法和事件 | Columns 集合 | Indexes 集合 | Keys 集合 | Properties 集合 | Tables 集合


属性、方法和事件

ADOX 2.5 API 参考

Table 对象的属性、方法和事件

属性/集合

DateCreated 属性

DateModified 属性

Indexes 集合

Keys 集合

Name 属性

ParentCatalog 属性

Type 属性 (Table)

方法

无。

事件

无。

请参阅

应用于：Table 对象


User 对象 (ADOX)

ADOX 2.5 API 参考

User 对象

表示在安全数据库中具有访问权限的用户帐号。

说明

Catalog 的 Users 集合表示目录的所有用户。Group 的 Users 集合仅表示某个组的用户。

使用 User 对象的属性、集合和方法，可以：

  • 使用 Name 属性标识用户。
  • 使用 ChangePassword 方法更改用户的密码。
  • 使用 GetPermissions 和 SetPermissions 方法确定用户是否具有读、写或删除的权限。
  • 使用 Groups 集合访问用户所属的组。
  • 使用 Properties 集合访问提供者特有的属性。

请参阅

GetPermissions 和 SetPermissions 方法范例 (VB)

属性、方法和事件 | Groups 集合 | Users 集合


属性、方法和事件

ADOX 2.4 API 参考

User 对象的属性、方法和事件

属性/集合

Groups 集合

Name 属性

Properties 集合

方法

ChangePassword 方法

GetPermissions 方法

SetPermissions 方法

事件

无。

请参阅

应用于：User 对象


View 对象 (ADOX)

ADOX 2.5 API 参考

View 对象

表示已过滤的记录集或虚拟表。当与 ADO Command 对象结合使用时，View 对象可用于添加、删除或修改视图。

说明

视图是从其他数据库表或视图创建的虚拟表。View 对象允许创建视图，而无须知道或使用提供者的“CREATE VIEW”语法。

使用 View 对象的属性，可以：

  • 使用 Name 属性标识视图。
  • 使用 Command 属性指定可用于添加、删除或修改视图的 ADO Command 对象。
  • 使用 DateCreated 和 DateModified 属性返回日期信息。

请参阅

Views 和 Fields 集合范例 (VB) | Views 的 Append 方法范例 (VB) | Views 集合，CommandText 属性范例 (VB) | Views 的 Delete 方法范例 (VB)

属性、方法和事件 | Views 集合


属性、方法和事件

ADOX 2.5 API 参考

View 对象的属性、方法和事件

属性

Command 属性

DateCreated 属性

DateModified 属性

Name 属性

方法

无。

事件

无。

请参阅

应用于：View 对象


ADOX 集合

Columns | 包含表、索引或键的所有 Column 对象。
Groups | 包含目录或用户的所有已存储的 Group 对象。
Indexes | 包含表的所有 Index 对象。
Keys | 包含表的所有 Key 对象。
Procedures | 包含目录的所有 Procedure 对象。
Tables | 包含目录的所有 Table 对象。
Users | 包含目录或组的所有已存储的 User 对象。
Views | 包含目录的所有 View 对象。

请参阅

ADOX API 参考 | ADOX 对象模型 | ADOX 对象 | Microsoft ADOX 程序员参考


Columns 集合 (ADOX)

ADOX 2.5 API 参考

Columns 集合

包含表、索引或键的所有 Column 对象。

说明

Columns 集合的 Append 方法对于 ADOX 是唯一的，可以：

  • 使用 Append 方法向集合中添加新的列。

其余的属性和方法对于 ADO 集合是标准的，可以：

  • 使用 Item 属性访问集合中的列。
  • 使用 Count 属性返回包含在集合中的列的数目。
  • 使用 Delete 方法从集合中删除列。
  • 使用 Refresh 方法更新集合中的对象以反映当前数据库的模式。
注意 向 Index 的 Columns 集合中追加 Column 时，如果已追加到 Tables 集合中的 Table 中不存在 Column，将出现错误。

请参阅

Columns 和 Tables 的 Append 方法、Name 属性范例 (VB) | Connection 的 Close 方法、Table 的 Type 属性范例 (VB) | Keys 的 Append 方法，Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VB) | ParentCatalog 属性范例 (VB) | SortOrder 属性范例 (VB)

属性、方法和事件 | Column 对象


Columns 集合的属性、方法和事件

属性

Count 属性

Item 属性

方法

Append 方法 (Columns)

Delete 方法（集合）

Refresh 方法

事件

无。

请参阅

应用于：Columns 集合


Groups 集合 (ADOX)

ADOX 2.5 API 参考

Groups 集合

包含目录或用户的所有已存储的 Group 对象。

说明

Catalog 的 Groups 集合表示此目录的所有组的帐号。User 的 Groups 集合仅表示用户所属的组。

Groups 集合的 Append 方法对于 ADOX 是唯一的，可以：

  • 使用 Append 方法向集合中添加新的安全组。

其余的属性和方法对于 ADO 集合是标准的，可以：

  • 使用 Item 属性访问集合中的组。
  • 使用 Count 属性返回包含在集合中的组的数目。
  • 使用 Delete 方法从集合中删除组。
  • 使用 Refresh 方法更新集合中的对象以反映当前数据库的模式。
注意 向 User 对象的 Groups 集合中追加 Group 对象之前，Catalog 的 Groups 集合中必须已经存在与被追加的对象具有相同 Name 的 Group 对象。

请参阅

属性、方法和事件 | Catalog 对象 | Group 对象


Groups 集合的属性、方法和事件

属性

Count 属性

Item 属性

方法

Append 方法 (Groups)

Delete 方法（集合）

Refresh 方法

事件

无。

请参阅

应用于： Groups 集合


Indexes 集合 (ADOX)

ADOX 2.5 API 参考

Indexes 集合

包含表的所有 Index 对象。

说明

Indexes 集合的 Append 方法对于 ADOX 是唯一的，可以：

  • 使用 Append 方法向集合中添加新的索引。

其余的属性和方法对于 ADO 集合是标准的，可以：

  • 使用 Item 属性访问集合中的索引。
  • 使用 Count 属性返回包含在集合中的索引的数目。
  • 使用 Delete 方法从集合中删除索引。
  • 使用 Refresh 方法更新集合中的对象以反映当前数据库的模式。

请参阅

Indexes 的 Append 方法范例 (VB)

属性、方法和事件 | Index 对象


Indexes 集合的属性、方法和事件

属性

Count 属性

Item 属性

方法

Append 方法 (Indexes)

Delete 方法（集合）

Refresh 方法

事件

无。

请参阅

应用于： Indexes 集合


Keys 集合 (ADOX)

ADOX 2.5 API 参考

Keys 集合

包含表的所有 Key 对象。

说明

Keys 集合的 Append 方法对于 ADOX 是唯一的，可以：

  • 使用 Append 方法向集合中添加新键。

其余的属性和方法对于 ADO 集合是标准的，可以：

  • 使用 Item 属性访问集合中的键。
  • 使用 Count 属性返回包含在集合中的键的数目。
  • 使用 Delete 方法从集合中删除键。
  • 使用 Refresh 方法更新集合中的对象以反映当前数据库的模式。

请参阅

Keys 的 Append 方法，Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VB)

属性、方法和事件 | Key 对象


Keys 集合的属性、方法和事件

属性

Count 属性

Item 属性

方法

Append 方法 (Keys)

Delete 方法（集合）

Refresh 方法

事件

无。

请参阅

应用于：Keys 集合


Procedures 集合 (ADOX)

ADOX 2.5 API 参考

Procedures 集合

包含目录的所有 Procedure 对象。

说明

Procedures 集合的 Append 方法对于 ADOX 是唯一的，可以：

  • 使用 Append 方法向集合中添加新的过程。

其余的属性和方法对于 ADO 集合是标准的，可以：

  • 使用 Item 属性访问集合中的过程。
  • 使用 Count 属性返回包含在集合中的过程的数目。
  • 使用 Delete 方法从集合中删除过程。
  • 使用 Refresh 方法更新集合中的对象以反映当前数据库的模式。

请参阅

Command 和 CommandText 属性范例 (VB) | Parameters 集合，Command 属性范例 (VB) | Procedures 的 Append 方法范例 (VB) | Procedures 的 Delete 方法范例 (VB) | Procedures 的 Refresh 方法范例 (VB)

属性、方法和事件 | Catalog 对象 | Procedure 对象


Procedures 集合的属性、方法和事件

属性

Count 属性

Item 属性

方法

Append 方法 (Procedures)

Delete 方法（集合）

Refresh 方法

事件

无。

请参阅

应用于：Procedures 集合


Tables 集合 (ADOX)

ADOX 2.5 API 参考

Tables 集合

包含目录的所有 Table 对象。

说明

Tables 集合的 Append 方法对于 ADOX 是唯一的，可以：

  • 使用 Append 方法向集合中添加新的表。

其余的属性和方法对于 ADO 集合是标准的，可以：

  • 使用 Item 属性访问集合中的表。
  • 使用 Count 属性返回包含在集合中的表的数目。
  • 使用 Delete 方法从集合中删除表。
  • 使用 Refresh 方法更新集合中的对象以反映当前数据库的模式。

某些提供者可能在 Tables 集合中返回诸如 View 的其他模式对象。因此，某些 ADOX 集合可能包含对同一对象的引用。如果从一个集合中删除对象，只有在集合上调用 Refresh 方法之后，引用被删除对象的另一个集合才能显示所做的更改。例如，通过 OLE DB Provider for Microsoft Jet，使用 Tables 集合返回 View。如果删除 View，必须刷新 Tables 集合才能在该集合中反映此更改。

请参阅

Catalog 的 ActiveConnection 属性范例 (VB) | Columns 和 Tables 的 Append 方法，Name 属性范例 (VB) | Connection 的 Close 方法，Table 的 Type 属性范例 (VB) | Keys 的 Append 方法，Key Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VB)

属性、方法和事件 | Catalog 对象 | Table 对象


Tables 集合的属性、方法和事件

属性

Count 属性

Item 属性

方法

Append 方法 (Tables)

Delete 方法（集合）

Refresh 方法

事件

无。

请参阅

应用于：Tables 集合


Users 集合 (ADOX)

ADOX 2.5 API 参考

Users 集合

包含目录或组的所有已存储的 User 对象。

说明

Catalog 的 Users 集合表示目录的所有用户。Group 的 Users 集合仅表示属于某个组的成员的用户。

Users 集合的 Append 方法对于 ADOX 是唯一的，可以：

  • 使用 Append 方法向集合中添加新的用户。

其余的属性和方法对于 ADO 集合是标准的，可以：

  • 使用 Item 属性访问集合中的用户。
  • 使用 Count 属性返回包含在集合中的用户的数目。
  • 使用 Delete 方法从集合中删除用户。
  • 使用 Refresh 方法更新集合中的对象以反映当前数据库的模式。
注意 向 Group 对象的 Users 集合中追加 User 对象之前，Catalog 的 Users 集合中必须已经存在与被追加的对象具有相同 Name 的 User 对象。

请参阅

GetPermissions 和 SetPermissions 方法范例 (VB)

属性、方法和事件 | Catalog 对象 | User 对象


Users 集合的属性、方法和事件

属性

Count 属性

Item 属性

方法

Append 方法 (Users)

Delete 方法（集合）

Refresh 方法

事件

无。

请参阅

应用于：Users 集合


Views 集合 (ADOX)

ADOX 2.5 API 参考

Views 集合

包含目录的所有 View 对象。

说明

Views 集合的 Append 方法对于 ADOX 是唯一的，可以：

  • 使用 Append 方法向集合中添加新的视图。

其余的属性和方法对于 ADO 集合是标准的，可以：

  • 使用 Item 属性访问集合中的视图。
  • 使用 Count 属性返回包含在集合中的视图的数目。
  • 使用 Delete 方法从集合中删除视图。
  • 使用 Refresh 方法更新集合中的对象以反映当前数据库的模式。

请参阅

Views 和 Fields 集合范例 (VB) | Views 的 Append 方法范例 (VB) | Views 集合，CommandText 属性范例 (VB) | Views 的 Delete 方法范例 (VB) | Views 的 Refresh 方法范例 (VB)

属性、方法和事件 | Catalog 对象 | View 对象


Views 集合的属性、方法和事件

属性

Count 属性

Item 属性

方法

Append 方法 (Views)

Delete 方法（集合）

Refresh 方法

事件

无。

请参阅

应用于：Views 集合


ADOX 属性

ActiveConnection | 指示目录所属的 ADO Connection 对象。
Attributes | 描述列的特性。
Clustered | 指示索引是否被分簇。
Command | 指定可用于创建或执行过程的 ADO Command 对象。
Count | 指示集合中对象的数目。
DateCreated | 指示创建对象的日期。
DateModified | 指示上次修改对象的日期。
DefinedSize | 指示列的最大允许大小。
DeleteRule | 指示主键被删除时执行的操作。
IndexNulls | 指示在索引字段中具有 Null 值的记录是否有索引项。
Item | 按名称或序号指示集合的特定成员。
Name | 指示对象的名称。
NumericScale | 指示列中的数字值的范围。
ParentCatalog | 指定表或列的父目录以访问提供者特有的属性。
Precision | 指示列中的数据值的最高精度。
PrimaryKey | 指示索引是否表示表的主键。
RelatedColumn | 指示相关表中相关列的名称（仅适用于键列）。
RelatedTable | 指示相关表的名称。
SortOrder | 指示列的排序顺序（仅适用于索引列）。
Type (Column) | 指示列的数据类型。
Type (Key) | 指示键的数据类型。
Type (Table) | 指示表的类型。
Unique | 指示索引键是否必须是唯一键。
UpdateRule | 指示更新主键时执行的操作。

请参阅

ADOX API 参考 | Microsoft ADOX 程序员参考


ActiveConnection 属性 (ADOX)

ADOX 2.5 API 参考

ActiveConnection 属性

指示 Catalog 所属的 ADO Connection 对象。

设置和返回值

设置 Connection 对象或包含连接的定义的 String。返回活动的 Connection 对象。

说明

默认值为 Null 对象引用。

请参阅

Catalog 的 ActiveConnection 属性范例 (VB) | Command 和 CommandText 属性范例 (VB) | Connection 的 Close 方法，Table 的 Type 属性范例 (VB) | Parameters 集合，Command 属性范例 (VB) | Procedures 的 Append 方法范例 (VB) | Procedures 的 Delete 方法范例 (VB) | Procedures 的 Refresh 方法范例 (VB) | Views 和 Fields 集合范例 (VB) | Views 的 Append 方法范例 (VB) | Views 集合，CommandText 属性范例 (VB) | Views 的 Refresh 方法范例 (VB)

Create 方法

应用于：Catalog 对象


Attributes 属性 (ADOX)

ADOX 2.5 API 参考

Attributes 属性

描述列的特性。

设置和返回值

设置或返回 Long 值。该值指定 Column 对象所表示的表的特性，可以是 ColumnAttributesEnum 常量的组合。默认值为零 (0)，而不是 adColFixed 或 adColNullable。

请参阅

Attributes 属性范例 (VB)

应用于：Column 对象 | Property 对象


Clustered 属性 (ADOX)

ADOX 2.5 API 参考

Clustered 属性

指示索引是否被分簇。

设置和返回值

设置并返回 Boolean 值。

说明

默认值为 False。

对于已追加到集合中的 Index 对象，此属性为只读。

请参阅

Clustered 属性范例 (VB)

应用于：Index 对象


Command 属性 (ADOX)

ADOX 2.5 API 参考

Command 属性

指定可用于创建或执行过程的 ADO Command 对象。

设置和返回值

设置或返回有效的 ADO Command 对象。

说明

如果提供者不支持持久命令，在获得和设置这个属性时，将出现错误。

请参阅

Command 和 CommandText 属性范例 (VB) | Parameters 集合，Command 属性范例 (VB) | Views 和 Fields 集合范例 (VB) | Views 集合，CommandText 属性范例 (VB)

应用于：Procedure 对象 | View 对象


DateCreated 属性 (ADOX)

ADOX 2.5 API 参考

DateCreated 属性

指示创建对象的日期。

返回值

返回 Variant 值，指定创建日期。如果提供者不支持 DateCreated，那么该值为 Null。

说明

对于新追加的对象，DateCreated 属性为 Null。追加新的 View 或 Procedure 之后，必须调用 Views 或 Procedures 集合的 Refresh 方法，以获取 DateCreated 属性的值。

请参阅

DateCreated 和 DateModified 属性范例 (VB)

DateModified 属性

Applies To: Procedure 对象 | Table 对象 | View 对象


DateModified 属性 (ADOX)

ADOX 2.5 API 参考

DateModified 属性

指示上次修改对象的日期。

返回值

返回 Variant 值，指定修改日期。如果提供者不支持 DateModified，那么该值为 Null。

说明

对于新追加的对象，DateModified 属性为 Null。追加新的 View 或 Procedure 之后，必须调用 Views 或 Procedures 集合的 Refresh 方法，以获取 DateModified 属性的值。

请参阅

DateCreated 和 DateModified 属性范例 (VB)

DateCreated 属性

应用于：Procedure 对象 | Table 对象 | View 对象


DefinedSize 属性 (ADOX)

ADOX 2.5 API 参考

DefinedSize 属性

指示列的最大允许大小。

设置和返回值

设置并返回 Long 值，该值为数据值的最大字符长度。

说明

默认值为零 (0)。

对于已追加到集合中的 Column 对象，此属性为只读。

请参阅

DefinedSize 属性范例 (VB)

应用于：Column 对象


DeleteRule 属性 (ADOX)

ADOX 2.5 API 参考

DeleteRule 属性

指示主键被删除时执行的操作。

设置和返回值

设置并返回 Long 值，该值可以是一个 RuleEnum 常量。默认值为 adRINone。

说明

对于已追加到集合中的 Key 对象，此属性为只读。

请参阅

DeleteRule 属性范例 (VB)

应用于：Key 对象


IndexNulls 属性 (ADOX)

ADOX 2.5 API 参考

IndexNulls 属性

指示在索引字段中具有 Null 值的记录是否有索引项。

设置和返回值

设置并返回 AllowNullsEnum 值。默认值为 adIndexNullsDisallow。

说明

对于已追加到集合中的 Index 对象，此属性为只读。

请参阅

IndexNulls 属性范例 (VB)

应用于：Index 对象


Name 属性 (ADOX)

ADOX 2.5 API 参考

Name 属性

指示对象的名称。

设置和返回值

设置或返回 String 值。

说明

名称在集合中不必是唯一的。

对于 Column、Group、Key、Index、Table 和 User 对象，Name 属性为读/写。对于 Catalog、Procedure 和 View 对象，Name 属性为只读。

对于读/写的对象（Column、Group、Key、Index、Table 和 User 对象），默认值为空字符串 ("")。

注意 对于键，本属性对于已追加到集合中的 Key 对象为只读。
对于表，本属性对于已追加到集合中的 Table 对象为只读。

请参阅

Columns 和 Tables 的 Append 方法，Name 属性范例 (VB) | Keys 的 Append 方法，Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VB) | ParentCatalog 属性范例 (VB)

应用于：Column 对象 | Group 对象 | Index 对象 | Key 对象 | Procedure 对象 | Property 对象 | Table 对象 | User 对象 | View 对象


NumericScale 属性 (ADOX)

ADOX 2.5 API 参考

NumericScale 属性

指示列中的数字值的范围。

设置和返回值

设置并返回 Byte 值，该值是当 Type 属性为 adNumeric 或 adDecimal 时列中数据值的范围。对于所有其他数据类型，可忽略 NumericScale。

说明

默认值为零 (0)。

对于已追加到集合中的 Column 对象，NumericScale 为只读。

请参阅

NumericScale 和 Precision 属性范例 (VB)

Type 属性 (Column)

应用于：Column 对象


ParentCatalog 属性 (ADOX)

ADOX 2.5 API 参考

ParentCatalog 属性

指定表或列的父目录以访问提供者特有的属性。

设置和返回值

设置并返回 Catalog 对象。将 ParentCatalog 设置为打开的 Catalog，可允许在向 Catalog 集合追加表或列之前访问提供者特有的属性。

说明

某些数据提供者仅允许在创建时（向其 Catalog 集合中追加表或列时）写入提供者特有的属性值。要在向 Catalog 中追加这些对象之前访问这些属性，请先在 ParentCatalog 属性中指定 Catalog。

将表或列追加到非 ParentCatalog 的 Catalog 中时，将出现错误。

请参阅

ParentCatalog 属性范例 (VB)

应用于：Column 对象 | Table 对象


Precision 属性 (ADOX)

ADOX 2.5 API 参考

Precision 属性

指示列中的数据值的最高精度。

设置和返回值

设置并返回 Long 值，该值是当 Type 属性为数字型时列中数据值的最高精度。对于所有其他数据类型，可忽略 Precision。

说明

默认值为零 (0)。

对于已追加到集合中的 Column 对象，此属性为只读。

请参阅

NumericScale 和 Precision 属性范例 (VB)

Type 属性 (Column)

应用于：Column 对象


PrimaryKey 属性 (ADOX)

ADOX 2.5 API 参考

PrimaryKey 属性

指示索引是否表示表的主键。

设置和返回值

设置并返回 Boolean 值。

说明

默认值为 False。

对于已追加到集合中的 Index 对象，此属性为只读。

请参阅

PrimaryKey 和 Unique 属性范例 (VB)

应用于：Index 对象


RelatedColumn 属性 (ADOX)

ADOX 2.5 API 参考

RelatedColumn 属性

指示相关表中相关列的名称（仅适用于键列）。

设置和返回值

设置并返回 String 值，该值是相关表中相关列的名称。

说明

默认值是空字符串 ("")。

对于已追加到集合中的 Column 对象，此属性为只读。

请参阅

Keys 的 Append 方法，Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VB)

Key 对象

应用于：Column 对象


RelatedTable 属性 (ADOX)

ADOX 2.5 API 参考

RelatedTable 属性

指示相关表的名称。

设置和返回值

设置并返回 String 值。

说明

默认值是空字符串 ("")。

如果该键是外键，那么 RelatedTable 是包含该键的表的名称。

请参阅

Keys 的 Append 方法，Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VB)

应用于：Key 对象

© 1998-2003 Microsoft Corporation. 保留所有权利。


SortOrder 属性 (ADOX)

ADOX 2.5 API 参考

SortOrder 属性

指示列的排序顺序（仅适用于索引列）。

设置和返回值

设置并返回 Long 值，该值可以是一个 SortOrderEnum 常量。默认值为 adSortAscending。

说明

此属性仅应用于 Index 的 Columns 集合中的 Column 对象。

请参阅

SortOrder 属性范例 (VB)

Columns 集合 | Index 对象

应用于：Column 对象


Type 属性 (Column) (ADOX)

ADOX 2.5 API 参考

Type 属性 (Column)

指示列的数据类型。

设置和返回值

设置或返回 Long 值，该值可以是一个 DataTypeEnum 常量。默认值为 adVarWChar。

说明

在向集合或另一个对象中追加 Column 对象之前，此属性是可读写的，而在追加之后此属性为只读。

请参阅

ParentCatalog 属性范例 (VB)

Type 属性 (Key) | Type 属性 (Table)

应用于：Column 对象


Type 属性 (Key) (ADOX)

ADOX 2.5 API 参考

Type 属性 (Key)

指示键的类型。

设置和返回值

设置或返回 Long 值，该值可以是一个 KeyTypeEnum 常量。默认值为 adKeyPrimary。

说明

对于已追加到集合中的 Key 对象，此属性为只读。

请参阅

Keys 的 Append 方法，Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VB)

Type 属性 (Column) | Type 属性 (Table)

应用于：Key 对象


Type 属性 (Table) (ADOX)

ADOX 2.5 API 参考

Type 属性 (Table)

指示表的类型。

返回值

返回 String 值，指定表的类型，例如“TABLE”、“SYSTEM TABLE”或“GLOBAL TEMPORARY”。

说明

此属性是只读的。

请参阅

Catalog 的 ActiveConnection 属性范例 (VB) | Connection 的 Close 方法，Table 的 Type 属性范例 (VB)

Type 属性 (Column) | Type 属性 (Key)

应用于：Table 对象


Unique 属性 (ADOX)

ADOX 2.5 API 参考

Unique 属性

指示索引键是否必须是唯一键。

设置和返回值

设置并返回 Boolean 值。

说明

默认值为 False。

对于已追加到集合中的 Index 对象，此属性为只读。

请参阅

PrimaryKey 和 Unique 属性范例 (VB)

Key 对象

应用于：Index 对象


UpdateRule 属性 (ADOX)

ADOX 2.5 API 参考

UpdateRule 属性

指示更新主键时执行的操作。

设置和返回值

设置并返回 Long 值，该值可以是一个 RuleEnum 常量。默认值为 adRINone。

说明

对于已追加到集合中的 Key 对象，此属性为只读。

请参阅

Keys 的 Append 方法，Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VB)

应用于：Key 对象


ADOX 方法

Append (Columns) | 向 Columns 集合中添加新的 Column 对象。
Append (Groups) | 向 Groups 集合中添加新的 Group 对象。
Append (Indexes) | 向 Indexes 集合中添加新的 Index 对象。
Append (Keys) | 向 Keys 集合中添加新的 Key 对象。
Append (Procedures) | 向 Procedures 集合中添加新的 Procedure 对象。
Append (Tables) | 向 Tables 集合中添加新的 Table 对象。
Append (Users) | 向 Users 集合中添加新的 User 对象。
Append (Views) | 向 Views 集合中添加新的 View 对象。
ChangePassword | 更改用户帐号的密码。
Create | 创建新目录。
Delete | 从集合中删除对象。
GetObjectOwner | 返回目录中的对象的所有者。
GetPermissions | 返回组或用户对一个对象所具有的权限。
SetObjectOwner | 指定目录中的对象的所有者。
SetPermissions | 指定组或用户对一个对象所具有的权限。

请参阅

ADOX API 参考 | Microsoft ADOX 程序员参考


Append 方法 (ADOX Columns)

ADOX 2.5 API 参考

Append 方法 (Columns)

向 Columns 集合中添加新的 Column 对象。

语法

Columns.Append Column [, Type] [, DefinedSize]

参数

Column
要追加的 Column 对象或要创建并追加的列的名称。
Type
可选。Long 值，指定列的数据类型。Type 参数对应于 Column 对象的 Type 属性。
DefinedSize
可选。Long 值，指定列的大小。DefinedSize 参数对应于 Column 对象的 DefinedSize 属性。
注意 向 Index 的 Columns 集合中追加 Column 时，如果已追加到 Tables 集合中的 Table 中不存在 Column，将出现错误。

请参阅

Columns 和 Tables 的 Append 方法，Name 属性范例 (VB) | Keys 的 Append 方法，Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VB) | ParentCatalog 属性范例 (VB)

Append 方法 (Groups) | Append 方法 (Indexes) | Append 方法 (Keys) | Append 方法 (Procedures) | Append 方法 (Tables) | Append 方法 (Users) | Append 方法 (Views)

应用于：Columns 集合


Append 方法 (ADOX Groups)

ADOX 2.5 API 参考

Append 方法 (Groups)

向 Groups 集合中添加新的 Group 对象。

语法

Groups.Append Group

参数

Group
要追加的 Group 对象或要创建并追加的组的名称。

说明

Catalog 的 Groups 集合表示此目录的所有组的帐号。User 的 Groups 集合仅表示用户所属的组。

如果提供者不支持创建组，将出现错误。

注意 向 User 对象的 Groups 集合中追加 Group 对象之前，Catalog 的 Groups 集合中必须已经存在与被追加的对象具有相同 Name 的 Group 对象。

请参阅

Groups 和 Users 的 Append、ChangePassword 方法范例 (VB)

Append 方法 (Columns) | Append 方法 (Indexes) | Append 方法 (Keys) | Append 方法 (Procedures) | Append 方法 (Tables) | Append 方法 (Users) | Append 方法 (Views)

应用于：Groups 集合


Append 方法 (ADOX Indexes)

ADOX 2.5 API 参考

Append 方法 (Indexes)

向 Indexes 集合中添加新的 Index 对象。

语法

Indexes.Append Index [, Columns]

参数

Index
要追加的 Index 对象或要创建并追加的索引的名称。
Columns
可选。Variant 值，指定要索引的列的名称。Columns 参数对应于一个或多个 Column 对象的 Name 属性的值。

说明

Columns 参数可使用列名或列名的数组。

如果提供者不支持创建索引，将出现错误。

请参阅

Indexes 的 Append 方法范例 (VB)

Append 方法 (Columns) | Append 方法 (Groups) | Append 方法 (Keys) | Append 方法 (Procedures) | Append 方法 (Tables) | Append 方法 (Users) | Append 方法 (Views)

应用于：Indexes 集合


Append 方法 (ADOX Keys)

ADOX 2.5 API 参考

Append 方法 (Keys)

向 Keys 集合中添加新的 Key 对象。

语法

Keys.Append Key [, KeyType] [, Column] [, RelatedTable] [, RelatedColumn]

参数

Key
要追加的 Key 对象或要创建并追加的键的名称。
KeyType
可选。Long 值，指定键的类型。Key 参数对应于 Key 对象 Type 属性。
Column
可选。String 值，指定要索引的列的名称。Columns 参数对应于 Column 对象的 Name 属性的值。
RelatedTable
可选。String 值，指定相关表的名称。RelatedTable 参数对应于 Table 对象的 Name 属性的值。
RelatedColumn
可选。String 值，指定外键的相关列的名称。RelatedColumn 参数对应于 Column 对象的 Name 属性的值。

说明

Columns 参数可使用列名或列名的数组。

请参阅

Keys 的 Append 方法，Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VB)

Append 方法 (Columns) | Append 方法 (Groups) | Append 方法 (Indexes) | Append 方法 (Procedures) | Append 方法 (Tables) | Append 方法 (Users) | Append M方法 (Views)

应用于：Keys 集合


Append 方法 (ADOX Procedures)

ADOX 2.5 API 参考

Append 方法 (Procedures)

向 Procedures 集合中添加新的 Procedure 对象。

语法

Procedures.Append Name, Command

参数

Name
String 值，指定要创建并追加的过程名称。
Command
ADO Command 对象，表示要创建并追加的过程。

说明

在数据源中创建具有 Command 对象指定的名称和属性的新过程。

如果用户指定的命令文本表示视图而非过程，该行为取决于所使用的提供者。如果提供者不支持持久命令，Append 将失败。

注意 使用 OLE DB Provider for Microsoft Jet 时，Procedures 集合的 Append 方法将允许在 Command 参数中指定 View 而非 Procedure。View 将被添加到数据源和 Procedures 集合中。在 Append 之后，如果 Procedures 和 Views 集合被刷新，View 将不再位于 Procedures 集合中，而是出现在 Views 集合中。

请参阅

Procedures 的 Append 方法范例 (VB)

Append 方法 (Columns) | Append 方法 (Groups) | Append 方法 (Indexes) | Append 方法 (Keys) | Append 方法 (Tables) | Append 方法 (Users) | Append 方法 (Views)

应用于：Procedures 集合


Append 方法 (ADOX Tables)

ADOX 2.5 API 参考

Append 方法 (Tables)

向 Tables 集合中添加新的 Table 对象。

语法

Tables.Append Table

参数

Table
Variant 值，包含对要追加的 Table 或要创建并追加的表名称的引用。

说明

如果提供者不支持创建表，将出现错误。

请参阅

Columns 和 Tables 的 Append 方法，Name 属性范例 (VB) | ParentCatalog 属性范例 (VB)

Append 方法 (Columns) | Append 方法 (Groups) | Append 方法 (Indexes) | Append 方法 (Keys) | Append 方法 (Procedures) | Append 方法 (Users) | Append 方法 (Views)

应用于：Tables 集合


Append 方法 (ADOX Users)

ADOX 2.5 API 参考

Append 方法 (Users)

向 Users 集合中添加新的 User 对象。

语法

Users.Append User[, Password]

参数

User
Variant 值，包含要追加的 User 对象或要创建并追加的用户的名称。
Password
可选。String 值，包含用户的密码。Password 参数对应于由 User 对象的 ChangePassword 方法指定的值。

说明

Catalog 的 Users 集合表示目录的所有用户。Group 的 Users 集合仅表示属于某个组的成员的用户。

如果提供者不支持创建用户，将出现错误。

注意 向 Group 对象的 Users 集合中追加 User 对象之前，Catalog 的 Users 集合中必须已经存在与被追加的对象具有相同 Name 的 User 对象。

请参阅

Groups 和 Users 的 Append、ChangePassword 方法范例 (VB)

Append 方法 (Columns) | Append 方法 (Groups) | Append 方法 (Indexes) | Append 方法 (Keys) | Append 方法 (Procedures) | Append 方法 (Tables) | Append 方法 (Views)

应用于：Users 集合


Append 方法 (ADOX Views)

ADOX 2.5 API 参考

Append 方法 (Views)

创建新的 View 对象并将其追加到 Views 集合中。

语法

Views.Append Name, Command

参数

Name
String 值，指定要创建的视图的名称。
Command
ADO Command 对象，表示要创建的视图。

说明

在数据源中创建具有在 Command 对象中指定的名称和属性的新视图。

如果用户指定的命令文本表示过程而非视图，该行为取决于提供者。如果提供者不支持持久命令，Append 将失败。

注意 使用 OLE DB Provider for Microsoft Jet 时，Views 集合的 Append 方法将允许在 Command 参数中指定 Procedure，而并非 View。Procedure 将被添加到数据源和 Views 集合中。在 Append 之后，如果 Procedures 和 Views 集合被刷新，Procedure 将不再位于 Views 集合中，而是出现在 Procedures 集合中。

请参阅

Views 的 Append 方法范例 (VB)

Append 方法 (Columns) | Append 方法 (Groups) | Append 方法 (Indexes) | Append 方法 (Keys) | Append 方法 (Procedures) | Append 方法 (Tables) | Append 方法 (Users)

应用于：Views 集合


ChangePassword 方法 (ADOX)

ADOX 2.5 API 参考

ChangePassword 方法

更改用户帐号的密码。

语法

User.ChangePassword OldPassword, NewPassword

参数

OldPassword
String 值，指定用户现有的密码。如果用户当前没有密码，请对 OldPassword 使用空字符串 ("")。
NewPassword
String 值，指定新密码。

说明

出于安全考虑，除新密码外还必须指定旧密码。

如果提供者不支持受托者属性的管理，将出现错误。

请参阅

Groups 和 Users 的 Append、ChangePassword 方法范例 (VB)

应用于：User 对象


Create 方法 (ADOX)

ADOX 2.5 API 参考

Create 方法

创建新目录。

语法

Catalog.Create ConnectString

参数

ConnectString
String 值，用于连接到数据源。

说明

Create 方法创建并打开在 ConnectString 中指定的到数据源的新 ADO Connection。如果成功，新的 Connection 对象将被分配给 ActiveConnection 属性。

如果提供者不支持创建新目录，将出现错误。

请参阅

Create 方法范例 (VB)

ActiveConnection 属性

应用于：Catalog 对象


Delete 方法（ADOX 集合）

ADOX 2.5 API 参考

Delete 方法（集合）

从集合中删除对象。

语法

Collection.Delete Name

参数

Name
Variant，指定要删除的对象的名称或序号位置（索引）。

说明

如果集合中不存在 Name，将出现错误。

对于 Tables 和 Users 集合，如果提供者不支持删除表或用户，将出现错误。对于 Procedures 和 Views 集合，如果提供者不支持持久命令，Delete 将失败。

请参阅

Procedures 的 Delete 方法范例 (VB) | Views 的 Delete 方法范例 (VB)

Applies To: Columns 集合 | Groups 集合 | Indexes 集合 | Keys 集合 | Procedures 集合 | Tables 集合 | Users 集合 | Views 集合


GetObjectOwner 方法 (ADOX)

ADOX 2.5 API 参考

GetObjectOwner 方法

返回 Catalog 中的对象的所有者。

语法

Owner = Catalog.GetObjectOwner(ObjectName, ObjectType [, ObjectTypeId])

返回值

返回 String 值，该值指定拥有对象的 User 或 Group 的 Name。

参数

ObjectName
String 值，指定要返回其所有者的对象的名称。
ObjectType
Long 值，该值可以是一个 ObjectTypeEnum 常量，指定要获得其所有者的对象的类型。
ObjectTypeId
可选。Variant 值，指定 OLE DB 规范未定义的提供者对象类型的 GUID。如果 ObjectType 设置为 adPermObjProviderSpecific，那么这个参数是必需的。否则，将不使用它。

说明

如果提供者不支持返回对象的所有者，将出现错误。

请参阅

GetObjectOwner 和 SetObjectOwner 方法范例 (VB)

SetObjectOwner 方法

应用于：Catalog 对象


GetPermissions 方法 (ADOX)

ADOX 2.5 API 参考

GetPermissions 方法

返回组或用户对一个对象或对象容器所具有的权限。

语法

ReturnValue = GroupOrUser.GetPermissions(Name, ObjectType
   [, ObjectTypeId])

返回值

返回 Long 值，该值指定包含组或用户对该对象具有的权限的位掩码。此值可以是一个或多个 RightsEnum 常量。

参数

Name
Variant 值，指定要设置其权限的对象的名称。如果想获得对象容器的权限，请将 Name 设置为 Null 值。
ObjectType
Long 值，该值可以是一个 ObjectTypeEnum 常量，指定要获得其权限的对象的类型。
ObjectTypeId
可选。Variant 值，指定 OLE DB 规范未定义的提供者对象类型的 GUID。如果 ObjectType 设置为 adPermObjProviderSpecific，那么这个参数是必需的。否则，将不使用它。

请参阅

GetPermissions 和 SetPermissions 方法范例 (VB)

Name 属性 | SetPermissions 方法

应用于：Group 对象 | User 对象


SetObjectOwner 方法 [ADOX]

ADOX 2.5 API 参考

SetObjectOwner 方法

指定 Catalog 中的对象的所有者。

语法

Catalog.SetObjectOwner ObjectName, ObjectType , OwnerName [, ObjectTypeId]

参数

ObjectName
String 值，指定要指定其所有者的对象的名称。
ObjectType
Long 值，该值可以是一个 ObjectTypeEnum 常量，指定所有者的类型。
OwnerName
String 值，该值指定拥有对象的 User 或 Group 的 Name。
ObjectTypeId
可选。Variant 值，指定 OLE DB 规范未定义的提供者对象类型的 GUID。如果 ObjectType 设置为 adPermObjProviderSpecific，那么这个参数是必需的。否则，将不使用它。

说明

如果提供者不支持指定对象的所有者，将出现错误。

请参阅

GetObjectOwner 和 SetObjectOwner 方法范例 (VB)

GetObjectOwner 方法

应用于：Catalog 对象


SetPermissions 方法 (ADOX)

ADOX 2.5 API 参考

SetPermissions 方法

指定组或用户对一个对象所具有的权限。

语法

GroupOrUser.SetPermissions Name, ObjectType, Action, Rights [, Inherit]
   [, ObjectTypeId]

参数

Name
String 值，指定要设置其权限的对象的名称。
ObjectType
Long 值，该值可以是一个 ObjectTypeEnum 常量，指定要获得其权限的对象的类型。
Action
Long 值，可以是一个 ActionEnum 常量，指定设置权限时要执行的操作的类型。
Rights
Long 值，该值可以是一个或多个 RightsEnum 常量的位掩码，指示要设置的权限。
Inherit
可选。Long 值，该值可以是一个 InheritTypeEnum 常量，指定对象继承这些权限的方式。默认值为 adInheritNone。
ObjectTypeId
可选。Variant 值，指定 OLE DB 规范未定义的提供者对象类型的 GUID。如果 ObjectType 设置为 adPermObjProviderSpecific，那么这个参数是必需的。否则，将不使用它。

说明

如果提供者不支持为组或用户设置访问权限，将出现错误。

注意 调用 SetPermissions 时，把 Actions 设置为 adAccessRevoke 将覆盖 Rights 参数的所有设置。如果想使在 Rights 参数中指定的权限生效，请不要将 Actions 设置为 adAccessRevoke。

请参阅

GetPermissions 和 SetPermissions 方法范例 (VB)

GetPermissions 方法 | Name 属性

应用于：Group 对象 | User 对象


ADOX 枚举常量

为了帮助调试，ADOX 枚举常量列出了每个常量的值。但是，此值仅供参考。在不同的 ADOX 版本中，它可能会有变化。代码只应取决于枚举常量的名称，而不是实际值。

下面是已定义的枚举常量。

枚举 | 说明
ActionEnum | 指定调用 SetPermissions 时要执行的操作的类型。
AllowNullsEnum | 指定是否索引值为 Null 的记录。
ColumnAttributesEnum | 指定 Column 的特性。
DataTypeEnum | 指定 Field、Parameter 或 Property 的数据类型。
InheritTypeEnum | 指定对象如何继承用 SetPermissions 设置的权限。
KeyTypeEnum | 指定 Key 的类型：主键、外键或唯一键。
ObjectTypeEnum | 指定要设置权限或所有权的数据库对象的类型。
RightsEnum | 指定组或用户对一个对象所具有的权限。
RuleEnum | 指定删除 Key 时要遵循的规则。
SortOrderEnum | 指定索引列的排序顺序。

请参阅

ADOX API 参考 | Microsoft ADOX 程序员参考

© 1998-2003 Microsoft Corporation。保留所有权。


ActionEnum

指定调用 SetPermissions时要执行的操作的类型。

常量 | 值 | 说明
adAccessDeny | 3 | 组或用户将被拒绝赋予所指定的权限。
adAccessGrant | 1 | 组或用户将至少具有所请求的权限。
adAccessRevoke | 4 | 组或用户具有的任何显式访问权限将被取消。
adAccessSet | 2 | 组或用户将只具有所请求的权限。


AllowNullsEnum

指定是否索引值为 Null 的记录。

常量 | 值 | 说明
adIndexNullsAllow | 0 | 索引允许存在键列为 Null 的项目。如果在键列中输入 Null 值，此项目将被插入索引。
adIndexNullsDisallow | 1 | 默认值。索引不允许存在键列为 Null 的项目。如果在键列中输入 Null 值，将出现错误。
adIndexNullsIgnore | 2 | 索引不插入包含 Null 键的项目。如果在键列中输入 Null 值，该项目将被忽略，并且不出现错误。
adIndexNullsIgnoreAny | 4 | 索引不插入某个键列中具有 Null 值的项目。对于具有多列键的索引，如果在某个列中输入 Null 值，该项目将被忽略，并且不出现错误。

请参阅

应用于：IndexNulls 属性


ColumnAttributesEnum

指定 Column的特性。

常量 | 值 | 说明
adColFixed | 1 | 列是定长的。
adColNullable | 2 | 列中可以包含 Null 值。

请参阅

应用于：Attributes 属性


InheritTypeEnum

指定对象如何继承用 SetPermissions 设置的权限。

常量 | 值 | 说明
adInheritBoth | 3 | 主对象中包含的对象和其他容器均继承该项目。
adInheritContainers | 2 | 主对象中包含的其他容器继承该项目。
adInheritNone | 0 | 默认值。未发生继承。
adInheritNoPropagate | 4 | adInheritObjects 和 adInheritContainers 标志未被传播给继承的项目。
adInheritObjects | 1 | 容器中的非容器对象继承权限。

请参阅

应用于：SetPermissions 方法


KeyTypeEnum

指定 Key 的类型：主键、外键或唯一键。

常量 | 值 | 说明
adKeyPrimary | 1 | 默认值。此键是主键。
adKeyForeign | 2 | 此键是外键。
adKeyUnique | 3 | 此键是唯一键。

请参阅

应用于：Type 属性 (Key)


ObjectTypeEnum

指定要设置权限或所有权的数据库对象的类型。

常量 | 值 | 说明
adPermObjColumn | 2 | 对象是列。
adPermObjDatabase | 3 | 对象是数据库。
adPermObjProcedure | 4 | 对象是过程。
adPermObjProviderSpecific | -1 | 对象是由提供者定义的类型。如果 ObjectType 参数是 adPermObjProviderSpecific，并且未提供 ObjectTypeId，将出现错误。
adPermObjTable | 1 | 对象是表。
adPermObjView | 5 | 对象是视图。

请参阅

应用于：GetObjectOwner 方法 | GetPermissions 方法 | SetObjectOwner 方法 | SetPermissions 方法


RightsEnum

指定组或用户对一个对象所具有的权限。

常量 | 值 | 说明
adRightCreate | 16384 (&H4000) | 用户或组具有创建此类型新对象的权限。
adRightDelete | 65536 (&H10000) | 用户或组具有从对象中删除数据的权限。对于诸如 Table 的对象，用户具有从记录中删除数据值的权限。
adRightDrop | 256 (&H100) | 用户或组具有从目录中删除对象的权限。例如，可以用 DROP TABLE SQL 命令删除 Table。
adRightExclusive | 512 (&H200) | 用户或组具有独占访问对象的权限。
adRightExecute | 536870912 (&H20000000) | 用户或组具有执行对象的权限。
adRightFull | 268435456 (&H10000000) | 用户或组具有对该对象的所有权限。
adRightInsert | 32768 (&H8000) | 用户或组具有插入对象的权限。对于诸如 Table 的对象，用户具有向表中插入数据的权限。
adRightMaximumAllowed | 33554432 (&H2000000) | 用户或组具有提供者所允许的最大权限数。某些权限依赖于提供者。
adRightNone | 0 | 用户或组对该对象没有权限。
adRightRead | -2147483648 (&H80000000) | 用户或组具有读取对象的权限。对于诸如 Table 的对象，用户具有读取表中的数据的权限。
adRightReadDesign | 1024 (&H400) | 用户或组具有读取对象设计的权限。
adRightReadPermissions | 131072 (&H20000) | 用户或组可以查看目录中的对象的某些权限，但不能更改。
adRightReference | 8192 (&H2000) | 用户或组具有引用对象的权限。
adRightUpdate | 1073741824 (&H40000000) | 用户或组具有更新对象的权限。对于诸如 Table 的对象，用户具有更新表中的数据的权限。
adRightWithGrant | 4096 (&H1000) | 用户或组具有授予对象权限的权限。
adRightWriteDesign | 2048 (&H800) | 用户或组具有修改对象设计的权限。
adRightWriteOwner | 524288 (&H80000) | 用户或组具有修改对象所有者的权限。
adRightWritePermissions | 262144 (&H40000) | 用户或组可以修改目录中的对象的某些权限。

请参阅

应用于：GetPermissions 方法 | SetPermissions 方法


RuleEnum

指定删除 Key 时要遵循的规则。

常量 | 值 | 说明
adRICascade | 1 | 层叠更改。
adRINone | 0 | 默认值。未发生操作。
adRISetDefault | 3 | 外键值设置为默认值。
adRISetNull | 2 | 外键值设置为 Null。

请参阅

应用于：DeleteRule 属性


SortOrderEnum

指定索引列的排序顺序。

常量 | 值 | 说明
adSortAscending | 1 | 默认值。列的排序顺序为升序。
adSortDescending | 2 | 列的排序顺序为降序。

请参阅

应用于：SortOrder 属性


ADOX 代码范例

通过下列代码范例来学习如何使用 ADOX 对象、方法、属性和事件。

注意 请将整个代码范例粘贴到代码编辑器中。如果只使用部分范例或者丢失了段落格式，范例可能无法正确运行。
  • Microsoft Visual Basic 中的 ADOX 代码范例
  • Microsoft Visual C++ 中的 ADOX 代码范例

请参阅

Catalog 的 ActiveConnection 属性范例 (VB) | Columns 和 Tables 的 Append 方法，Name 属性范例 (VB) | Command 和 CommandText 属性范例 (VB) | Connection 的 Close 方法，Table 的 Type 属性范例 (VB) | GetPermissions 和 SetPermissions 方法范例 (VB) | Indexes 的 Append 方法范例 (VB) | Keys 的 Append 方法，Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VB) | Microsoft ADOX 程序员参考 | Parameters 集合，Command 属性范例 (VB) | ParentCatalog 属性范例 (VB) | Procedures 的 Append 方法范例 (VB) | Procedures 的 Delete 方法范例 (VB) | Procedures 的 Refresh 方法范例 (VB) | Views 和 Fields 集合范例 (VB) | Views 的 Append 方法范例 (VB) | Views 集合，CommandText 属性范例 (VB) | Views 的 Delete 方法范例 (VB) | Views 的 Refresh 方法范例 (VB)


Microsoft Visual Basic 中的 ADOX 代码范例

这些主题提供了帮助用户了解如何使用 ADOX 的代码范例。所有代码范例均使用 Microsoft Visual Basic 编写。

注意 请将 Sub 和 End Sub 之间的整个代码范例粘贴到您的代码编辑器中。如果使用部分范例或丢失段落格式，那么范例可能无法正确运行。

方法

  • Columns 和 Tables 的 Append 方法、Name 属性范例 (VB)
  • Connection 的 Close 方法，Table 的 Type 属性范例 (VB)
  • Create 方法范例 (VB)
  • GetObjectOwner 和 SetObjectOwner 方法范例 (VB)
  • GetPermissions 和 SetPermissions 方法范例 (VB)
  • Groups 和 Users 的 Append、ChangePassword 方法范例 (VB)
  • Indexes 的 Append 方法范例 (VB)
  • Keys 的 Append 方法，Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VB)
  • Procedures 的 Append 方法范例 (VB)
  • Procedures 的 Delete 方法范例 (VB)
  • Procedures 的 Refresh 方法范例 (VB)
  • Views 的 Append 方法范例 (VB)
  • Views 的 Delete 方法范例 (VB)
  • Views 的 Refresh 方法范例 (VB)

属性

  • Attributes 属性范例 (VB)
  • Catalog 的 ActiveConnection 属性范例 (VB)
  • Clustered 属性范例 (VB)
  • Command 和 CommandText 属性范例 (VB)
  • Command 属性，Parameters 集合范例 (VB)
  • CommandText 属性，Views 集合范例 (VB)
  • DateCreated 和 DateModified 属性范例 (VB)
  • DefinedSize 属性范例 (VB)
  • DeleteRule 属性范例 (VB)
  • IndexNulls 属性范例 (VB)
  • Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性，Keys 的 Append 方法范例 (VB)
  • Name 属性、Columns 和 Tables 的 Append 方法范例 (VB)
  • NumericScale 和 Precision 属性范例 (VB)
  • ParentCatalog 属性范例 (VB)
  • PrimaryKey 和 Unique 属性范例 (VB)
  • SortOrder 属性范例 (VB)
  • Table 的 Type 属性，Connection 的 Close 方法范例 (VB)

集合

  • Parameters 集合，Command 属性范例 (VB)
  • Views 和 Fields 集合范例 (VB)
  • Views 集合，CommandText 属性范例 (VB)


Attributes 属性范例 (VB)

本范例演示了 Column 的 Attributes 属性。把它设置为 adColNullable 可允许用户将 Recordset Field 的值设置为空字符串。在这种情况下，用户可以区别出有未知数据的记录和有不适用数据的记录。

' BeginAttributesVB
Sub Main()
    On Error GoTo AttributesXError

    Dim cnn As New ADODB.Connection
    Dim cat As New ADOX.Catalog
    Dim colTemp As New ADOX.Column
    Dim rstEmployees As New Recordset
    Dim strMessage As String
    Dim strInput As String
    Dim tblEmp As ADOX.Table

    ' Connect the catalog.
    cnn.Open "Provider='Microsoft.Jet.OLEDB.4.0';data source=" & _
        "'c:\Program Files\Microsoft Office\Office\Samples\Northwind.mdb';"
    Set cat.ActiveConnection = cnn

    Set tblEmp = cat.Tables("Employees")

    ' Create a new Field object and append it to the Fields
    ' collection of the Employees table.
    colTemp.Name = "FaxPhone"
    colTemp.Type = adVarWChar
    colTemp.DefinedSize = 24
    colTemp.Attributes = adColNullable
    cat.Tables("Employees").Columns.Append colTemp.Name, adWChar, 24

    ' Open the Employees table for updating as a Recordset
    rstEmployees.Open "Employees", cnn, adOpenKeyset, adLockOptimistic, adCmdTable

    With rstEmployees
        ' Get user input.
        strMessage = "Enter fax number for " & _
            !FirstName & " " & !LastName & "." & vbCr & _
            "[? - unknown, X - has no fax]"
        strInput = UCase(InputBox(strMessage))
        If strInput <> "" Then
            Select Case strInput
                Case "?"
                    !FaxPhone = Null
                Case "X"
                    !FaxPhone = ""
                Case Else
                    !FaxPhone = strInput
            End Select
            .Update

            ' Print report.
            Debug.Print "Name - Fax number"
            Debug.Print !FirstName & " " & !LastName & " - ";

            If IsNull(!FaxPhone) Then
                Debug.Print "[Unknown]"
            Else
                If !FaxPhone = "" Then
                    Debug.Print "[Has no fax]"
                Else
                    Debug.Print !FaxPhone
                End If
            End If

        End If

        .Close
    End With

    'Clean up
    tblEmp.Columns.Delete colTemp.Name
    cnn.Close
    Set rstEmployees = Nothing
    Set cat = Nothing
    Set colTemp = Nothing
    Set cnn = Nothing
    Exit Sub

AttributesXError:

    If Not rstEmployees Is Nothing Then
        If rstEmployees.State = adStateOpen Then rstEmployees.Close
    End If
    Set rstEmployees = Nothing

    If Not tblEmp Is Nothing Then tblEmp.Columns.Delete colTemp.Name

    Set cat = Nothing
    Set colTemp = Nothing

    If Not cnn Is Nothing Then
        If cnn.State = adStateOpen Then cnn.Close
    End If
    Set cnn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

End Sub
' EndAttributesVB

请参阅

Attributes 属性 | Catalog 对象 | Column 对象


Catalog 的 ActiveConnection 属性范例 (VB)

将 ActiveConnection 属性设置为有效值，打开连接就可以“打开”目录。通过打开的目录可以访问包含在其中的模式对象。

' BeginOpenConnectionVB
Sub OpenConnection()
    On Error GoTo OpenConnectionError

    Dim cnn As New ADODB.Connection
    Dim cat As New ADOX.Catalog

    cnn.Open "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source= 'c:\Program Files\Microsoft Office\" & _
        "Office\Samples\Northwind.mdb';"
    Set cat.ActiveConnection = cnn
    Debug.Print cat.Tables(0).Type

    'Clean up
    cnn.Close
    Set cat = Nothing
    Set cnn = Nothing
    Exit Sub

OpenConnectionError:

    Set cat = Nothing

    If Not cnn Is Nothing Then
        If cnn.State = adStateOpen Then cnn.Close
    End If
    Set cnn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndOpenConnectionVB

将 ActiveConnection 属性设置为有效的连接字符串也可以“打开”目录。

' BeginOpenConnection2VB
Sub Main()
    On Error GoTo OpenConnectionWithStringError
    Dim cat As New ADOX.Catalog

    cat.ActiveConnection = "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\Microsoft Office\" & _
        "Office\Samples\Northwind.mdb';"
    Debug.Print cat.Tables(0).Type

    'Clean up
    Set cat.ActiveConnection = Nothing
    Exit Sub

OpenConnectionWithStringError:
    Set cat = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndOpenConnection2VB

请参阅

ActiveConnection 属性 | Catalog 对象 | Table 对象 | Tables 集合 | Type 属性 (Table)


Clustered 属性范例 (VB)

本范例演示了 Index 的 Clustered 属性。注意，Microsoft Jet 数据库不支持分簇索引，因此本范例将对 Northwind 数据库中所有索引的 Clustered 属性返回 False。

' BeginClusteredVB
Sub Main()
    On Error GoTo ClusteredXError

    Dim cnn As New ADODB.Connection
    Dim cat As New ADOX.Catalog
    Dim tblLoop As ADOX.Table
    Dim idxLoop As ADOX.Index
    Dim strCnn As String

    strCnn = "Provider='SQLOLEDB';Data Source='MySqlServer';Initial Catalog='pubs';" & _
        "Integrated Security='SSPI';"
    ' Connect the catalog.
    cnn.Open strCnn
    cat.ActiveConnection = cnn

    ' Enumerate Tables
    For Each tblLoop In cat.Tables
        'Enumerate Indexes
        For Each idxLoop In tblLoop.Indexes
            Debug.Print tblLoop.Name & " " & _
                idxLoop.Name & " " & idxLoop.Clustered
        Next idxLoop
    Next tblLoop

    'Clean up
    cnn.Close
    Set cat = Nothing
    Set cnn = Nothing
    Exit Sub

ClusteredXError:

    Set cat = Nothing

    If Not cnn Is Nothing Then
        If cnn.State = adStateOpen Then cnn.Close
    End If
    Set cnn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndClusteredVB

请参阅

Catalog 对象 | Clustered 属性 | Index 对象 | Table 对象


Columns 和 Tables 的 Append 方法、Name 属性范例 (VB)

下面的代码演示如何创建新的表。

' BeginCreateTableVB
Sub Main()
    On Error GoTo CreateTableError

    Dim tbl As New Table
    Dim cat As New ADOX.Catalog

    ' Open the Catalog.
    cat.ActiveConnection = "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\Microsoft Office\" & _
        "Office\Samples\Northwind.mdb';"

    tbl.Name = "MyTable"
    tbl.Columns.Append "Column1", adInteger
    tbl.Columns.Append "Column2", adInteger
    tbl.Columns.Append "Column3", adVarWChar, 50
    cat.Tables.Append tbl
    Debug.Print "Table 'MyTable' is added."

    'Delete the table as this is a demonstration.
    cat.Tables.Delete tbl.Name
    Debug.Print "Table 'MyTable' is deleted."

    'Clean up
    Set cat.ActiveConnection = Nothing
    Set cat = Nothing
    Set tbl = Nothing
    Exit Sub

CreateTableError:

    Set cat = Nothing
    Set tbl = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndCreateTableVB

请参阅

Append 方法 (Columns) | Append 方法 (Tables) | Column 对象 | Columns 集合 | Name 属性 | Table 对象 | Tables 集合


Command 和 CommandText 属性范例 (VB)

下面的代码演示如何使用 Command 属性更新过程文本。

' BeginProcedureTextVB
Sub Main()
    On Error GoTo ProcedureTextError

    Dim cnn As New ADODB.Connection
    Dim cat As New ADOX.Catalog
    Dim cmd As New ADODB.Command

    ' Open the Connection
    cnn.Open "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\Microsoft Office\" & _
        "Office\Samples\Northwind.mdb';"

    ' Open the catalog
    Set cat.ActiveConnection = cnn

    ' Get the Command
    Set cmd = cat.Procedures("CustomerById").Command

    ' Update the CommandText
    cmd.CommandText = "Select CustomerId, CompanyName, ContactName " & _
        "From Customers " & _
        "Where CustomerId = [CustId]"

    ' Update the Procedure
    Set cat.Procedures("CustomerById").Command = cmd

    'Clean up
    cnn.Close
    Set cat = Nothing
    Set cmd = Nothing
    Set cnn = Nothing
    Exit Sub

ProcedureTextError:
    Set cat = Nothing
    Set cmd = Nothing

    If Not cnn Is Nothing Then
        If cnn.State = adStateOpen Then cnn.Close
    End If
    Set cnn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndProcedureTextVB

请参阅

ActiveConnection 属性 | Catalog 对象 | Command 属性 | Procedure 对象 | Procedures 集合


Connection 的 Close 方法，Table 的 Type 属性范例 (VB)

将 ActiveConnection 属性设置为 Nothing 可“关闭”目录。关联的集合将被清空。目录中任何通过模式对象创建的对象都将被孤立。这些已缓存对象中的任何属性仍然可用，但试图读取需要调用提供者的属性时，操作将失败。

' BeginCloseConnectionVB
Sub Main()
    On Error GoTo CloseConnectionByNothingError

    Dim cnn As New ADODB.Connection
    Dim cat As New ADOX.Catalog
    Dim tbl As ADOX.Table

    cnn.Open "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source= 'c:\Program Files\Microsoft Office\" & _
        "Office\Samples\Northwind.mdb';"
    Set cat.ActiveConnection = cnn
    Set tbl = cat.Tables(0)
    Debug.Print tbl.Type    ' Cache tbl.Type info
    Set cat.ActiveConnection = Nothing
    Debug.Print tbl.Type    ' tbl is orphaned
    ' Previous line will succeed if this was cached
    Debug.Print tbl.Columns(0).DefinedSize
    ' Previous line will fail if this info has not been cached

    'Clean up
    cnn.Close
    Set cat = Nothing
    Set cnn = Nothing
    Exit Sub

CloseConnectionByNothingError:
    Set cat = Nothing

    If Not cnn Is Nothing Then
        If cnn.State = adStateOpen Then cnn.Close
    End If
    Set cnn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndCloseConnectionVB

关闭用于“打开”目录的 Connection 对象应该与将 ActiveConnection 属性设置为 Nothing 的效果相同。

Sub CloseConnection()
    On Error GoTo CloseConnectionError

    Dim cnn As New ADODB.Connection
    Dim cat As New ADOX.Catalog
    Dim tbl As ADOX.Table

    cnn.Open "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source= 'c:\Program Files\Microsoft Office\" & _
        "Office\Samples\Northwind.mdb';"
    Set cat.ActiveConnection = cnn
    Set tbl = cat.Tables(0)
    Debug.Print tbl.Type    ' Cache tbl.Type info
    cnn.Close
    Debug.Print tbl.Type    ' tbl is orphaned
    ' Previous line will succeed if this was cached
    Debug.Print tbl.Columns(0).DefinedSize
    ' Previous line will fail if this info has not been cached

    'Clean up
    Set cat = Nothing
    Set cnn = Nothing
    Exit Sub

CloseConnectionError:

    Set cat = Nothing

    If Not cnn Is Nothing Then
        If cnn.State = adStateOpen Then cnn.Close
    End If
    Set cnn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndCloseConnection2VB

请参阅

ActiveConnection 属性 | Catalog 对象 | Column 对象 | Columns 集合 | Table 对象 | Tables 集合 | Type 属性 (Table)


Create 方法范例 (VB)

下面的代码显示如何用 Create 方法创建新的 Microsoft Jet 数据库。

' BeginCreateDatabseVB
Sub CreateDatabase()
    On Error GoTo CreateDatabaseError

    Dim cat As New ADOX.Catalog
    cat.Create "Provider='Microsoft.Jet.OLEDB.4.0';Data Source='c:\new.mdb'"

    'Clean up
    Set cat = Nothing
    Exit Sub

CreateDatabaseError:
    Set cat = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndCreateDatabaseVB

请参阅

Catalog 对象 | Create 方法


DateCreated 和 DateModified 属性范例 (VB)

本范例通过向现有的 Table 中添加新的 Column 以及创建新的 Table 来演示 DateCreated 和 DateModified 属性。运行本范例需要 DateOutput 过程。

' BeginDateCreatedVB
Sub Main()
    On Error GoTo DateCreatedXError

    Dim cat As New ADOX.Catalog
    Dim tblEmployees As ADOX.Table
    Dim tblNewTable As ADOX.Table

    ' Connect the catalog.
    cat.ActiveConnection = "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\" & _
        "Microsoft Office\Office\Samples\Northwind.mdb';"

    With cat
        Set tblEmployees = .Tables("Employees")

        ' Print current information about the Employees table.
        DateOutput "Current properties", tblEmployees

        ' Create and append column to the Employees table.
        tblEmployees.Columns.Append "NewColumn", adInteger
        .Tables.Refresh

        ' Print new information about the Employees table.
        DateOutput "After creating a new column", tblEmployees

        ' Delete new column because this is a demonstration.
        tblEmployees.Columns.Delete "NewColumn"

        ' Create and append new Table object to the Northwind database.
        Set tblNewTable = New ADOX.Table
        tblNewTable.Name = "NewTable"
        tblNewTable.Columns.Append "NewColumn", adInteger
        .Tables.Append tblNewTable
        .Tables.Refresh

        ' Print information about the new Table object.
        DateOutput "After creating a new table", .Tables("NewTable")

        ' Delete new Table object because this is a demonstration.
        .Tables.Delete tblNewTable.Name
    End With

    'Clean up
    Set cat.ActiveConnection = Nothing
    Set cat = Nothing
    Exit Sub

DateCreatedXError:
    Set cat = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

End Sub

Sub DateOutput(strTemp As String, tblTemp As ADOX.Table)
    ' Print DateCreated and DateModified information about
    ' specified Table object.
    Debug.Print strTemp
    Debug.Print "    Table: " & tblTemp.Name
    Debug.Print "        DateCreated = " & tblTemp.DateCreated
    Debug.Print "        DateModified = " & tblTemp.DateModified
    Debug.Print
End Sub
' EndDateCreatedVB

请参阅

DateCreated 属性 | DateModified 属性 | Procedure 对象 | Procedures 集合 | View 对象 | Views 集合


DefinedSize 属性范例 (VB)

本范例演示 Column 的 DefinedSize 属性。此代码将重新定义 Northwind 数据库 Employees 表的 FirstName 列的大小。然后，基于 Employees 表的 Recordset FirstName Field 的值的变化将显示出来。注意，在默认情况下，重新定义 DefinedSize 属性后，FirstName 字段用空格填充。

' BeginDefinedSizeVB
Public Sub Main()
    On Error GoTo DefinedSizeXError

    Dim rstEmployees As ADODB.Recordset
    Dim catNorthwind As New ADOX.Catalog
    Dim colFirstName As ADOX.Column
    Dim colNewFirstName As New ADOX.Column
    Dim aryFirstName() As String
    Dim i As Integer
    Dim strCnn As String

    strCnn = "Provider='Microsoft.Jet.OLEDB.4.0';" & _
             "Data Source='c:\Program Files\" & _
             "Microsoft Office\Office\Samples\Northwind.mdb';"

    ' Open a Recordset for the Employees table.
    Set rstEmployees = New ADODB.Recordset
    rstEmployees.Open "Employees", strCnn, adOpenKeyset, , adCmdTable
    ReDim aryFirstName(rstEmployees.RecordCount)

    ' Open a Catalog for the Northwind database,
    ' using same connection as rstEmployees
    Set catNorthwind.ActiveConnection = rstEmployees.ActiveConnection

    ' Loop through the recordset displaying the contents
    ' of the FirstName field, the field's defined size,
    ' and its actual size.
    ' Also store FirstName values in aryFirstName array.
    rstEmployees.MoveFirst
    Debug.Print " "
    Debug.Print "Original Defined Size and Actual Size"
    i = 0
    Do Until rstEmployees.EOF
        Debug.Print "Employee name: " & rstEmployees!FirstName & _
            " " & rstEmployees!LastName
        Debug.Print "    FirstName Defined size: " _
            & rstEmployees!FirstName.DefinedSize
        Debug.Print "    FirstName Actual size: " & _
            rstEmployees!FirstName.ActualSize
            If Not rstEmployees!FirstName = Null Then
                aryFirstName(i) = rstEmployees!FirstName
            End If
        rstEmployees.MoveNext
        i = i + 1
    Loop
    rstEmployees.Close

    ' Redefine the DefinedSize of FirstName in the catalog
    Set colFirstName = catNorthwind.Tables("Employees").Columns("FirstName")
    colNewFirstName.Name = colFirstName.Name
    colNewFirstName.Type = colFirstName.Type
    colNewFirstName.DefinedSize = colFirstName.DefinedSize + 1

    ' Append new FirstName column to catalog
    catNorthwind.Tables("Employees").Columns.Delete colFirstName.Name
    catNorthwind.Tables("Employees").Columns.Append colNewFirstName

    ' Open Employee table in Recordset for updating
    rstEmployees.Open "Employees", catNorthwind.ActiveConnection, _
        adOpenKeyset, adLockOptimistic, adCmdTable

    ' Loop through the recordset displaying the contents
    ' of the FirstName field, the field's defined size,
    ' and its actual size.
    ' Also restore FirstName values from aryFirstName.
    rstEmployees.MoveFirst
    Debug.Print " "
    Debug.Print "New Defined Size and Actual Size"
    i = 0
    Do Until rstEmployees.EOF
        rstEmployees!FirstName = aryFirstName(i)
        Debug.Print "Employee name: " & rstEmployees!FirstName & _
            " " & rstEmployees!LastName
        Debug.Print "    FirstName Defined size: " _
            & rstEmployees!FirstName.DefinedSize
        Debug.Print "    FirstName Actual size: " & _
            rstEmployees!FirstName.ActualSize
        rstEmployees.MoveNext
        i = i + 1
    Loop
    rstEmployees.Close

    ' Restore original FirstName column to catalog
    catNorthwind.Tables("Employees").Columns.Delete colNewFirstName.Name
    catNorthwind.Tables("Employees").Columns.Append colFirstName

    ' Restore original FirstName values to Employees table
    rstEmployees.Open "Employees", catNorthwind.ActiveConnection, _
        adOpenKeyset, adLockOptimistic, adCmdTable

    rstEmployees.MoveFirst
    i = 0
    Do Until rstEmployees.EOF
        rstEmployees!FirstName = aryFirstName(i)
        rstEmployees.MoveNext
        i = i + 1
    Loop
    rstEmployees.Close

    'Clean up
    Set catNorthwind = Nothing
    Set colNewFirstName = Nothing
    Set colFirstName = Nothing
    Set rstEmployees = Nothing
    Exit Sub

DefinedSizeXError:
    Set catNorthwind = Nothing
    Set colNewFirstName = Nothing
    Set colFirstName = Nothing

    If Not rstEmployees Is Nothing Then
        If rstEmployees.State = adStateOpen Then rstEmployees.Close
    End If
    Set rstEmployees = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

End Sub
' EndDefinedSizeVB

请参阅

Column 对象 | DefinedSize 属性


DeleteRule 属性范例 (VB)

本范例演示 Key 对象的 DeleteRule 属性。该代码将追加一个新的 Table，然后定义新的主键，将 DeleteRule 设置为 adRICascade。

' BeginDeleteRuleVB
Sub Main()
    On Error GoTo DeleteRuleXError

    Dim kyPrimary As New ADOX.Key
    Dim cat As New ADOX.Catalog
    Dim tblNew As New ADOX.Table

    ' Connect the catalog
    cat.ActiveConnection = "Provider='Microsoft.Jet.OLEDB.4.0';" & _
                     "data source='c:\Program Files\" & _
                     "Microsoft Office\Office\Samples\Northwind.mdb';"

    ' Name new table
    tblNew.Name = "NewTable"

    ' Append a numeric and a text field to new table.
    tblNew.Columns.Append "NumField", adInteger, 20
    tblNew.Columns.Append "TextField", adVarWChar, 20

    ' Append the new table
    cat.Tables.Append tblNew

    ' Define the Primary key
    kyPrimary.Name = "NumField"
    kyPrimary.Type = adKeyPrimary
    kyPrimary.RelatedTable = "Customers"
    kyPrimary.Columns.Append "NumField"
    kyPrimary.Columns("NumField").RelatedColumn = "CustomerId"
    kyPrimary.DeleteRule = adRICascade

    ' Append the primary key
    cat.Tables("NewTable").Keys.Append kyPrimary
    Debug.Print "The primary key is appended."

    'Delete the table as this is a demonstration.
    cat.Tables.Delete tblNew.Name
    Debug.Print "The primary key is deleted."

    'Clean up
    Set cat.ActiveConnection = Nothing
    Set cat = Nothing
    Set kyPrimary = Nothing
    Set tblNew = Nothing
    Exit Sub

DeleteRuleXError:

    Set cat = Nothing
    Set kyPrimary = Nothing
    Set tblNew = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

End Sub
' EndDeleteRuleVB

请参阅

DeleteRule 属性 | Key 对象


GetObjectOwner 和 SetObjectOwner 方法范例 (VB)

本范例演示 GetObjectOwner 和 SetObjectOwner 方法。此代码假定存在 Accounting 组（要查看如何向系统中添加这个组，请参阅 Groups 和 Users 的 Append、ChangePassword 方法范例 (VB)）。Categories 表的所有者设置为 Accounting。

' BeginOwnersVB
Sub Main()
    On Error GoTo OwnersXError

    Dim tblLoop As New ADOX.Table
    Dim cat As New ADOX.Catalog
    Dim strOwner As String

    ' Open the Catalog.
    cat.ActiveConnection = "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\" & _
        "Microsoft Office\Office\Samples\Northwind.mdb';" & _
        "jet oledb:system database=" & _
        "'c:\Program Files\Microsoft Office\Office\system.mdw'"

    ' Print the original owner of Categories
    strOwner = cat.GetObjectOwner("Categories", adPermObjTable)
    Debug.Print "Owner of Categories: " & strOwner

    ' Set the owner of Categories to Accounting
    cat.SetObjectOwner "Categories", adPermObjTable, "Accounting"

    ' List the owners of all tables and columns in the catalog.
    For Each tblLoop In cat.Tables
        Debug.Print "Table: " & tblLoop.Name
        Debug.Print "   Owner: " & _
            cat.GetObjectOwner(tblLoop.Name, adPermObjTable)
    Next tblLoop

    ' Restore the original owner of Categories
    cat.SetObjectOwner "Categories", adPermObjTable, strOwner

    'Clean up
    Set cat.ActiveConnection = Nothing
    Set cat = Nothing
    Exit Sub

OwnersXError:

    Set cat = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

End Sub
' EndOwnersVB

请参阅

Catalog 对象 | GetObjectOwner 方法 | SetObjectOwner 方法


GetPermissions 和 SetPermissions 方法范例 (VB)

本范例演示 GetPermissions 和 SetPermissions 方法。下面的代码将赋予管理员用户对 Orders 表的完全访问权限。

' BeginGrantPermissionsVB
Sub GrantPermissions()
    On Error GoTo GrantPermissionsError

    Dim cnn As New ADODB.Connection
    Dim cat As New ADOX.Catalog
    Dim lngPerm As Long

    ' Opens a connection to the northwind database
    ' using the Microsoft Jet 4.0 provider
    cnn.Provider = "Microsoft.Jet.OLEDB.4.0"
    cnn.Open "Data Source='c:\Program Files\" & _
        "Microsoft Office\Office\Samples\Northwind.mdb';" & _
        "jet oledb:system database=" & _
        "'c:\Program Files\Microsoft Office\Office\system.mdw'"

    Set cat.ActiveConnection = cnn

    ' Retrieve original permissions
    lngPerm = cat.Users("admin").GetPermissions("Orders", adPermObjTable)
    Debug.Print "Original permissions: " & Str(lngPerm)

    ' Revoke all permissions
    cat.Users("admin").SetPermissions "Orders", adPermObjTable, _
        adAccessRevoke, adRightFull

    ' Display permissions
    Debug.Print "Revoked permissions: " & _
        Str(cat.Users("admin").GetPermissions("Orders", adPermObjTable))

    ' Give the Admin user full rights on the orders object
    cat.Users("admin").SetPermissions "Orders", adPermObjTable, _
        adAccessSet, adRightFull

    ' Display permissions
    Debug.Print "Full permissions: " & _
        Str(cat.Users("admin").GetPermissions("Orders", adPermObjTable))

    ' Restore original permissions
    cat.Users("admin").SetPermissions "Orders", adPermObjTable, _
        adAccessSet, lngPerm

    ' Display permissions
    Debug.Print "Final permissions: " & _
        Str(cat.Users("admin").GetPermissions("Orders", adPermObjTable))

    'Clean up
    cnn.Close
    Set cat = Nothing
    Set cnn = Nothing
    Exit Sub

GrantPermissionsError:

    Set cat = Nothing

    If Not cnn Is Nothing Then
        If cnn.State = adStateOpen Then cnn.Close
    End If
    Set cnn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

End Sub

' EndGrantPermissionsVB请参阅

Catalog 对象 | GetPermissions 方法 | SetPermissions 方法 | User 对象 | Users 集合


Groups 和 Users 的 Append、ChangePassword 方法范例 (VB)

本范例通过向系统中添加新的 Group 和新的 User 来演示 Groups 的 Append 方法和 Users 的 Append 方法。新的 Group 被追加到新的 User 的 Groups 集合中。因此，新的 User 被添加到 Group 中。同样，ChangePassword 方法用于指定 User 密码。

' BeginGroupVB
Sub Main()
    On Error GoTo GroupXError

    Dim cat As ADOX.Catalog
    Dim usrNew As ADOX.User
    Dim usrLoop As ADOX.User
    Dim grpLoop As ADOX.Group

    Set cat = New ADOX.Catalog

    cat.ActiveConnection = "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\" & _
        "Microsoft Office\Office\Samples\Northwind.mdb';" & _
        "jet oledb:system database=" & _
        "'c:\Program Files\Microsoft Office\Office\system.mdw'"

    With cat
        'Create and append new group with a string.
        .Groups.Append "Accounting"

        ' Create and append new user with an object.
        Set usrNew = New ADOX.User
        usrNew.Name = "Pat Smith"
        usrNew.ChangePassword "", "Password1"
        .Users.Append usrNew

        ' Make the user Pat Smith a member of the
        ' Accounting group by creating and adding the
        ' appropriate Group object to the user's Groups
        ' collection. The same is accomplished if a User
        ' object representing Pat Smith is created and
        ' appended to the Accounting group Users collection
        usrNew.Groups.Append "Accounting"

        ' Enumerate all User objects in the
        ' catalog's Users collection.
        For Each usrLoop In .Users
            Debug.Print "  " & usrLoop.Name
            Debug.Print "    Belongs to these groups:"
            ' Enumerate all Group objects in each User
            ' object's Groups collection.
            If usrLoop.Groups.Count <> 0 Then
                For Each grpLoop In usrLoop.Groups
                    Debug.Print "    " & grpLoop.Name
                Next grpLoop
            Else
                Debug.Print "    [None]"
            End If
        Next usrLoop

        ' Enumerate all Group objects in the default
        ' workspace's Groups collection.
        For Each grpLoop In .Groups
            Debug.Print "  " & grpLoop.Name
            Debug.Print "    Has as its members:"
            ' Enumerate all User objects in each Group
            ' object's Users collection.
            If grpLoop.Users.Count <> 0 Then
                For Each usrLoop In grpLoop.Users
                    Debug.Print "    " & usrLoop.Name
                Next usrLoop
            Else
                Debug.Print "    [None]"
            End If
        Next grpLoop

        ' Delete new User and Group objects because this
        ' is only a demonstration.
        ' These two line are commented out because the sub "OwnersX" uses
        ' the group "Accounting".
'        .Users.Delete "Pat Smith"
'        .Groups.Delete "Accounting"

    End With

    'Clean up
    Set cat.ActiveConnection = Nothing
    Set cat = Nothing
    Set usrNew = Nothing
    Exit Sub

GroupXError:

    Set cat = Nothing
    Set usrNew = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndGroupVB

请参阅

Append 方法 (Groups) | Append 方法 (Users) | Catalog 对象 | ChangePassword 方法 | Group 对象 | Groups 集合 | User 对象 | Users 集合


Indexes 的 Append 方法范例 (VB)

下面的代码演示如何创建新的索引。该索引在表中占两列。

' BeginCreateIndexVB
Sub Main()
    On Error GoTo CreateIndexError

    Dim tbl As New Table
    Dim idx As New ADOX.Index
    Dim cat As New ADOX.Catalog

    'Open the catalog.
    ' Open the Catalog.
    cat.ActiveConnection = "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\Microsoft Office\" & _
        "Office\Samples\Northwind.mdb';"

    ' Define the table and append it to the catalog
    tbl.Name = "MyTable"
    tbl.Columns.Append "Column1", adInteger
    tbl.Columns.Append "Column2", adInteger
    tbl.Columns.Append "Column3", adVarWChar, 50
    cat.Tables.Append tbl
    Debug.Print "Table 'MyTable' is added."

    ' Define a multi-column index
    idx.Name = "multicolidx"
    idx.Columns.Append "Column1"
    idx.Columns.Append "Column2"

    ' Append the index to the table
    tbl.Indexes.Append idx
    Debug.Print "The index is appended to table 'MyTable'."

    'Delete the table as this is a demonstration
    cat.Tables.Delete tbl.Name
    Debug.Print "Table 'MyTable' is deleted."

    'Clean up
    Set cat.ActiveConnection = Nothing
    Set cat = Nothing
    Set tbl = Nothing
    Set idx = Nothing
    Exit Sub

CreateIndexError:
    Set cat = Nothing
    Set tbl = Nothing
    Set idx = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndCreateIndexVB

请参阅

Append 方法 (Indexes) | Index 对象 | Indexes 集合


IndexNulls 属性范例 (VB)

本范例演示 Index 的 IndexNulls 属性。该代码创建新的索引并基于用户输入（通过名为 List1 的列表框）来设置 IndexNulls 的值。然后，Index 被追加到 Northwind Catalog 的 Employees Table 中。新的 Index 被应用于基于 Employees 表的 Recordset，并且该 Recordset 被打开。Employees 表中添加了一个新记录，该记录的索引字段中带有 Null 值。是否显示此新记录取决于 IndexNulls 属性的设置。

' IndexNullsVB
Sub Main()
    On Error GoTo IndexNullsXError

    Dim cnn As New ADODB.Connection
    Dim catNorthwind As New ADOX.Catalog
    Dim idxNew As New ADOX.Index
    Dim rstEmployees As New ADODB.Recordset
    Dim varBookmark As Variant

    ' Connect the catalog.
    cnn.Open "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\" & _
        "Microsoft Office\Office\Samples\Northwind.mdb';"

    Set catNorthwind.ActiveConnection = cnn

    ' Append Country column to new index
    idxNew.Columns.Append "Country"
    idxNew.Name = "NewIndex"

    Dim Response
    Response = MsgBox("Allow 'Null' index? Otherwise ignore 'Null' index.", vbYesNo)
    '"Allow 'Null' index? Otherwise ignore 'Null' index."
    ', vbYesNo + vbCritical + vbDefaultButton2,,,,
    If Response = vbYes Then   ' User chose Yes.
       idxNew.IndexNulls = adIndexNullsAllow
    Else   ' User chose No.
       idxNew.IndexNulls = adIndexNullsIgnore
    End If

    'Append new index to Employees table
    catNorthwind.Tables("Employees").Indexes.Append idxNew

    rstEmployees.Index = idxNew.Name
    rstEmployees.Open "Employees", cnn, adOpenKeyset, _
        adLockOptimistic, adCmdTableDirect

    With rstEmployees
        ' Add a new record to the Employees table.
        .AddNew
        !FirstName = "Gary"
        !LastName = "Haarsager"
        .Update

        ' Bookmark the newly added record
        varBookmark = .Bookmark

        ' Use the new index to set the order of the records.
        .MoveFirst

        Debug.Print "Index = " & .Index & _
            ", IndexNulls = " & idxNew.IndexNulls
        Debug.Print "  Country - Name"

        ' Enumerate the Recordset. The value of the
        ' IndexNulls property will determine if the newly
        ' added record appears in the output.
        Do While Not .EOF
            Debug.Print "    " & _
                IIf(IsNull(!Country), "[Null]", !Country) & _
                " - " & !FirstName & " " & !LastName
            .MoveNext
        Loop

        ' Delete new record because this is a demonstration.
        .Bookmark = varBookmark
        .Delete

        .Close
    End With

    'Clean up
    Set rstEmployees = Nothing
    catNorthwind.Tables("Employees").Indexes.Delete idxNew.Name
    cnn.Close
    Set cnn = Nothing
    Set catNorthwind = Nothing
    Set idxNew = Nothing
    Exit Sub

IndexNullsXError:

    If Not rstEmployees Is Nothing Then
        If rstEmployees.State = adStateOpen Then rstEmployees.Close
    End If
    Set rstEmployees = Nothing

    ' Delete new Index because this is a demonstration.
    If Not catNorthwind Is Nothing Then
        catNorthwind.Tables("Employees").Indexes.Delete idxNew.Name
    End If

    If Not cnn Is Nothing Then
        If cnn.State = adStateOpen Then cnn.Close
    End If
    Set cnn = Nothing

    Set catNorthwind = Nothing
    Set idxNew = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

End Sub
' EndIndexNullsVB

请参阅

Index 对象 | IndexNulls 属性


Keys 的 Append 方法，Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VB)

下面的代码演示如何创建新的外键。假设存在两个表（Customers 和 Orders）。

' BeginCreateKeyVB
Sub Main()
    On Error GoTo CreateKeyError

    Dim kyForeign As New ADOX.Key
    Dim cat As New ADOX.Catalog

    ' Connect the catalog
    cat.ActiveConnection = "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\Microsoft Office\" & _
        "Office\Samples\Northwind.mdb';"

    ' Define the foreign key
    kyForeign.Name = "CustOrder"
    kyForeign.Type = adKeyForeign
    kyForeign.RelatedTable = "Customers"
    kyForeign.Columns.Append "CustomerId"
    kyForeign.Columns("CustomerId").RelatedColumn = "CustomerId"
    kyForeign.UpdateRule = adRICascade

    ' Append the foreign key
    cat.Tables("Orders").Keys.Append kyForeign

    'Delete the Key as this is a demonstration
    cat.Tables("Orders").Keys.Delete kyForeign.Name

    'Clean up
    Set cat.ActiveConnection = Nothing
    Set cat = Nothing
    Set kyForeign = Nothing
    Exit Sub

CreateKeyError:
    Set cat = Nothing
    Set kyForeign = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

End Sub
' EndCreateKeyVB

请参阅

Append 方法 (Columns) | Append 方法 (Keys) | Catalog 对象 | Column 对象 | Columns 集合 | Key 对象 | Keys 集合 | Name 属性 | RelatedColumn 属性 | RelatedTable 属性 | Table 对象 | Tables 集合 | Type 属性 (Key) | UpdateRule 属性


NumericScale 和 Precision 属性范例 (VB)

本范例演示 Column 对象的 NumericScale 和 Precision 属性。此代码显示这两个属性在 Northwind 数据库的 Order Details 表中的值。

' BeginNumericScalePrecVB
Sub Main()
    On Error GoTo NumericScalePrecXError

    Dim cnn As New ADODB.Connection
    Dim cat As New ADOX.Catalog
    Dim tblOD As ADOX.Table
    Dim colLoop As ADOX.Column

    ' Connect the catalog.
    cnn.Open "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "data source='c:\Program Files\" & _
        "Microsoft Office\Office\Samples\Northwind.mdb';"
    Set cat.ActiveConnection = cnn

    ' Retrieve the Order Details table
    Set tblOD = cat.Tables("Order Details")

    ' Display numeric scale and precision of
    ' small integer fields.
    For Each colLoop In tblOD.Columns
        If colLoop.Type = adSmallInt Then
            MsgBox "Column: " & colLoop.Name & vbCr & _
                "Numeric scale: " & _
                colLoop.NumericScale & vbCr & _
                "Precision: " & colLoop.Precision
        End If
    Next colLoop

    'Clean up
    cnn.Close
    Set cat = Nothing
    Set cnn = Nothing
    Exit Sub

NumericScalePrecXError:
    Set cat = Nothing

    If Not cnn Is Nothing Then
        If cnn.State = adStateOpen Then cnn.Close
    End If
    Set cnn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndNumericScalePrecVB

请参阅

Column 对象 | NumericScale 属性 | Precision 属性


Parameters 集合，Command 属性范例 (VB)

下面的代码演示如何通过 Command 对象使用 Command 属性检索过程的参数信息。

' BeginParametersVB
Sub Main()
    On Error GoTo ProcedureParametersError

    Dim cnn As New ADODB.Connection
    Dim cmd As ADODB.Command
    Dim prm As ADODB.Parameter
    Dim cat As New ADOX.Catalog

    ' Open the Connection
    cnn.Open _
        "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\Microsoft Office\" & _
        "Office\Samples\Northwind.mdb';"

    ' Open the catalog
    Set cat.ActiveConnection = cnn

    ' Get the command object
    Set cmd = cat.Procedures("CustomerById").Command

    ' Retrieve Parameter information
    cmd.Parameters.Refresh
    For Each prm In cmd.Parameters
        Debug.Print prm.Name & ":" & prm.Type
    Next

    'Clean up
    cnn.Close
    Set cat = Nothing
    Set cmd = Nothing
    Set cnn = Nothing
    Exit Sub

ProcedureParametersError:

    Set cat = Nothing
    Set cmd = Nothing

    If Not cnn Is Nothing Then
        If cnn.State = adStateOpen Then cnn.Close
    End If
    Set cnn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndParametersVB

请参阅

ActiveConnection 属性 | Catalog 对象 | Command 属性 | Procedure 对象 | Procedures 集合


ParentCatalog 属性范例 (VB)

下面的代码演示如何使用 ParentCatalog 属性在向目录中追加表之前访问提供者特有的属性。该属性为 AutoIncrement，它在 Microsoft Jet 数据库中创建了一个 AutoIncrement 字段。

' BeginCreateAutoIncrColumnVB
Sub Main()
    On Error GoTo CreateAutoIncrColumnError

    Dim cnn As New ADODB.Connection
    Dim cat As New ADOX.Catalog
    Dim tbl As New ADOX.Table

    cnn.Open "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\" & _
        "Microsoft Office\Office\Samples\Northwind.mdb';"
    Set cat.ActiveConnection = cnn

    With tbl
        .Name = "MyContacts"
        Set .ParentCatalog = cat
        ' Create fields and append them to the new Table object.
        .Columns.Append "ContactId", adInteger
        ' Make the ContactId column and auto incrementing column
        .Columns("ContactId").Properties("AutoIncrement") = True
        .Columns.Append "CustomerID", adVarWChar
        .Columns.Append "FirstName", adVarWChar
        .Columns.Append "LastName", adVarWChar
        .Columns.Append "Phone", adVarWChar, 20
        .Columns.Append "Notes", adLongVarWChar
    End With

    cat.Tables.Append tbl
    Debug.Print "Table 'MyContacts' is added."

    ' Delete the table as this is a demonstration.
    cat.Tables.Delete tbl.Name
    Debug.Print "Table 'MyContacts' is delete."

    'Clean up
    cnn.Close
    Set cat = Nothing
    Set tbl = Nothing
    Set cnn = Nothing
    Exit Sub

CreateAutoIncrColumnError:

    Set cat = Nothing
    Set tbl = Nothing

    If Not cnn Is Nothing Then
        If cnn.State = adStateOpen Then cnn.Close
    End If
    Set cnn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

End Sub
' EndCreateAutoIncrColumnVB

请参阅

Append 方法 (Columns) | Append 方法 (Tables) | Catalog 对象 | Column 对象 | Columns 集合 | Name 属性 | ParentCatalog 属性 | Table 对象 | Type 属性 (Column)


PrimaryKey 和 Unique 属性范例 (VB)

本范例演示 Index 的 PrimaryKey 和 Unique 属性。此代码创建了一个具有两列的新表。PrimaryKey 和 Unique 属性用于使一个列成为主键列，该列中的值不允许重复。

' BeginPrimaryKeyVB
Sub Main()
    On Error GoTo PrimaryKeyXError

    Dim catNorthwind As New ADOX.Catalog
    Dim tblNew As New ADOX.Table
    Dim idxNew As New ADOX.Index
    Dim idxLoop As New ADOX.Index
    Dim colLoop As New ADOX.Column

    ' Connect the catalog
    catNorthwind.ActiveConnection = "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\" & _
        "Microsoft Office\Office\Samples\Northwind.mdb';"

    ' Name new table
    tblNew.Name = "NewTable"

    ' Append a numeric and a text field to new table.
    tblNew.Columns.Append "NumField", adInteger, 20
    tblNew.Columns.Append "TextField", adVarWChar, 20

    ' Append new Primary Key index on NumField column
    ' to new table
    idxNew.Name = "NumIndex"
    idxNew.Columns.Append "NumField"
    idxNew.PrimaryKey = True
    idxNew.Unique = True
    tblNew.Indexes.Append idxNew

    ' Append an index on Textfield to new table.
    ' Note the different technique: Specifying index and
    ' column name as parameters of the Append method
    tblNew.Indexes.Append "TextIndex", "TextField"

    ' Append the new table
    catNorthwind.Tables.Append tblNew

    With tblNew
        Debug.Print tblNew.Indexes.Count & " Indexes in " & _
            tblNew.Name & " Table"

        ' Enumerate Indexes collection.
        For Each idxLoop In .Indexes
            With idxLoop
                Debug.Print "Index " & .Name
                Debug.Print "   Primary key = " & .PrimaryKey
                Debug.Print "   Unique = " & .Unique

                ' Enumerate Columns collection of each Index
                ' object.
                Debug.Print "    Columns"
                For Each colLoop In .Columns
                    Debug.Print "       " & colLoop.Name
                Next colLoop
            End With
        Next idxLoop

    End With

    ' Delete new table as this is a demonstration.
    catNorthwind.Tables.Delete tblNew.Name

    'Clean up
    Set catNorthwind.ActiveConnection = Nothing
    Set catNorthwind = Nothing
    Set tblNew = Nothing
    Set idxNew = Nothing
    Set idxLoop = Nothing
    Set colLoop = Nothing
    Exit Sub

PrimaryKeyXError:

    Set catNorthwind = Nothing
    Set tblNew = Nothing
    Set idxNew = Nothing
    Set idxLoop = Nothing
    Set colLoop = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndPrimaryKeyVB

请参阅

Index 对象 | PrimaryKey 属性 | Unique 属性


Procedures 的 Append 方法范例 (VB)

下面的代码演示如何使用 Command 对象和 Procedures 集合的 Append 方法在基本数据源中创建新过程。

' BeginCreateProcedureVB
Sub Main()
    On Error GoTo CreateProcedureError

    Dim cnn As New ADODB.Connection
    Dim cmd As New ADODB.Command
    Dim prm As ADODB.Parameter
    Dim cat As New ADOX.Catalog

    ' Open the Connection
    cnn.Open _
        "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\Microsoft Office\" & _
        "Office\Samples\Northwind.mdb';"

    ' Create the parameterized command (Microsoft Jet specific)
    Set cmd.ActiveConnection = cnn
    cmd.CommandText = "PARAMETERS [CustId] Text;" & _
    "Select * From Customers Where CustomerId = [CustId]"

    ' Open the Catalog
    Set cat.ActiveConnection = cnn

    ' Create the new Procedure
    cat.Procedures.Append "CustomerById", cmd

    'Clean
    cnn.Close
    Set cat = Nothing
    Set cmd = Nothing
    Set cnn = Nothing
    Exit Sub

CreateProcedureError:
    Set cat = Nothing
    Set cmd = Nothing

    If Not cnn Is Nothing Then
        If cnn.State = adStateOpen Then cnn.Close
    End If
    Set cnn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndCreateProcedureVB

请参阅

ActiveConnection 属性 | Append 方法 (Procedures) | Catalog 对象 | Procedure 对象 | Procedures 集合


Procedures 的 Delete 方法范例 (VB)

下面的代码演示如何使用 Procedures 集合的 Delete 方法删除过程。

' BeginDeleteProcedureVB
Sub Main()
    On Error GoTo DeleteProcedureError

    Dim cat As New ADOX.Catalog

    ' Open the Catalog.
    cat.ActiveConnection = _
        "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\Microsoft Office\" & _
        "Office\Samples\Northwind.mdb';"

    ' Delete the Procedure.
    cat.Procedures.Delete "CustomerById"

    'Clean up
    Set cat.ActiveConnection = Nothing
    Set cat = Nothing
    Exit Sub

DeleteProcedureError:
    Set cat = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndDeleteProcedureVB

请参阅

ActiveConnection 属性 | Catalog 对象 | Delete 方法 (Collections) | Procedure 对象 | Procedures 集合


Procedures 的 Refresh 方法范例 (VB)

下面的代码显示如何刷新 Catalog 的 Procedures 集合。在访问 Catalog 的 Procedure 对象之前需要执行此操作。

' BeginProceduresRefreshVB
Sub Main()
    On Error GoTo ProcedureRefreshError

    Dim cat As New ADOX.Catalog

    ' Open the Catalog
    cat.ActiveConnection = _
        "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\" & _
        "Microsoft Office\Office\Samples\Northwind.mdb';"

    ' Refresh the Procedures collection
    cat.Procedures.Refresh

    'Clean up
    Set cat.ActiveConnection = Nothing
    Set cat = Nothing
    Exit Sub

ProcedureRefreshError:
    Set cat = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndProceduresRefreshVB

请参阅

Catalog 对象 | Procedures 集合 | Refresh 方法


SortOrder 属性范例 (VB)

本范例演示已追加到 Index 的 Columns 集合中的 Column 的 SortOrder 属性。此代码将升序索引追加到 Employees 表的 Country 列中，并显示这些记录。然后代码将降序索引追加到 Employees 表的 Country 列中，并再次显示这些记录。这样就可以看出升序索引和降序索引的差别。

' BeginSortOrderVB
Sub Main()
    On Error GoTo SortOrderXError

    Dim cnn As New ADODB.Connection
    Dim catNorthwind As New ADOX.Catalog
    Dim idxAscending As New ADOX.Index
    Dim idxDescending As New ADOX.Index
    Dim rstEmployees As New ADODB.Recordset

    ' Connect the catalog.
    cnn.Open "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\" & _
        "Microsoft Office\Office\Samples\Northwind.mdb';"
    Set catNorthwind.ActiveConnection = cnn

    ' Append Country column to new index
    idxAscending.Columns.Append "Country"
    idxAscending.Columns("Country").SortOrder = adSortAscending
    idxAscending.Name = "Ascending"
    idxAscending.IndexNulls = adIndexNullsAllow

    'Append new index to Employees table
    catNorthwind.Tables("Employees").Indexes.Append idxAscending

    rstEmployees.Index = idxAscending.Name
    rstEmployees.Open "Employees", cnn, adOpenKeyset, _
        adLockOptimistic, adCmdTableDirect

    With rstEmployees
        .MoveFirst
        Debug.Print "Index = " & .Index
        Debug.Print "  Country - Name"

        ' Enumerate the Recordset. The value of the
        ' IndexNulls property will determine if the newly
        ' added record appears in the output.
        Do While Not .EOF
            Debug.Print "    " & !Country & " - " & _
                !FirstName & " " & !LastName
            .MoveNext
        Loop

        .Close
    End With

    ' Append Country column to new index
    idxDescending.Columns.Append "Country"
    idxDescending.Columns("Country").SortOrder = adSortDescending
    idxDescending.Name = "Descending"
    idxDescending.IndexNulls = adIndexNullsAllow

    'Append descending index to Employees table
    catNorthwind.Tables("Employees").Indexes.Append idxDescending

    rstEmployees.Index = idxDescending.Name
    rstEmployees.Open "Employees", cnn, adOpenKeyset, _
        adLockOptimistic, adCmdTableDirect

    With rstEmployees
        .MoveFirst
        Debug.Print "Index = " & .Index
        Debug.Print "  Country - Name"

        ' Enumerate the Recordset. The value of the
        ' IndexNulls property will determine if the newly
        ' added record appears in the output.
        Do While Not .EOF
            Debug.Print "    " & !Country & " - " & _
                !FirstName & " " & !LastName
            .MoveNext
        Loop

        .Close
    End With

    ' Delete new Indexes because this is a demonstration.
    catNorthwind.Tables("Employees").Indexes.Delete idxAscending.Name
    catNorthwind.Tables("Employees").Indexes.Delete idxDescending.Name

    'Clean up
    cnn.Close
    Set catNorthwind = Nothing
    Set idxAscending = Nothing
    Set idxDescending = Nothing
    Set rstEmployees = Nothing
    Set cnn = Nothing
    Exit Sub

SortOrderXError:

    Set catNorthwind = Nothing
    Set idxAscending = Nothing
    Set idxDescending = Nothing

    If Not rstEmployees Is Nothing Then
        If rstEmployees.State = adStateOpen Then rstEmployees.Close
    End If
    Set rstEmployees = Nothing

    If Not cnn Is Nothing Then
        If cnn.State = adStateOpen Then cnn.Close
    End If
    Set cnn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndSortOrderVB

请参阅

Column 对象 | Columns 集合 | Index 对象 | SortOrder 属性


Views 和 Fields 集合范例 (VB)

下面的代码演示如何使用 Command 属性和 Recordset 对象检索视图的字段信息。

' BeginViewFieldsVB
Sub ViewFields()
    On Error GoTo ViewFieldsError

    Dim cnn As New ADODB.Connection
    Dim rst As New ADODB.Recordset
    Dim fld As ADODB.Field
    Dim cat As New ADOX.Catalog

    ' Open the Connection
    cnn.Open _
        "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\Microsoft Office\" & _
        "Office\Samples\Northwind.mdb';"

    ' Open the catalog
    Set cat.ActiveConnection = cnn

    ' Set the Source for the Recordset
    Set rst.Source = cat.Views("AllCustomers").Command

    ' Retrieve Field information
    rst.Fields.Refresh
    For Each fld In rst.Fields
        Debug.Print fld.Name & ":" & fld.Type
    Next

    'Clean up
    cnn.Close
    Set cat = Nothing
    Set rst = Nothing
    Set cnn = Nothing
    Exit Sub

ViewFieldsError:

    If Not cnn Is Nothing Then
        If cnn.State = adStateOpen Then cnn.Close
    End If

    Set cat = Nothing
    Set rst = Nothing
    Set cnn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If

End Sub
' EndViewFieldsVB

请参阅

ActiveConnection 属性 | Catalog 对象 | Command 属性 | View 对象 | Views 集合


Views 的 Append 方法范例 (VB)

下面的代码演示如何使用 Command 对象和 Views 集合的 Append 方法在基本数据源中创建新的视图。

' BeginCreateViewVB
Sub Main()
    On Error GoTo CreateViewError

    Dim cmd As New ADODB.Command
    Dim cat As New ADOX.Catalog

    ' Open the Catalog
    cat.ActiveConnection = _
        "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\Microsoft Office\" & _
        "Office\Samples\Northwind.mdb';"

    ' Create the command representing the view.
    cmd.CommandText = "Select * From Customers"

    ' Create the new View
    cat.Views.Append "AllCustomers", cmd

    'Clean up
    Set cat.ActiveConnection = Nothing
    Set cat = Nothing
    Set cmd = Nothing
    Exit Sub

CreateViewError:

    Set cat = Nothing
    Set cmd = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndCreateViewVB

请参阅

ActiveConnection 属性 | Append 方法 (Views) | Catalog 对象 | View 对象 | Views 集合


Views 集合，CommandText 属性范例 (VB)

下面的代码演示如何使用 Command 属性更新视图的文本。

' BeginViewsCollectionVB
Sub Main()
    On Error GoTo ViewTextError

    Dim cnn As New ADODB.Connection
    Dim cat As New ADOX.Catalog
    Dim cmd As New ADODB.Command

    ' Open the Connection
    cnn.Open _
        "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\Microsoft Office\" & _
        "Office\Samples\Northwind.mdb';"

    ' Open the catalog
    Set cat.ActiveConnection = cnn

    ' Get the command
    Set cmd = cat.Views("AllCustomers").Command

    ' Update the CommandText of the Command
    cmd.CommandText = _
    "Select CustomerId, CompanyName, ContactName From Customers"

    ' Update the View
    Set cat.Views("AllCustomers").Command = cmd

    'Clean up
    cnn.Close
    Set cat = Nothing
    Set cmd = Nothing
    Set cnn = Nothing
    Exit Sub

ViewTextError:

    Set cat = Nothing
    Set cmd = Nothing

    If Not cnn Is Nothing Then
        If cnn.State = adStateOpen Then cnn.Close
    End If
    Set cnn = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndViewsCollectionVB

请参阅

ActiveConnection 属性 | Catalog 对象 | Command 属性 | View 对象 | Views 集合


Views 的 Delete 方法范例 (VB)

下面的代码显示如何使用 Delete 方法从目录中删除视图。

' BeginDeleteViewVB
Sub Main()
    On Error GoTo DeleteViewError

    Dim cat As New ADOX.Catalog

    ' Open the catalog
    cat.ActiveConnection = "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\Microsoft Office\" & _
        "Office\Samples\Northwind.mdb';"

    'Delete the View
    cat.Views.Delete "AllCustomers"

    'Clean up
    Set cat.ActiveConnection = Nothing
    Set cat = Nothing
    Exit Sub

DeleteViewError:
    Set cat = Nothing

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndDeleteViewVB

请参阅

Delete 方法 (Collections) | Views 集合


Views 的 Refresh 方法范例 (VB)

下面的代码显示如何刷新 Catalog 的 Views 集合。在 Catalog 的 View 对象可被访问之前需要执行此操作。

' BeginViewsRefreshVB
Sub Main()
    On Error GoTo ProcedureViewsRefreshError

    Dim cat As New ADOX.Catalog

    ' Open the Catalog
    cat.ActiveConnection = "Provider='Microsoft.Jet.OLEDB.4.0';" & _
        "Data Source='c:\Program Files\" & _
        "Microsoft Office\Office\Samples\Northwind.mdb';"

    ' Refresh the Procedures collection
    cat.Views.Refresh

    'Clean up
    Set cat = Nothing
    Exit Sub

ProcedureViewsRefreshError:

    If Not cat Is Nothing Then
        Set cat = Nothing
    End If

    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
    End If
End Sub
' EndViewsRefreshVB

请参阅

Refresh 方法 | Views 集合


Microsoft Visual C++ 中的 ADOX 代码范例

这些主题提供了帮助用户了解如何使用 ADOX 的范例代码。所有的代码范例都使用 Microsoft Visual C++ 编写的。

注意 请将整个代码范例（从开始到结束）粘贴到代码编辑器中。如果使用部分范例或丢失段落格式，那么范例可能无法正确运行。

方法

  • Columns 和 Tables 的 Append 方法，Name 属性范例 (VC++)
  • Connection 的 Close 方法，Table 的 Type 属性范例 (VC++)
  • Create 方法范例 (VC++)
  • GetObjectOwner 和 SetObjectOwner 方法范例 (VC++)
  • GetPermissions 和 SetPermissions 方法范例 (VC++)
  • Groups 和 Users 的 Append、ChangePassword 方法范例 (VC++)
  • Indexes 的 Append 方法范例 (VC++)
  • Keys 的 Append 方法，Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VC++)

Properties

  • Attributes 属性范例 (VC++)
  • Catalog 的 ActiveConnection 属性范例 (VC++)
  • Clustered 属性范例 (VC++)
  • Command 和 CommandText 属性范例 (VC++)
  • Command 属性，Parameters 集合范例 (VB)
  • DateCreated 和 DateModified 属性范例 (VC++)
  • DefinedSize 属性范例 (VC++)
  • DeleteRule 属性范例 (VC++)
  • IndexNulls 属性范例 (VC++)
  • Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性，Keys 的 Append 方法范例 (VC++)
  • Name 属性、Columns 和 Tables 的 Append 方法范例 (VC++)
  • NumericScale 和 Precision 属性范例 (VC++)
  • ParentCatalog 属性范例 (VC++)
  • PrimaryKey 和 Unique 属性范例 (VC++)
  • Table 的 Type 属性，Connection 的 Close 方法范例 (VC++)

集合

  • Parameters 集合，Command 属性范例 (VC++)


Attributes 属性范例 (VC++)

本范例演示了 Column 的 Attributes 属性。把它设置为 adColNullable 可允许用户将 Recordset Field 的值设置为空字符串。在这种情况下，用户可以区别出有未知数据的记录和有不适用数据的记录。

// BeginAttributesCpp
#import "c:\Program Files\Common Files\system\ado\msado15.dll"
#import "c:\Program Files\Common Files\system\ado\msadox.dll" \
    no_namespace

#include "iostream.h"
#include "stdio.h"
#include "conio.h"
#include "ADOXAttributesX.h"

//Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void AttributesX(void);
inline char* mygets(char* strDest, int n)
{
    char strExBuff[10];
    char* pstrRet = fgets(strDest, n, stdin);

    if (pstrRet == NULL)
        return NULL;

    if (!strrchr(strDest, '\n'))
        // Exhaust the input buffer.
        do
        {
            fgets(strExBuff, sizeof(strExBuff), stdin);
        }while (!strrchr(strExBuff, '\n'));
    else
        // Replace '\n' with '\0'
        strDest[strrchr(strDest, '\n') - strDest] = '\0';

    return pstrRet;
}

//////////////////////////////////////////////////////////
//                                                      //
//         Main Function                                //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    AttributesX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//        AttributesX Function                          //
//                                                      //
//////////////////////////////////////////////////////////
void AttributesX(void)
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.
    _CatalogPtr m_pCatalog  = NULL;
    _ColumnPtr m_pColumn  = NULL;
    _TablePtr m_pTable  = NULL;

    // Define ADODB object pointers
    ADODB::_ConnectionPtr m_pCnn         = NULL;
    ADODB::_RecordsetPtr m_pRstEmployees  = NULL;

    IADORecordBinding *picRs  = NULL;   // Interface Pointer Declared
    CEmployeeRs emprs;            // C++ Class Object

    // Define string variables.
    _bstr_t strcnn("Provider='Microsoft.JET.OLEDB.4.0';"
        "Data Source= 'c:\\Program Files\\Microsoft Office\\"
        "Office\\Samples\\Northwind.mdb';");

    try
    {
        // Connect the catalog.
        TESTHR(hr = m_pCnn.CreateInstance(__uuidof (ADODB::Connection)));
        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof (Catalog)));
        TESTHR(hr = m_pColumn.CreateInstance(__uuidof(Column)));
        TESTHR(hr = m_pRstEmployees.CreateInstance(__uuidof(ADODB::Recordset)));

        m_pCnn->Open(strcnn,"","",NULL);
        m_pCatalog->PutActiveConnection(
            _variant_t((IDispatch *) m_pCnn));
        m_pTable= m_pCatalog->Tables->GetItem("Employees");

        // Create a new Field object and append it to the Fields
        // collection of the Employees table.
        m_pColumn->Name = "FaxPhone";
        m_pColumn->Type = adVarWChar;
        m_pColumn->DefinedSize = 24;
        m_pColumn->Attributes = adColNullable;

        m_pCatalog->Tables->GetItem("Employees")->Columns->
            Append(m_pColumn->Name, adVarWChar, 24);
            //Append("FaxPhone",adVarWChar,24);

        // Open the Employees table for updating as a Recordset.
        m_pRstEmployees->Open("Employees",
            _variant_t((IDispatch *) m_pCnn),
            ADODB::adOpenKeyset,ADODB::adLockOptimistic,
            ADODB::adCmdTable);

        // Get user input.
        printf("Enter fax number for : %s %s\n",(LPSTR) (_bstr_t)
            m_pRstEmployees->Fields->GetItem("LastName")->Value,
           (LPSTR) (_bstr_t) m_pRstEmployees->Fields->
            GetItem("FirstName")->Value);
        printf("[? - unknown, X - has no fax] : \n");
        char strInput[10];
        mygets(strInput, 10);
        char* strTemp = strtok(strInput," \t");
        _variant_t vNull;
        vNull.vt = VT_BSTR;
        vNull.bstrVal = NULL;
        if(strTemp!=NULL)
        {
            if(strcmp(strTemp,"?") == 0)
            {
                m_pRstEmployees->Fields->GetItem("FaxPhone")->
                    PutValue(vNull);
            }
            else if( (strcmp(strTemp,"X") == 0) | (strcmp(strTemp,"x") == 0) )
            {
                m_pRstEmployees->Fields->GetItem("FaxPhone")->
                    PutValue("");
            }
            else
            {
                m_pRstEmployees->Fields->GetItem("FaxPhone")->
                    PutValue(strTemp);
            }
            m_pRstEmployees->Update();

            // Open an IADORecordBinding interface pointer which
            // we will use for binding Recordset to a class
            TESTHR(hr = m_pRstEmployees->QueryInterface(
                __uuidof(IADORecordBinding),(LPVOID*)&picRs));

            // Bind the Recordset to a C++ class here
            TESTHR(hr = picRs->BindToRecordset(&emprs));

            // Print report.
            printf("\nName - Fax number\n");
            printf("%s %s ",emprs.lemp_LastNameStatus == adFldOK ?
                emprs.m_szemp_LastName : "<NULL>",
                emprs.lemp_FirstNameStatus == adFldOK ?
                emprs.m_szemp_FirstName : "<NULL>");

            if (emprs.lemp_FaxphoneStatus == adFldNull)
                printf("- [Unknown]\n");
            else if (strcmp((LPSTR)emprs.m_szemp_Faxphone,"") == 0)
                printf("- [Has no fax]\n");
            else
                printf("- %s\n",emprs.m_szemp_Faxphone);

        }

        // Delete new field because this is a demonstration.
        //m_pTable->Columns->Delete(m_pColumn->Name);
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
            (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }
    catch(...)
    {
        cout << "Error occured in AttributesX...."<< endl;
    }

    if (m_pRstEmployees)
        if (m_pRstEmployees->State == 1)
            m_pRstEmployees->Close();

    // Delete new field because this is a demonstration.
    if (m_pTable != NULL)
        m_pTable->Columns->Delete(m_pColumn->Name);

    if (m_pCnn)
        if (m_pCnn->State == 1)
            m_pCnn->Close();

    // Release the IADORecordset Interface here
    if(picRs)
        picRs->Release();

}
// EndAttributesCpp

ADOXAttributesX.h

// BeginAttributesH
#include "icrsint.h"

//This class extracts LastName, FirstName, FaxPhone from Employees table

class CEmployeeRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CEmployeeRs)

        // Column LastName is the 2nd field in the table
        ADO_VARIABLE_LENGTH_ENTRY2(2,adVarChar,m_szemp_LastName,
            sizeof(m_szemp_LastName),lemp_LastNameStatus,TRUE)

        // Column FirstName is the 17th field in the table
        ADO_VARIABLE_LENGTH_ENTRY2(17,adVarChar,m_szemp_FirstName,
            sizeof(m_szemp_FirstName),lemp_FirstNameStatus,TRUE)

        // Column FaxPhone is the 18th field in the table
        ADO_VARIABLE_LENGTH_ENTRY2(18,adVarChar,m_szemp_Faxphone,
            sizeof(m_szemp_Faxphone),lemp_FaxphoneStatus,TRUE)

END_ADO_BINDING()

public:
    CHAR  m_szemp_LastName[21];
    ULONG lemp_LastNameStatus;
    CHAR  m_szemp_FirstName[11];
    ULONG lemp_FirstNameStatus;
    CHAR  m_szemp_Faxphone[25];
    ULONG lemp_FaxphoneStatus;
};
// EndAttributesH

请参阅

Attributes 属性 | Column 对象


Catalog 的 ActiveConnection 属性范例 (VC++)

将 ActiveConnection 属性设置为有效值，打开连接就可以“打开”目录。通过打开的目录可以访问包含在其中的模式对象。

// BeginActiveConnectionCpp
#import "c:\Program Files\Common Files\system\ado\msado15.dll"
#import "c:\Program Files\Common Files\system\ado\msadox.dll" \
    no_namespace

#include "iostream.h"
#include "stdio.h"
#include "conio.h"

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void OpenConnectionX(void);
void OpenConnectionWithStringX(void);

//////////////////////////////////////////////////////////
//                                                      //
//         Main Function                                //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    OpenConnectionX();

    OpenConnectionWithStringX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//     OpenConnectionX Function                         //
//                                                      //
//////////////////////////////////////////////////////////
void OpenConnectionX(void)
{
   HRESULT   hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.
    _CatalogPtr m_pCatalog = NULL;

    //Define ADODB object pointers
    ADODB::_ConnectionPtr m_pCnn   = NULL;

    // Define string variables.
    _bstr_t strcnn("Provider='Microsoft.JET.OLEDB.4.0';"
        "Data source = 'c:\\Program Files\\Microsoft Office\\"
        "Office\\Samples\\Northwind.mdb';");

    try
    {
        TESTHR(hr = m_pCnn.CreateInstance(__uuidof(ADODB::Connection)));
        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof (Catalog)));
        m_pCnn->Open(strcnn,"","",NULL);
        m_pCatalog->PutActiveConnection(_variant_t((IDispatch *) m_pCnn));
        _variant_t vIndex = (short) 0;
        cout<<m_pCatalog->Tables->GetItem(vIndex)->Type<<endl;
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
            (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }
    catch(...)
    {
        cout << "Error occured in OpenConnectionX...."<< endl;
    }

    if (m_pCnn)
        if (m_pCnn->State == 1)
            m_pCnn->Close();
}

//////////////////////////////////////////////////////////
//                                                      //
//         OpenConnectionWithStringX Function           //
//                                                      //
//////////////////////////////////////////////////////////
void OpenConnectionWithStringX(void)
{
    HRESULT   hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.
    _CatalogPtr m_pCatalog = NULL;

    // Define string variables.
    _bstr_t strcnn("Provider='Microsoft.JET.OLEDB.4.0';"
                "Data source = 'c:\\Program Files\\Microsoft Office\\"
                "Office\\Samples\\Northwind.mdb';");

    try
    {
        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof (Catalog)));
        m_pCatalog->PutActiveConnection(strcnn);
        _variant_t vIndex = (short) 0;
        cout<<m_pCatalog->Tables->GetItem(vIndex)->Type<<endl;
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
           (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }
    catch(...)
    {
        cout << "Error occured in OpenConnectionWithStringX...."<< endl;
    }
}
// EndActiveConnectionCpp

请参阅

ActiveConnection 属性


Clustered 属性范例 (VC++)

本范例演示了 Index 的 Clustered 属性。注意，Microsoft Jet 数据库不支持分簇索引，因此本范例将对 Northwind 数据库中所有索引的 Clustered 属性返回 False。

// BeginClusteredCpp
#import "c:\Program Files\Common Files\system\ado\msadox.dll" \
    no_namespace

#include "iostream.h"
#include "stdio.h"
#include "conio.h"

//Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void ClusteredX(void);

//////////////////////////////////////////////////////////
//                                                      //
//     Main Function                                    //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    ClusteredX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//       ClusteredX Function                            //
//                                                      //
//////////////////////////////////////////////////////////
void ClusteredX()
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.
    _CatalogPtr m_pCatalog = NULL;
    _TablePtr m_pTable = NULL;
    _IndexPtr m_pIndex = NULL;

    //Define other variables here
    _variant_t vIndex;
    try
    {
        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof(Catalog)));

        // Connect to the catalog.
        m_pCatalog->PutActiveConnection(
            "Provider='Microsoft.JET.OLEDB.4.0';data source="
            "'c:\\Program Files\\Microsoft Office\\Office\\Samples"
            "\\Northwind.mdb';");

        int iLineCnt = 1;
        //Enumerate Tables.
        for(short iTable = 0;iTable < m_pCatalog->Tables->Count;iTable++)
        {
            vIndex = iTable;
            m_pTable = m_pCatalog->Tables->GetItem(vIndex);

            //Enumerate Indexes.
            for(short iIndex = 0;iIndex < m_pTable->Indexes->Count;
                iIndex++)
            {
                vIndex = iIndex;
                m_pIndex = m_pTable->Indexes->GetItem(vIndex);
                cout << m_pTable->Name << "   " ;
                cout << m_pIndex->Name << "   " << (m_pIndex->
                    GetClustered() ? "True" : "False") << endl;

                 if (iLineCnt%15 == 0)
                {
                    printf("\nPress any key to continue...\n");
                    getch();
                }
                iLineCnt++;
            }
        }
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
            (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }
    catch(...)
    {
        cout << "Error occured in ClusteredX...."<< endl;
    }
}
// EndClusteredCpp

请参阅

Clustered 属性 | Index 对象


Columns 和 Tables 的 Append 方法，Name 属性范例 (VC++)

下面的代码演示如何创建新的表。

// BeginCreateTableCpp
#import "c:\Program Files\Common Files\system\ado\msadox.dll" \
    no_namespace

#include "iostream.h"
#include "stdio.h"
#include "conio.h"

//Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void CreateTableX(void);

//////////////////////////////////////////////////////////
//                                                      //
//       Main Function                                  //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    CreateTableX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//       CreateTableX Function                          //
//                                                      //
//////////////////////////////////////////////////////////
void CreateTableX()
{
        HRESULT hr = S_OK;

        // Define ADOX object pointers.
        // Initialize pointers on define.
        // These are in the ADOX::  namespace.
        _CatalogPtr m_pCatalog = NULL;
        _TablePtr m_pTable = NULL;

        try
        {
            TESTHR(hr = m_pCatalog.CreateInstance(__uuidof(Catalog)));

            //Open the catalog
            m_pCatalog->PutActiveConnection(
                "Provider='Microsoft.JET.OLEDB.4.0';" \
                "data source='c:\\Program Files\\Microsoft Office"
                "\\Office\\Samples\\Northwind.mdb';");

            TESTHR(hr = m_pTable.CreateInstance(__uuidof(Table)));
            m_pTable->PutName("MyTable");
            m_pTable->Columns->Append("Column1",adInteger,0);
            m_pTable->Columns->Append("Column2",adInteger,0);
            m_pTable->Columns->Append("Column3",adVarWChar,50);
            m_pCatalog->Tables->Append(
                _variant_t((IDispatch *)m_pTable));
            printf("Table 'MyTable' is added.\n");

            // Delete the table as this is a demonstration.
            m_pCatalog->Tables->Delete("MyTable");
            printf("Table 'MyTable' is deleted.\n");
        }

    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
            (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }

    catch(...)
    {
        cout << "Error occured in include files...."<< endl;
    }
}
// EndCreateTableCpp

请参阅

Append 方法 (Columns) | Append 方法 (Tables) | Name 属性


Command 和 CommandText 属性范例 (VC++)

下面的代码演示如何使用 Command 属性更新过程文本。

// BeginCommandTextCpp
// This sample runs correctly only if procedure 'CustomerById'
// exists. If the procedure doesn't exist, please use
// 'ADOXProceduresAppend.cpp' to creat it.

#import "c:\Program Files\Common Files\system\ado\msadox.dll" \
    no_namespace
#import "c:\Program Files\Common Files\system\ado\msado15.dll"

#include "iostream.h"
#include "stdio.h"
#include "conio.h"

//Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void ProcedureTextX(void);

//////////////////////////////////////////////////////////
//                                                      //
//      Main Function                                   //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    ProcedureTextX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//       ProcedureTextX Function                        //
//                                                      //
//////////////////////////////////////////////////////////
void ProcedureTextX()
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.
    _CatalogPtr m_pCatalog = NULL;

    // Define ADODB object pointers.
    ADODB::_ConnectionPtr m_pCnn = NULL;
    ADODB::_CommandPtr m_pCommand = NULL;

    try
    {
        //Open the Connection
        TESTHR(hr = m_pCnn.CreateInstance(__uuidof(ADODB::Connection)));
        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof(Catalog)));
        TESTHR(hr = m_pCommand.CreateInstance(__uuidof(ADODB::Command)));
        m_pCnn->Open("Provider='Microsoft.JET.OLEDB.4.0';"
            "data source='c:\\Program Files\\Microsoft Office"
            "\\Office\\Samples\\Northwind.mdb';","","",NULL);

        // Open the catalog
        m_pCatalog->PutActiveConnection(_variant_t((IDispatch *)m_pCnn));

        // Get the Command
        m_pCommand = m_pCatalog->Procedures->GetItem("CustomerById")->GetCommand();

        // Update the CommandText
        m_pCommand->PutCommandText("PARAMETERS [CustId] Text;select "
            "CustomerId, CompanyName, ContactName "
            "from Customers where CustomerId = [CustId]");
        printf("CommandText is updated.\n");

        // Update the Procedure
        m_pCatalog->Procedures->GetItem("CustomerById")->PutCommand(
            _variant_t((IDispatch *)m_pCommand));
        printf("Procedure 'CustomerById' is updated.\n");
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",(LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }
    catch(...)
    {
        cout << "Error occured in ProcedureTextX...."<< endl;
    }
}
// EndCommandTextCpp

请参阅

Command 属性


Connection 的 Close 方法，Table 的 Type 属性范例 (VC++)

将 ActiveConnection 属性设置为 Nothing 可“关闭”目录。关联的集合将被清空。目录中任何通过模式对象创建的对象都将被孤立。这些已缓存对象中的任何属性仍然可用，但试图读取需要调用提供者的属性时，操作将失败。

// BeginCloseConnectionCpp
#import "c:\Program Files\Common Files\system\ado\msadox.dll" \
    no_namespace
#import "c:\Program Files\Common Files\system\ado\msado15.dll"

#include "iostream.h"
#include "stdio.h"
#include "conio.h"

//Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void CloseConnectionByNothingX(void);
void CloseConnectionX(void);

//////////////////////////////////////////////////////////
//                                                      //
//     Main Function                                    //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    CloseConnectionByNothingX();
    CloseConnectionX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//        CloseConnectionByNothingX Function            //
//                                                      //
//////////////////////////////////////////////////////////
void CloseConnectionByNothingX(void)
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.

    _CatalogPtr m_pCatalog = NULL;
    _TablePtr m_pTable = NULL;

    //Define ADODB object pointers
    ADODB::_ConnectionPtr m_pCnn = NULL;

    //Define other variables
    _variant_t vIndex = (short) 0;

    try
    {
        TESTHR(hr = m_pCnn.CreateInstance(__uuidof(ADODB::Connection)));

        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof(Catalog)));

        m_pCnn->Open("Provider='Microsoft.JET.OLEDB.4.0';"
            "Data Source= 'c:\\Program Files\\Microsoft Office\\"
            "Office\\Samples\\Northwind.mdb';","","",NULL);

        m_pCatalog->PutActiveConnection(_variant_t((IDispatch *)m_pCnn));

        m_pTable = m_pCatalog->Tables->GetItem(vIndex);

        // Cache m_pTable.Type info
        cout << m_pTable->Type << endl;

        _variant_t vCnn;
        vCnn.vt = VT_DISPATCH;
        vCnn.pdispVal = NULL;
        m_pCatalog->PutActiveConnection(vCnn);

        // m_pTable is orphaned
        cout << m_pTable->Type << endl;
        // Previous line will succeed if this was cached

        cout << m_pTable->Columns->GetItem(vIndex)->DefinedSize << endl;
        // Previous line will fail if this info has not been cached
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\nError\n\tSource :  %s \n\tdescription : %s \n",
            (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }
    catch(...)
    {
        cout << "Error occured in CloseConnectionByNothingX...."<< endl;
    }
}

//////////////////////////////////////////////////////////
//                                                      //
//     CloseConnectionX Function                        //
//                                                      //
//////////////////////////////////////////////////////////
void CloseConnectionX()
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.

    _CatalogPtr m_pCatalog = NULL;
    _TablePtr m_pTable = NULL;

    //Define ADODB object pointers
    ADODB::_ConnectionPtr m_pCnn = NULL;

    //Define other variables
    _variant_t vIndex = (short) 0;
    try
    {
        TESTHR(hr = m_pCnn.CreateInstance(__uuidof(ADODB::Connection)));
        m_pCnn->Open("Provider='Microsoft.JET.OLEDB.4.0';"
            "Data Source= 'c:\\Program Files\\Microsoft Office\\"
            "Office\\Samples\\Northwind.mdb';","","",NULL);

        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof(Catalog)));
        m_pCatalog->PutActiveConnection(_variant_t((IDispatch *)m_pCnn));

        m_pTable = m_pCatalog->Tables->GetItem(vIndex);

        // Cache m_pTable.Type info
        cout << m_pTable->Type << endl;

        m_pCnn->Close();

        // m_pTable is orphaned
        cout << m_pTable->Type << endl;
        // Previous line will succeed if this was cached

        cout << m_pTable->Columns->GetItem(vIndex)->DefinedSize << endl;
        // Previous line will fail if this info has not been cached
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\nError\n\tSource :  %s \n\tdescription : %s \n",
            (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }
    catch(...)
    {
        cout << "Error occured in CloseConnectionX...."<< endl;
    }
}
// EndCloseConnectionCpp

请参阅

ActiveConnection 属性


Create 方法范例 (VC++)

下面的代码显示如何用 Create 方法创建新的 Microsoft Jet 数据库。

// BeginCreateDatabaseCpp
#import "c:\Program Files\Common Files\system\ado\msadox.dll" no_namespace
#import "c:\Program Files\Common Files\system\ado\msado15.dll"

#define TESTHR(x) if FAILED(x) _com_issue_error(x);

#include "iostream.h"
#include "stdio.h"
#include "conio.h"

//Function declarations
void CreateDatabaseX(void);

//------------------------------------------------------------//
//Main Function
//Purpose:  Test Driver
//------------------------------------------------------------//
void main()
{
    HRESULT hr = S_OK;

    hr = ::CoInitialize(NULL);
    if(SUCCEEDED(hr))
    {
        CreateDatabaseX();

        //Wait here for the user to see the output
        printf("Press any key to continue...");
        getch();

        ::CoUninitialize();
    }
}

//------------------------------------------------------------//
//CreateDatabaseX
//Purpose:  create a new Jet database with the Create method
//------------------------------------------------------------//
void CreateDatabaseX()
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.

    _CatalogPtr m_pCatalog = NULL;

    //Set ActiveConnection of Catalog to this string
    _bstr_t strcnn("Provider='Microsoft.JET.OLEDB.4.0';"
                "Data source = c:\\new.mdb");
    try
    {
        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof (Catalog)));
        m_pCatalog->Create(strcnn);
        printf("Database 'c:\\new.mdb' is created.\n");
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
            (LPCSTR)bstrSource,(LPCSTR)bstrDescription);

    }
    catch(...)
    {
        cout << "Error occured in CreateDatabaseX...."<< endl;
    }

}
// EndCreateDatabaseCpp

请参阅

Create 方法


DateCreated 和 DateModified 属性范例 (VC++)

本范例通过向现有的 Table 中添加新的 Column 以及创建新的 Table 来演示 DateCreated 和 DateModified 属性。运行本范例需要 DateOutput 过程。

// BeginDateCreatedCpp
#import "c:\Program Files\Common Files\system\ado\msadox.dll" \
    no_namespace
#import "c:\Program Files\Common Files\system\ado\msado15.dll"

#include "iostream.h"
#include "stdio.h"
#include "conio.h"

//Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void DateCreatedX(void);
void DateOutPut(_bstr_t strTemp , _TablePtr tblTemp);

//////////////////////////////////////////////////////////
//                                                      //
//        Main Function                                 //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    DateCreatedX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//       DateCreatedX Function                          //
//                                                      //
//////////////////////////////////////////////////////////
void DateCreatedX()
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.
    _CatalogPtr m_pCatalog = NULL;
    _TablePtr m_pTblEmployees = NULL;
    _TablePtr m_pTblNew = NULL;

    //Set ActiveConnection of Catalog to this string
    _bstr_t strCnn("Provider='Microsoft.JET.OLEDB.4.0';"
        "Data Source= 'c:\\Program Files\\Microsoft Office\\"
        "Office\\Samples\\Northwind.mdb';");

    try
    {
        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof (Catalog)));

        // Connect the catalog.
        m_pCatalog->PutActiveConnection(strCnn);

        m_pTblEmployees = m_pCatalog->Tables->GetItem("Employees");

        // Print current information about the Employees table.
        DateOutPut((_bstr_t)"Current properties", m_pTblEmployees);

        // Create and append column to the Employees table.
        m_pTblEmployees->Columns->Append("NewColumn", adInteger,0);

        m_pCatalog->Tables->Refresh();

        // Print new information about the Employees table.
        DateOutPut((_bstr_t)"After creating a new column",
            m_pTblEmployees);

        // Delete new column because this is a demonstration.
        m_pTblEmployees->Columns->Delete("NewColumn");

        // Create and append new Table object to the Northwind database.
        TESTHR(hr = m_pTblNew.CreateInstance(__uuidof(Table)));

        m_pTblNew->Name = "NewTable";
        m_pTblNew->Columns->Append("NewColumn", adInteger,0);
        m_pCatalog->Tables->Append(_variant_t((IDispatch*)m_pTblNew));
        m_pCatalog->Tables->Refresh();

        //Print information about the new Table object.
        DateOutPut((_bstr_t)"After creating a new table", m_pCatalog->
            Tables->GetItem("NewTable"));

        // Delete new Table object because this is a demonstration.
        m_pCatalog->Tables->Delete(m_pTblNew->Name);
    }

    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
            (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }

    catch(...)
    {
        cout << "Error occured in include files...."<< endl;
    }
}

//////////////////////////////////////////////////////////
//                                                      //
//        DateOutPut Function                           //
//                                                      //
//////////////////////////////////////////////////////////
void DateOutPut(_bstr_t strTemp , _TablePtr tblTemp)
{
    // Print DateCreated and DateModified information about
    // specified Table object.
    cout << strTemp << endl;
    cout << "    Table: " << tblTemp->GetName() << endl;
    cout << "        DateCreated = " << (_bstr_t)tblTemp->
        GetDateCreated() << endl;
    cout << "        DateModified = " << (_bstr_t)tblTemp->
        GetDateModified() << endl;
}
// EndDateCreatedCpp

请参阅

Column 对象 | DateCreated 属性 | DateModified 属性 | Table 对象


DefinedSize 属性范例 (VC++)

本范例演示 Column 的 DefinedSize 属性。此代码将重新定义 Northwind 数据库 Employees 表的 FirstName 列的大小。然后，基于 Employees 表的 Recordset FirstName Field 的值的变化将显示出来。注意，在默认情况下，重新定义 DefinedSize 属性后，FirstName 字段用空格填充。

// BeginDefinedSizeCpp
#import "c:\Program Files\Common Files\system\ado\msadox.dll" \
    no_namespace
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
     rename("EOF", "EndOfFile")

#include "iostream.h"
#include "stdio.h"
#include "conio.h"

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void DefinedSizeX(void);

//////////////////////////////////////////////////////////
//                                                      //
//      Main Function                                   //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    DefinedSizeX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//      DefinedSizeX Function                           //
//                                                      //
//////////////////////////////////////////////////////////
void DefinedSizeX(void)
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.
    _CatalogPtr m_pCatNorthwind   = NULL;
    _ColumnPtr m_pColFirstName    = NULL;
    _ColumnPtr m_pColNewFirstName = NULL;

    // Define ADODB object pointers
    ADODB::_RecordsetPtr m_pRstEmployees  = NULL;

    // Define string variables.
    _bstr_t strCnn("Provider='Microsoft.JET.OLEDB.4.0';data source="
        "'c:\\Program Files\\Microsoft Office\\Office\\Samples\\"
        "Northwind.mdb';");
    _bstr_t aryFirstName[10];

    try
    {
        // Open a Recordset for the Employees table.
        TESTHR(hr = m_pRstEmployees.CreateInstance(
            __uuidof(ADODB::Recordset)));
        TESTHR(hr = m_pCatNorthwind.CreateInstance(__uuidof (Catalog)));
        TESTHR(hr = m_pColNewFirstName.CreateInstance(__uuidof(Column)));

        m_pRstEmployees->Open("Employees",strCnn,ADODB::adOpenKeyset,
            ADODB::adLockReadOnly,ADODB::adCmdTable);

        long lngSize = m_pRstEmployees->RecordCount;
        aryFirstName[lngSize];

        // Open a catalog for the Northwind database,
        // using same connection as rstEmployees.
        m_pCatNorthwind->PutActiveConnection(m_pRstEmployees->
            GetActiveConnection());

        // Loop through the recordset displaying the contents,
        // of the FirstName field, the field's defined size,
        // and its actual size.
        // Also store FirstName values in aryFirstName array.
        m_pRstEmployees->MoveFirst();
        printf("\nOriginal Defined Size and Actual Size");
        int iCount=0;
        while (!(m_pRstEmployees->EndOfFile))
        {
            printf("\nEmployee Name:");
            printf("%s ",(LPSTR)(_bstr_t)m_pRstEmployees->Fields->
                GetItem("FirstName")->Value);
            printf("%s\n",(LPSTR)(_bstr_t)m_pRstEmployees->Fields->
                GetItem("LastName")->Value);
            printf("  FirstName Defined size: %d\n",m_pRstEmployees->
                Fields->GetItem("FirstName")->DefinedSize) ;
            printf("  FirstName Actual size: %d\n",m_pRstEmployees->
                Fields->GetItem("FirstName")->ActualSize);
            aryFirstName[iCount] = (_bstr_t) m_pRstEmployees->Fields->
                GetItem("FirstName")->Value;
            m_pRstEmployees->MoveNext();
            iCount++;
            if(iCount%5==0)
            {
                printf("Press any key to continue...");
                getch();
                system("cls");
            }
        }
        m_pRstEmployees->Close();

        // Redefine the DefinedSize of FirstName in the catalog.
        m_pColFirstName = m_pCatNorthwind->Tables->GetItem("Employees")->
            Columns->GetItem("FirstName");
        m_pColNewFirstName->Name = m_pColFirstName->Name;
        m_pColNewFirstName->Type = m_pColFirstName->Type;
        m_pColNewFirstName->DefinedSize =
            (m_pColFirstName->DefinedSize) + 1;

        // Append new FirstName column to catalog.
        m_pCatNorthwind->Tables->GetItem("Employees")->Columns->
            Delete(m_pColFirstName->Name);
        m_pCatNorthwind->Tables->GetItem("Employees")->Columns->
            Append(_variant_t((IDispatch*)m_pColNewFirstName,true),
            adVarWChar,m_pColNewFirstName->DefinedSize);

        // Open Employee table in Recordset for updating.
        m_pRstEmployees->Open("Employees",m_pCatNorthwind->
            GetActiveConnection(),ADODB::adOpenKeyset,
            ADODB::adLockOptimistic,ADODB::adCmdTable);

        // Loop through the recordset displaying the contents
        // of the FirstName field,the field's defined size,
        // and its actual size.
        // Also restore FirstName values from aryFirstName.
        printf("Press any key to continue...");
        getch();
        system("cls");
        m_pRstEmployees->MoveFirst();
        printf("\n\nNew Defined Size and Actual Size");
        iCount=0;
        while (!(m_pRstEmployees->EndOfFile))
        {
            m_pRstEmployees->Fields->GetItem("FirstName")->Value =
                aryFirstName[iCount];
            printf("\nEmployee Name: ");
            printf("%s ",(LPSTR) (_bstr_t)m_pRstEmployees->Fields->
                GetItem("FirstName")->Value);
            printf("%s\n",(LPSTR)(_bstr_t)m_pRstEmployees->Fields->
                GetItem("LastName")->Value);
            printf("  FirstName Defined size: %d\n",m_pRstEmployees->
                Fields->GetItem("FirstName")->DefinedSize );
            printf("  FirstName Actual size: %d\n",m_pRstEmployees->
                Fields->GetItem("FirstName")->ActualSize );
            m_pRstEmployees->MoveNext();
            iCount++;
            if(iCount%5==0)
            {
                printf("Press any key to continue...");
                getch();
                system("cls");
            }
        }
        m_pRstEmployees->Close();

        // Restore original FirstName column to catalog
        m_pCatNorthwind->Tables->GetItem("Employees")->Columns->
            Delete(m_pColNewFirstName->Name);

        m_pCatNorthwind->Tables->GetItem("Employees")->Columns->
            Append(_variant_t((IDispatch*)m_pColFirstName,true),
            adVarWChar,m_pColFirstName->DefinedSize);

        // Restore original FirstName values to Employees table.
        m_pRstEmployees->Open("Employees",m_pCatNorthwind->
            GetActiveConnection(),ADODB::adOpenKeyset,
            ADODB::adLockOptimistic,ADODB::adCmdTable);

        m_pRstEmployees->MoveFirst();
        iCount = 0;
        while(!(m_pRstEmployees->EndOfFile))
        {
            m_pRstEmployees->Fields->GetItem("FirstName")->Value =
                aryFirstName[iCount];
            m_pRstEmployees->MoveNext();
            iCount++;
        }
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
            (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }
    catch(...)
    {
        cout << "Error occured in DefinedSizeX...."<< endl;
    }

    if (m_pRstEmployees)
        if (m_pRstEmployees->State == 1)
            m_pRstEmployees->Close();

    m_pCatNorthwind = NULL;
}
// EndDefinedSizeCpp

请参阅

Column 对象 | DefinedSize 属性


DeleteRule 属性范例 (VC++)

本范例演示 Key 对象的 DeleteRule 属性。该代码将追加一个新的 Table，然后定义新的主键，将 DeleteRule 设置为 adRICascade。

// BeginDeleteRuleCpp
#import "c:\Program Files\Common Files\system\ado\msadox.dll" \
    no_namespace
#import "c:\Program Files\Common Files\system\ado\msado15.dll"

#include "iostream.h"
#include "stdio.h"
#include "conio.h"

//Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void DeleteRuleX(void);

//////////////////////////////////////////////////////////
//                                                      //
//      Main Function                                   //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    DeleteRuleX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//       DeleteRuleX Function                           //
//                                                      //
//////////////////////////////////////////////////////////
void DeleteRuleX(void)
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.
    _KeyPtr m_pKeyPrimary = NULL;
    _CatalogPtr m_pCatalog   = NULL;
    _TablePtr m_pTblNew  = NULL;

    // Define string variables.
    _bstr_t strcnn("Provider='Microsoft.JET.OLEDB.4.0';"
                "Data source = 'c:\\Program Files\\Microsoft Office"
                "\\Office\\Samples\\Northwind.mdb';");
    try
    {
        TESTHR(hr = m_pKeyPrimary.CreateInstance(__uuidof(Key)));
        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof (Catalog)));
        TESTHR(hr = m_pTblNew.CreateInstance(__uuidof(Table)));

        // Connect the catalog.
        m_pCatalog->PutActiveConnection(strcnn);

        // Name new table.
        m_pTblNew->Name = "NewTable";

        // Append a numeric and a text field to new table.
        m_pTblNew->Columns->Append("NumField",adInteger,20);
        m_pTblNew->Columns->Append("TextField",adVarWChar,20);

        // Append the new table.
        m_pCatalog->Tables->Append(_variant_t((IDispatch*)m_pTblNew));
        printf("Table 'NewTable' is added.\n");

        // Define the Primary key.
        m_pKeyPrimary->Name = "NumField";
        m_pKeyPrimary->Type = adKeyPrimary;
        m_pKeyPrimary->RelatedTable = "Customers";
        m_pKeyPrimary->Columns->Append("NumField",adInteger,20);
        m_pKeyPrimary->Columns->GetItem("NumField")->RelatedColumn =
            "CustomerId";
        m_pKeyPrimary->DeleteRule = adRICascade;

        //to pass an optional column parameter to Key's Apppend method
        _variant_t vOptional;
        vOptional.vt = VT_ERROR;
        vOptional.scode = DISP_E_PARAMNOTFOUND;

        // Append the primary key.
        m_pCatalog->Tables->GetItem("NewTable")->Keys->Append(
            _variant_t((IDispatch*)m_pKeyPrimary),
            adKeyPrimary,vOptional,L"",L"");

        // Delete the table as this is a demonstration.
        m_pCatalog->Tables->Delete(m_pTblNew->Name);
        printf("Table 'NewTable' is deleted.\n");
    }

    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
            (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }

    catch(...)
    {
        cout << "Error occured in include files...."<< endl;
    }
}
// EndDeleteRuleCpp

请参阅

DeleteRule 属性 | Key 对象


GetObjectOwner 和 SetObjectOwner 方法范例 (VC++)

本范例演示 GetObjectOwner 和 SetObjectOwner 方法。此代码假定存在 Accounting 组（要查看如何向系统中添加这个组，请参阅 Groups 和 Users 的 Append、ChangePassword 方法范例 (VC++)）。Categories 表的所有者设置为 Accounting。

// BeginOwnersCpp
#import "c:\Program Files\Common Files\system\ado\msadox.dll" no_namespace

#include "iostream.h"
#include "stdio.h"
#include "conio.h"

//Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void OwnersX(void);

//////////////////////////////////////////////////////////
//                                                      //
//        Main Function                                 //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    OwnersX();

        ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//      OwnersX Function                                //
//                                                      //
//////////////////////////////////////////////////////////
void OwnersX()
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.
    _TablePtr m_pTable = NULL;
    _CatalogPtr m_pCatalog = NULL;

    try
    {
        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof(Catalog)));
        TESTHR(hr = m_pTable.CreateInstance(__uuidof(Table)));

        //Open the Catalog.
        m_pCatalog->PutActiveConnection(
            "Provider='Microsoft.JET.OLEDB.4.0';" \
            "data source='c:\\Program Files\\Microsoft Office\\"
            "Office\\Samples\\Northwind.mdb';"
            "jet oledb:system database='c:\\Program Files\\Microsoft Office\\"
            "Office\\system.mdw'");

        //Print the original owner of Categories
        _bstr_t strOwner = m_pCatalog->GetObjectOwner("Categories",
            adPermObjTable);
        cout << "Owner of Categories: " << strOwner << "\n" << endl;
        int iLineCnt = 2;

        //Create and append new group with a string.
        m_pCatalog->Groups->Append("Accounting");

        //Set the owner of Categories to Accounting.
        m_pCatalog->SetObjectOwner("Categories",
            adPermObjTable,"Accounting");

        _variant_t vIndex;
        //List the owners of all tables and columns in the catalog.
        for (long iIndex = 0; iIndex < m_pCatalog->Tables->Count; iIndex++)
        {
            vIndex = iIndex;
            m_pTable = m_pCatalog->Tables->GetItem(vIndex);
            cout << "Table: " << m_pTable->Name << endl;
            cout << "   Owner: " << m_pCatalog->
                GetObjectOwner(m_pTable->Name,adPermObjTable) << endl;
            if (iLineCnt%16 == 0)
                {
                    printf("\nPress any key to continue...\n");
                    getch();
                }
                iLineCnt = iLineCnt + 2;
        }

        //Restore the original owner of Categories
        m_pCatalog->SetObjectOwner("Categories",adPermObjTable,strOwner);

        //Delete Accounting
        m_pCatalog->Groups->Delete("Accounting");
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
             (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }

    catch(...)
    {
        cout << "Error occured in include files...."<< endl;
    }
}
// EndOwnersCpp


GetPermissions 和 SetPermissions 方法范例 (VC++)

本范例演示 GetPermissions 和 SetPermissions 方法。下面的代码授予管理员用户对 Orders 表的完全访问权限。

// BeginGrantPermissionCpp
#import "c:\Program Files\Common Files\system\ado\msado15.dll"
#import "c:\Program Files\Common Files\system\ado\msadox.dll" \
    no_namespace

#include "iostream.h"
#include "stdio.h"
#include "conio.h"

//Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void GrantPermissionsX(void);

//////////////////////////////////////////////////////////
//                                                      //
//     Main Function                                    //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    GrantPermissionsX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//    GrantPermissionsX Function                        //
//                                                      //
//////////////////////////////////////////////////////////
void GrantPermissionsX()
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.
    _CatalogPtr m_pCatalog = NULL;

    //Define ADODB object pointers;
    ADODB::_ConnectionPtr m_pCnn = NULL;

    //Define other variables here.
    try
    {
        TESTHR(hr = m_pCnn.CreateInstance(__uuidof(ADODB::Connection)));

        //Opens a connection to the northwind database
        //using the Microsoft Jet 4.0 provider
        m_pCnn->PutProvider("Microsoft.Jet.OLEDB.4.0");
        m_pCnn->Open("data source='c:\\Program Files\\"  \
        "Microsoft Office\\Office\\Samples\\Northwind.mdb';"  \
        "jet oledb:system database='c:\\Program Files\\Microsoft Office\\Office\\system.mdw'",
            "","",NULL);

        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof(Catalog)));

        m_pCatalog->PutActiveConnection(_variant_t((IDispatch *)m_pCnn));

        //Retrieve original permissions
        long lngPerm = m_pCatalog->Users->GetItem("admin")->
            GetPermissions("Orders",adPermObjTable);
        long lngOrgPerm = lngPerm;
        cout << "Original Permissions: " << lngPerm << "\n" << endl;

        //Revoke all permissions
        m_pCatalog->Users->GetItem("admin")->SetPermissions("Orders",
            adPermObjTable,adAccessRevoke,adRightFull,adInheritNone);

        //Display permissions
        lngPerm = m_pCatalog->Users->GetItem("admin")->
            GetPermissions("Orders",adPermObjTable);
        cout << "Revoked permissions: " << lngPerm << "\n" << endl;

        //Give the Admin user full rights on the orders object
        m_pCatalog->Users->GetItem("admin")->SetPermissions("Orders",
            adPermObjTable,adAccessSet,adRightFull,adInheritNone);

        //Display permissions
        lngPerm = m_pCatalog->Users->GetItem("admin")->
            GetPermissions("Orders",adPermObjTable);
        cout << "Full permissions: " << lngPerm << "\n" << endl;

        //Restore original permissions
        m_pCatalog->Users->GetItem("admin")->SetPermissions("Orders",
            adPermObjTable,adAccessSet,(RightsEnum) lngOrgPerm,
            adInheritNone);

        //Display permissions
        lngPerm = m_pCatalog->Users->GetItem("admin")->
            GetPermissions("Orders",adPermObjTable);
        cout << "Final permissions: " << lngPerm << "\n" << endl;
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
              (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }
    catch(...)
    {
        cout << "Error occured in GrantPermissionsX...."<< endl;
    }
}
// EndGrantPermissionCpp


Groups 和 Users 的 Append、ChangePassword 方法范例 (VC++)

本范例通过向系统中添加新的 Group 和新的 User 来演示 Groups 的 Append 方法和 Users 的 Append 方法。新的 Group 被追加到新的 User 的 Groups 集合中。因此，新的 User 被添加到 Group 中。同样，ChangePassword 方法用于指定 User 密码。

// BeginGroupCpp
#import "c:\Program Files\Common Files\system\ado\msadox.dll" no_namespace

#include "iostream.h"
#include "stdio.h"
#include "conio.h"

//Function declarations
void GroupX(void);
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};

//////////////////////////////////////////////////////////
//                                                      //
//      Main Function                                   //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    GroupX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//         GroupX Function                              //
//                                                      //
//////////////////////////////////////////////////////////
void GroupX(void)
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.
    _CatalogPtr m_pCatalog   = NULL;
    _UserPtr m_pUserNew   = NULL;
    _UserPtr m_pUser  = NULL;
    _GroupPtr m_pGroup = NULL;

    // Define String Variables.
    _bstr_t strCnn("Provider='Microsoft.JET.OLEDB.4.0';"
        "Data source = 'c:\\Program Files\\Microsoft Office\\"
        "Office\\Samples\\Northwind.mdb';"
        "jet oledb:system database='c:\\Program Files\\Microsoft Office\\"
        "Office\\system.mdw'");

    try
    {
        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof (Catalog)));
        m_pCatalog->PutActiveConnection(strCnn);

        // Create and append new group with a string.
        m_pCatalog->Groups->Append("Accounting");

        // Create and append new user with an object.
        TESTHR(hr = m_pUserNew.CreateInstance(__uuidof(User)));
        m_pUserNew->PutName("Pat Smith");
        m_pUserNew->ChangePassword("","Password1");
        m_pCatalog->Users->Append(
            _variant_t((IDispatch *)m_pUserNew),"");

        // Make the user Pat Smith a member of the
        // Accounting group by creating and adding the
        // appropriate Group object to the user's Groups
        // collection.The same is accomplished if a User
        // object representing Pat Smith is created and
        // appended to the Accounting group Users collection
        m_pUserNew->Groups->Append("Accounting");

        // Enumerate all User objects in the
        // catalog's Users collection.
        long lUsrIndex;
        long lGrpIndex;
        _variant_t vIndex;
        for (lUsrIndex=0; lUsrIndex<m_pCatalog->Users->Count; lUsrIndex++)
        {
            vIndex = lUsrIndex;
            m_pUser = m_pCatalog->Users->GetItem(vIndex);
            cout<<"  "<<m_pUser->Name <<endl;
            cout<<"   Belongs to these groups:"<<endl;

            // Enumerate all Group objects in each User
            // object's Groups collection.
            if(m_pUser->Groups->Count != 0)
            {
                for(lGrpIndex=0;lGrpIndex<m_pUser->Groups->Count;lGrpIndex++)
                {
                    vIndex = lGrpIndex;
                    m_pGroup = m_pUser->Groups->GetItem(vIndex);
                    cout<<"     "<< m_pGroup->Name<<endl;
                }
            }
            else
                cout<<"       [None]"<<endl;
        }

        // Enumerate all Group objects in the default
        // workspace's Groups collection.
        for (lGrpIndex=0; lGrpIndex<m_pCatalog->Groups->Count; lGrpIndex++)
        {
            vIndex = lGrpIndex;
            m_pGroup = m_pCatalog->Groups->GetItem(vIndex);
            cout<<"   "<< m_pGroup->Name <<endl;
            cout<<"    Has as its members:"<<endl;

            // Enumerate all User objects in each Group
            // object's Users Collection.
            if(m_pGroup->Users->Count != 0)
            {
                for (lUsrIndex=0; lUsrIndex<m_pGroup->Users->Count; lUsrIndex++)
                {
                    vIndex = lUsrIndex;
                    m_pUser = m_pGroup->Users->GetItem(vIndex);
                    cout<<"    "<<m_pUser->Name<<endl;
                }
            }
            else
                cout<<"      [None]"<<endl;
        }

        // Delete new User and Group object because this
        // is only a demonstration.
        m_pCatalog->Users->Delete("Pat Smith");
        m_pCatalog->Groups->Delete("Accounting");
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
             (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }
    catch(...)
    {
        cout << "Error occured in include files...."<< endl;
    }
}
// EndGroupCpp


Indexes 的 Append 方法范例 (VC++)

下面的代码演示如何创建新的索引。该索引在表中占两列。

// BeginCreateIndexCpp
#import "c:\Program Files\Common Files\system\ado\msadox.dll" no_namespace

#include "iostream.h"
#include "stdio.h"
#include "conio.h"

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void CreateIndexX(void);

//////////////////////////////////////////////////////////
//                                                      //
//      Main Function                                   //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    CreateIndexX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//        CreateIndexX Function                         //
//                                                      //
//////////////////////////////////////////////////////////
void CreateIndexX(void)
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.
    _TablePtr m_pTable   = NULL;
    _IndexPtr m_pIndex    = NULL;
    _CatalogPtr m_pCatalog = NULL;

    //Define other variables
    _bstr_t strcnn("Provider='Microsoft.JET.OLEDB.4.0';"
        "Data source = 'c:\\Program Files\\Microsoft Office\\"
        "Office\\Samples\\Northwind.mdb';");
    try
    {
        TESTHR(hr = m_pTable.CreateInstance(__uuidof(Table)));
        TESTHR(hr = m_pIndex.CreateInstance(__uuidof(Index)));
        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof (Catalog)));

        // Open the catalog.
        m_pCatalog->PutActiveConnection(strcnn);

        // Define the table and append it to the catalog.
        m_pTable->Name = "MyTable";
        m_pTable->Columns->Append("Column1",adInteger,0);
        m_pTable->Columns->Append("Column2",adInteger,0);
        m_pTable->Columns->Append("Column3",adVarWChar,50);
        m_pCatalog->Tables->Append(_variant_t((IDispatch *)m_pTable));
        printf("Table 'MyTable' is appended.\n");

        // Define a multi-column index.
        m_pIndex->Name = "multicolidx";
        m_pIndex->Columns->Append("Column1",adInteger,0);
        m_pIndex->Columns->Append("Column2",adInteger,0);

        // Append the index to the table.
        m_pTable->Indexes->Append(_variant_t((IDispatch *)m_pIndex));
        printf("Index 'multicolidx' is appended.\n");

        // Delete the table.
        m_pCatalog->Tables->Delete("MyTable");
        printf("Table 'MyTable' is deleted.\n");
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
             (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }
    catch(...)
    {
        cout << "Error occured in CreateIndexX...."<< endl;
    }
}
// EndCreateIndexCpp


IndexNulls 属性范例 (VC++)

本范例演示 Index 的 IndexNulls 属性。该代码创建新的索引，并基于用户输入来设置 IndexNulls 值。然后，Index 被追加到 Northwind Catalog 的 Employees Table 中。新的 Index 被应用于基于 Employees 表的 Recordset，并且该 Recordset 被打开。Employees 表中添加了一个新记录，该记录的索引字段中带有 Null 值。是否显示此新记录取决于 IndexNulls 属性的设置。

// BeignIndexNullCpp
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
    rename("EOF", "EndOfFile")
#import "c:\Program Files\Common Files\system\ado\msadox.dll" \
    no_namespace

#include "iostream.h"
#include "stdio.h"
#include "conio.h"
#include "ADOXIndexNullsX.h"

// Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void IndexNullsX(_bstr_t);

//////////////////////////////////////////////////////////
//                                                      //
//      Main Function                                   //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    printf("\nShow records having indexed field value = NULL? (Y/N):");
    char input = getche();

    if(toupper(input)=='Y')
    {
        IndexNullsX("Allow");
    }
    else if(toupper(input)=='N')
    {
        IndexNullsX("Ignore");
    }
    else
    {
       exit(0);
    }

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//      IndexNullsX Function                            //
//                                                      //
//////////////////////////////////////////////////////////
void IndexNullsX(_bstr_t strSel)
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.
    _CatalogPtr m_pCatalog     = NULL;
    _IndexPtr m_pIndexNew      = NULL;

    // Define ADODB object pointers
    ADODB::_ConnectionPtr m_pCnn           = NULL;
    ADODB::_RecordsetPtr  m_pRstEmployees  = NULL;

    // Define other variables
    IADORecordBinding *picRs  = NULL;  // Interface Pointer Declared
    CEmployeeRs emprs;          // C++ Class Object

    // Define string variable.
    _bstr_t strCnn("Provider='Microsoft.JET.OLEDB.4.0';"
        "data source='c:\\Program Files\\Microsoft Office\\Office\\"
        "Samples\\Northwind.mdb';");

    try
    {
        TESTHR(hr = m_pCnn.CreateInstance(__uuidof(ADODB::Connection)));
        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof (Catalog)));
        TESTHR(hr = m_pIndexNew.CreateInstance(__uuidof(Index)));
        TESTHR(hr = m_pRstEmployees.CreateInstance(
            __uuidof(ADODB::Recordset)));

        // Connect the catalog.
        m_pCnn->Open(strCnn,"","",NULL);
        m_pCatalog->PutActiveConnection(_variant_t((IDispatch *)m_pCnn));

        // Append Country column to new index.
        m_pIndexNew->Columns->Append("Country",adVarWChar,0);
        m_pIndexNew->Name = "NewIndex";

        // Set IndexNulls based on user input
        if(strcmp((LPSTR)strSel,"Allow")==0)
        {
            m_pIndexNew->IndexNulls = adIndexNullsAllow;
        }
        else if(strcmp((LPSTR)strSel,"Ignore")==0)
        {
            m_pIndexNew->IndexNulls = adIndexNullsIgnore;
        }

        // Append new index to Employees table
        m_pCatalog->Tables->GetItem("Employees")->Indexes->Append(
            _variant_t((IDispatch *)m_pIndexNew));
        m_pRstEmployees->Index = m_pIndexNew->Name;
        m_pRstEmployees->Open("Employees",
            _variant_t((IDispatch *)m_pCnn),
            ADODB::adOpenKeyset,ADODB::adLockOptimistic,
            ADODB::adCmdTableDirect);

        // Add a new record to the Employees table.
        m_pRstEmployees->AddNew();
        m_pRstEmployees->Fields->GetItem("FirstName")->Value =
             (_bstr_t) "Gary";
        m_pRstEmployees->Fields->GetItem("LastName")->Value =
             (_bstr_t) "Haarsager";
        m_pRstEmployees->Update();

        // Bookmark the newly added record.
        _variant_t varBookmark = m_pRstEmployees->Bookmark;

        // Use the new index to set the order of the records.
        m_pRstEmployees->MoveFirst();
        printf("\n\nIndex = %s,",(LPSTR) m_pRstEmployees->Index);
        printf("IndexNulls = %d\n\n",m_pIndexNew->IndexNulls);
        cout<<"Country            -        Name"<<endl;

        // Open an IADORecordBinding interface pointer which
        // we will use for binding Recordset to a class
        TESTHR(hr = m_pRstEmployees->QueryInterface(
            __uuidof(IADORecordBinding),(LPVOID*)&picRs));

        // Bind the Recordset to a C++ class here
        TESTHR(hr = picRs->BindToRecordset(&emprs));

        // Enumerate the Recordset.The value of the
        // IndexNulls property will determine if the newly
        // added record appears in the output.
        while(!(m_pRstEmployees->EndOfFile))
        {
            printf("%s    -    %s %s\n",
                emprs.lemp_CountryStatus == adFldOK ?
                emprs.m_szemp_Country :"[Null]",
                emprs.lemp_FirstNameStatus == adFldOK ?
                emprs.m_szemp_FirstName :"<NULL>",
                emprs.lemp_LastNameStatus == adFldOK ?
                emprs.m_szemp_LastName :"<NULL>");
            m_pRstEmployees->MoveNext();
        }

        // Delete new record because this is a demonstration.
        m_pRstEmployees->Bookmark = varBookmark;
        m_pRstEmployees->Delete(ADODB::adAffectCurrent);
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
             (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }
    catch(...)
    {
        cout << "Error occured in include files...."<< endl;
    }

    if (m_pRstEmployees)
    {
        if (m_pRstEmployees->State == 1)
        {
            m_pRstEmployees->Close();
            m_pRstEmployees = NULL;
        }
    }

    // Delete new Index because this is a demonstration.
    if (m_pCatalog)
        m_pCatalog->Tables->GetItem("Employees")->Indexes->
            Delete(m_pIndexNew->Name);

    if (m_pCnn)
    {
        if (m_pCnn->State == 1)
        {
            m_pCnn->Close();
            m_pCnn = NULL;
        }
    }

    m_pCatalog = NULL;
}
// EndIndexNullCpp

IndexNullX.h

// BeginIndexNullsH
// IndexNullsX.h

#include "icrsint.h"

//This class extracts LastName,Country,FirstName from Employees table

class CEmployeeRs : public CADORecordBinding
{
BEGIN_ADO_BINDING(CEmployeeRs)
        // Column LastName is the 2nd field in the table
        ADO_VARIABLE_LENGTH_ENTRY2(2,adVarChar,m_szemp_LastName,
            sizeof(m_szemp_LastName),lemp_LastNameStatus,TRUE)
        // Column Country is the 11th field in the table
        ADO_VARIABLE_LENGTH_ENTRY2(11,adVarChar,m_szemp_Country,
            sizeof(m_szemp_Country),lemp_CountryStatus,TRUE)
            // Column Country is the 17th field in the table
        ADO_VARIABLE_LENGTH_ENTRY2(17,adVarChar,m_szemp_FirstName,
            sizeof(m_szemp_FirstName),lemp_FirstNameStatus,TRUE)
END_ADO_BINDING()

public:
    CHAR m_szemp_LastName[21];
    ULONG lemp_LastNameStatus;
    CHAR m_szemp_Country[16];
    ULONG lemp_CountryStatus;
    CHAR m_szemp_FirstName[11];
    ULONG lemp_FirstNameStatus;
};
// EndIndexNullsH


Keys 的 Append 方法，Key 的 Type、RelatedColumn、RelatedTable 和 UpdateRule 属性范例 (VC++)

下面的代码演示如何创建新的外键。假设存在两个表（Customers 和 Orders）。

// BeginCreateKeyCpp
#import "c:\Program Files\Common Files\system\ado\msadox.dll" \
    no_namespace
#import "c:\Program Files\Common Files\system\ado\msado15.dll"

#include "iostream.h"
#include "stdio.h"
#include "conio.h"

//Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void CreateKeyX(void);

//////////////////////////////////////////////////////////
//                                                      //
//      Main Function                                   //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    CreateKeyX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//        CreateKeyX Function                           //
//                                                      //
//////////////////////////////////////////////////////////
void CreateKeyX(void)
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.
    _KeyPtr m_pKeyForeign = NULL;
    _CatalogPtr m_pCatalog   = NULL;

    //Define other variables
    _bstr_t strcnn("Provider='Microsoft.JET.OLEDB.4.0';"
                "Data source = 'c:\\Program Files\\Microsoft Office\\"
                "Office\\Samples\\Northwind.mdb';");
    try
    {
        TESTHR(hr = m_pKeyForeign.CreateInstance(__uuidof(Key)));
        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof (Catalog)));
        m_pCatalog->PutActiveConnection(strcnn);

        // Define the foreign key.
        m_pKeyForeign->Name = "CustOrder";
        m_pKeyForeign->Type = adKeyForeign;
        m_pKeyForeign->RelatedTable = "Customers";
        m_pKeyForeign->Columns->Append("CustomerId",adVarWChar,0);
        m_pKeyForeign->Columns->GetItem("CustomerId")->RelatedColumn =
            "CustomerId";
        m_pKeyForeign->UpdateRule = adRICascade;

        // To pass as column parameter to Key's Apppend method
        _variant_t vOptional;
        vOptional.vt = VT_ERROR;
        vOptional.scode = DISP_E_PARAMNOTFOUND;

        // Append the foreign key.
        m_pCatalog->Tables->GetItem("Orders")->Keys->
            Append(_variant_t((IDispatch *)m_pKeyForeign),
            adKeyPrimary,vOptional,L"",L"");
        printf("Foreign key 'CustOrder' is added.\n");

        // Delete the key as this is a demonstration.
        m_pCatalog->Tables->GetItem("Orders")->Keys->
            Delete(m_pKeyForeign->Name);
        printf("Foreign key 'CustOrder' is deleted.\n");
    }

    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
             (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }

    catch(...)
    {
        cout << "Error occured in include files...."<< endl;
    }
}
// EndCreateKeyCpp


NumericScale 和 Precision 属性范例 (VC++)

本范例演示 Column 对象的 NumericScale 和 Precision 属性。此代码显示这两个属性在 Northwind 数据库的 Order Details 表中的值。

// BeginNumericScalePrecCpp
#import "c:\Program Files\Common Files\system\ado\msadox.dll" \
    no_namespace
#import "c:\Program Files\Common Files\system\ado\msado15.dll"

#include "iostream.h"
#include "stdio.h"
#include "conio.h"

//Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void NumericScalePrecX(void);

//////////////////////////////////////////////////////////
//                                                      //
//       Main Function                                  //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    NumericScalePrecX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//          NumericScalePrecX Function                  //
//                                                      //
//////////////////////////////////////////////////////////
void NumericScalePrecX(void)
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.
    _CatalogPtr m_pCatalog = NULL;
    _TablePtr m_pTable = NULL;
    _ColumnPtr m_pColumn = NULL;

    //Define ADODB object pointers
    ADODB::_ConnectionPtr m_pCnn = NULL;

    //Declare string variables
    _bstr_t strCnn("Provider='Microsoft.JET.OLEDB.4.0';"
        "Data Source='c:\\Program Files\\Microsoft Office\\"
        "Office\\Samples\\Northwind.mdb';");
    try
    {
        TESTHR(hr = m_pCnn.CreateInstance(__uuidof(ADODB::Connection)));

        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof (Catalog)));

        // Connect the catalog.
        m_pCnn->Open (strCnn, "", "", NULL);

        m_pCatalog->PutActiveConnection(variant_t((IDispatch *)m_pCnn));

        // Retrieve the Order Details table
        m_pTable = m_pCatalog->Tables->GetItem("Order Details");

        // Display numeric scale and precision of
        // small integer fields.
        _variant_t vIndex;
        for (long lIndex=0; lIndex < m_pTable->Columns->Count; lIndex++)
        {
            vIndex = lIndex ;
            m_pColumn = m_pTable->Columns->GetItem(vIndex);
                if(m_pColumn->Type == adSmallInt)
                {
                    cout << "Column: " << m_pColumn->GetName() << endl;
                    cout << "Numeric scale: " << (_bstr_t) m_pColumn->
                        GetNumericScale() << endl;
                    cout << "Precision: " << m_pColumn->GetPrecision() <<
                        endl;
                }
        }
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
             (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }
    catch(...)
    {
        cout << "Error occured in NumericScalePrecX...."<< endl;
    }
}
// EndNumericScalePrecCpp


Parameters 集合，Command 属性范例 (VC++)

下面的代码演示如何通过 Command 对象使用 Command 属性检索过程的参数信息。

// This sample runs correctly only if procedure 'CustomerById'
// exists. If the procedure doesn't exist, please use
// 'ADOXProceduresAppend.cpp' to creat it.

// BeginProcedureParametersCpp
#import "c:\Program Files\Common Files\system\ado\msadox.dll" \
    no_namespace
#import "c:\Program Files\Common Files\system\ado\msado15.dll"

#include "iostream.h"
#include "stdio.h"
#include "conio.h"

//Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void ProcedureParametersX(void);

//////////////////////////////////////////////////////////
//                                                      //
//    Main Function                                     //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    ProcedureParametersX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//      ProcedureParametersX Function                   //
//                                                      //
//////////////////////////////////////////////////////////
void ProcedureParametersX()
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.
    _CatalogPtr m_pCatalog = NULL;

    //Define ADODB object pointers.
    ADODB::_ConnectionPtr m_pCnn = NULL;
    ADODB::_CommandPtr m_pCommand = NULL;
    ADODB::_ParameterPtr m_pParameter = NULL;

    try
    {
        TESTHR(hr = m_pCnn.CreateInstance(__uuidof(ADODB::Connection)));

        //Open the Connection
        m_pCnn->Open("Provider='Microsoft.JET.OLEDB.4.0';"
                "Data Source='c:\\Program Files\\Microsoft Office\\"
                "Office\\Samples\\Northwind.mdb';","","",NULL);

        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof(Catalog)));

        //Open the catalog
        m_pCatalog->PutActiveConnection(_variant_t((IDispatch *)m_pCnn));

        //Get the command object
        m_pCommand = m_pCatalog->Procedures->GetItem("CustomerById")->
            GetCommand();

        _variant_t vIndex;

        //Retrieve Parameter information
        m_pCommand->Parameters->Refresh();
        for (long lIndex = 0; lIndex < m_pCommand->Parameters->Count;
            lIndex ++)
        {
            vIndex = lIndex;
            m_pParameter = m_pCommand->Parameters->GetItem(vIndex);
            cout << m_pParameter->Name << ":" << m_pParameter->Type <<
                "\n" << endl;
        }
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
             (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }

    catch(...)
    {
        cout << "Error occured in ProcedureParametersX...."<< endl;
    }
}
// EndProcedureParametersCpp


ParentCatalog 属性范例 (VC++)

下面的代码演示如何使用 ParentCatalog 属性在向目录中追加表之前访问提供者特有的属性。该属性为 AutoIncrement，它在 Microsoft Jet 数据库中创建了一个 AutoIncrement 字段。

// BeginCreateAutoIncrColumnCpp
#import "c:\Program Files\Common Files\system\ado\msadox.dll" \
    no_namespace
#import "c:\Program Files\Common Files\system\ado\msado15.dll"

#include "iostream.h"
#include "stdio.h"
#include "conio.h"

//Function declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void CreateAutoIncrColumnX(void);

//////////////////////////////////////////////////////////
//                                                      //
//      Main Function                                   //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    CreateAutoIncrColumnX();

     ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//       CreateAutoIncrColumnX Function                 //
//                                                      //
//////////////////////////////////////////////////////////
void CreateAutoIncrColumnX(void)
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.
    _CatalogPtr m_pCatalog = NULL;
    _TablePtr m_pTable = NULL;

    // Define ADODB object pointers.
    ADODB::_ConnectionPtr m_pCnn = NULL;

    //Define string variables
    _bstr_t strCnn("Provider='Microsoft.JET.OLEDB.4.0';"
        "Data Source='c:\\Program Files\\Microsoft Office\\"
        "Office\\Samples\\Northwind.mdb';");
    try
    {
        TESTHR(hr = m_pCnn.CreateInstance(__uuidof(ADODB::Connection)));

        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof (Catalog)));

        TESTHR(hr = m_pTable.CreateInstance(__uuidof (Table)));

        // Connect the catalog.
        m_pCnn->Open (strCnn, "", "", NULL);

        m_pCatalog->PutActiveConnection(variant_t((IDispatch *)m_pCnn));

        m_pTable->Name="MyContacts";
        m_pTable->ParentCatalog = m_pCatalog;

        // Create fields and append them to the new Table object.
        m_pTable->Columns->Append("ContactId", adInteger,0);

        // Make the ContactId column and auto incrementing column
        m_pTable->Columns->GetItem("ContactId")->Properties->
            GetItem("AutoIncrement")->Value = true;
        m_pTable->Columns->Append("CustomerID", adVarWChar,0);
        m_pTable->Columns->Append("FirstName", adVarWChar,0);
        m_pTable->Columns->Append("LastName", adVarWChar,0);
        m_pTable->Columns->Append("Phone", adVarWChar, 20);
        m_pTable->Columns->Append("Notes", adLongVarWChar,0);
        m_pCatalog->Tables->Append(_variant_t((IDispatch*)m_pTable));

        // Refresh the database.
        m_pCatalog->Tables->Refresh();

        printf("Table 'MyContacts' is added.\n");

        // Delete new table, since this is only an example
        m_pCatalog->Tables->Delete("MyContacts");

        printf("Table 'MyContacts' is deleted.\n");
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
             (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }
    catch(...)
    {
        cout << "Error occured in CreateAutoIncrColumnX...."<< endl;
    }

    m_pCatalog = NULL;
}
// EndCreateAutoIncrColumnCpp


PrimaryKey 和 Unique 属性范例 (VC++)

本范例演示 Index 的 PrimaryKey 和 Unique 属性。此代码创建了一个具有两列的新表。PrimaryKey 和 Unique 属性用于使一个列成为主键列，该列中的值不允许重复。

// BeginPrimaryKeyCpp
#import "c:\program files\common files\system\ado\msadox.dll" \
    no_namespace
#import "c:\program files\common files\system\ado\msado15.dll"

#include "iostream.h"
#include "stdio.h"
#include "conio.h"

//Function Declarations
inline void TESTHR(HRESULT x) {if FAILED(x) _com_issue_error(x);};
void PrimaryKeyX(void);

//////////////////////////////////////////////////////////
//                                                      //
//    Main Function                                     //
//                                                      //
//////////////////////////////////////////////////////////
void main()
{
    if(FAILED(::CoInitialize(NULL)))
        return;

    PrimaryKeyX();

    ::CoUninitialize();
}

//////////////////////////////////////////////////////////
//                                                      //
//        PrimaryKeyX Function                          //
//                                                      //
//////////////////////////////////////////////////////////
void PrimaryKeyX()
{
    HRESULT hr = S_OK;

    // Define ADOX object pointers.
    // Initialize pointers on define.
    // These are in the ADOX::  namespace.
    _CatalogPtr m_pCatalog = NULL;
    _TablePtr m_pTableNew = NULL;
    _IndexPtr m_pIndexNew  = NULL;
    _IndexPtr m_pIndex  = NULL;
    _ColumnPtr m_pColumn = NULL;

    //Define string variable
    _bstr_t strcnn("Provider='Microsoft.JET.OLEDB.4.0';"
        "Data Source = 'c:\\Program Files\\"
        "Microsoft Office\\Office\\Samples\\Northwind.mdb';");

    try
    {
        TESTHR(hr = m_pCatalog.CreateInstance(__uuidof(Catalog)));
        TESTHR(hr = m_pTableNew.CreateInstance(__uuidof(Table)));
        TESTHR(hr = m_pIndexNew.CreateInstance(__uuidof(Index)));
        TESTHR(hr = m_pIndex.CreateInstance(__uuidof(Index)));
        TESTHR(hr = m_pColumn.CreateInstance(__uuidof(Column)));

        // Connect the catalog
        m_pCatalog->PutActiveConnection(strcnn);

        // Name new table
        m_pTableNew->Name = "NewTable";

        // Append a numeric and a text field to new table.
        m_pTableNew->Columns->Append("NumField", adInteger, 20);
        m_pTableNew->Columns->Append("TextField", adVarWChar, 20);

        // Append new Primary Key index on NumField column
        // to new table
        m_pIndexNew->Name = "NumIndex";
        m_pIndexNew->Columns->Append("NumField",adInteger,0);
        // here "-1" is required instead of "true".
        m_pIndexNew->PutPrimaryKey(-1);
        m_pIndexNew->PutUnique(-1);
        m_pTableNew->Indexes->Append(
            _variant_t ((IDispatch*)m_pIndexNew));

        // Append an index on Textfield to new table.
        // Note the different technique: Specifying index and
        // column name as parameters of the Append method
        m_pTableNew->Indexes->Append("TextIndex", "TextField");

        // Append the new table
        m_pCatalog->Tables->Append(_variant_t ((IDispatch*)m_pTableNew));

        cout << m_pTableNew->Indexes->Count << " Indexes in "
            << m_pTableNew->Name << " Table" << endl;
        m_pCatalog->Tables->Refresh();

        _variant_t vIndex;
        // Enumerate Indexes collection.
        for (long lIndex = 0;lIndex < m_pTableNew->Indexes->Count;
             lIndex++)
        {
            vIndex = lIndex;
            m_pIndex = m_pTableNew->Indexes->GetItem(vIndex);
            cout << "Index " << m_pIndex->Name << endl;
            cout << "   Primary key = " << (m_pIndex->GetPrimaryKey() ?
                "True" : "False") << endl;
            cout << "   Unique = "  << (m_pIndex->GetUnique() ? "True" :
                "False") << endl;

            // Enumerate Columns collection of each Index
            // object.
            cout << "    Columns" << endl;

            for (long lIndex = 0;lIndex < m_pIndex->Columns->Count;
                 lIndex++)
            {
                vIndex = lIndex  ;
                m_pColumn = m_pIndex->Columns->GetItem(vIndex);
                cout << "       " << m_pColumn->Name << endl;
            }
        }

        // Delete new table as this is a demonstration
        m_pCatalog->Tables->Delete(m_pTableNew->Name);
    }
    catch(_com_error &e)
    {
        // Notify the user of errors if any.
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());

        printf("\n\tSource :  %s \n\tdescription : %s \n ",
              (LPCSTR)bstrSource,(LPCSTR)bstrDescription);
    }
    catch(...)
    {
        cout << "Error occured in PrimaryKeyX...."<< endl;
    }

    m_pCatalog = NULL;
}
// EndPrimaryKeyCpp


法律和版权信息

ADO 2.5

法律和版权信息
Microsoft ActiveX Data Objects (ADO)

本文档中的信息（包含 URL 和其他 Internet 网站参考）的改动不另行通知。除非另行说明，否则此处所提及的举例性的公司、组织、产品、域名、电子邮件地址、徽标、人员、地点和事件都为虚构，并无有意联系或暗示任何真实公司、组织、产品、域名、电子邮件地址、徽标、人员、地点和事件。遵守所有适用版权的法律是用户的职责。在未经版权授予的情况下，不得将本文档中的任何部分复制、存储或引入检索系统，或者以任何形式或任何方式（电子、机械、影印、录音或其他方式）出于任何目的传播本文档中的信息，而未经 Microsoft Corporation 明确授权。

Microsoft 在涉及本文档的相关主题中拥有专利、专利申请、商标、版权或其他知识产权。除非 Microsoft 的许可协议明确声明，本文档并未向您授予这些专利、商标、版权或其他知识产权的许可权。

1998-2003 Microsoft Corporation。保留所有权利。

Microsoft、Windows、Windows NT、ActiveX、Developer Studio、FoxPro、JScript、MSDN、Visual Basic、Visual C++、Visual InterDev、Visual J++、Visual Studio 和 Win32 都是 Microsoft Corporation 在美国和/或其他国家（地区）的商标或注册商标。

Apple 是 Apple 计算机有限公司的注册商标。

Intel 是 Intel 公司的注册商标。

此处提及的真实的公司以及产品名称可能是其各自拥有者的商标。


SchemaObjectTypeEnum

指定由 GetSchemaObject 方法限制的对象的类型。

常量 | 值 | 说明
adObjectTypeDimension | 1 | Dimension 对象
adObjectTypeHierarchy | 2 | Hierarchy 对象
adObjectTypeLevel | 3 | Level 对象
adObjectTypeMember | 4 | Member 对象

© 1998-2002 Microsoft Corporation。保留所有权利。


GetSchemaObject 方法

通过 UniqueName 检索 ADO MD 模式对象（Dimension、Hierarchy、Level 或 Member）。

语法

Set object = CubeDef.GetSchemaObject (ObjType, UniqueName)

参数

ObjType
SchemaObjectTypeEnum 值，指定要检索的模式对象的类型（Dimension、Hierarchy、Level 或 Member）。
UniqueName
字符串，指定要检索的对象的 UniqueName 属性值。

说明

GetSchemaObject 使用对象的唯一名称（指定为 UniqueName 属性）来检索对象。无需知道父对象，且无需调用父对象来检索模式对象。

请参阅

应用于：CubeDef 对象

© 1998-2002 Microsoft Corporation。保留所有权利。


废弃的组件

下列的各个组件已经废弃不用。尽管 Microsoft Data Access Components (MDAC) 的这一版本仍然支持这些组件，但将来可能删除这些组件。在编写新的应用程序时，应该避免使用这些废弃的组件。在修改现有的应用程序时，强烈建议您取消对这些组件的依赖。

ODBC Provider (MSDASQL)

强烈建议您使用原生 OLE DB 提供者，而不是 Microsoft 开放式数据库连接 (ODBC) 提供者。原生 OLE DB 提供者可提供更好的应用程序稳定性和性能。而且，原生 OLE DB 提供者将在不久受到支持，而 MSDASQL 却不会添加任何新功能，而且不能在 64 位平台上使用，更不能从 OLE DB 网络数据提供者进行访问。

远程数据服务 (RDS)

远程数据服务 (RDS) 是 Microsoft 的专用机制，用于通过 Internet 或 Intranet 访问远程数据。Microsoft 正在开发 Microsoft Simple Object Access Protocol (SOAP) Toolkit 2.0，它使您可以用基于 XML 的开放标准访问远程数据。如果 SOAP Toolkit 2.0 可用，您应当从 RDS 迁移到 SOAP。SOAP 2.0 Toolkit 2.0 还包含远程访问 Microsoft ActiveX Data Objects (ADO) Recordsets 的范例代码。

Jet and Replication Objects (JRO)

MDAC 2.6 中删除了 Microsoft Jet OLE DB Provider 和其他相关的组件。Microsoft 已经废弃了 Microsoft Jet Engine，并计划不再对这一组件开发新的版本或服务包。因此，Jet and Replication Objects (JRO) 在这一版本中已经取消了，并且不会在以后的 MDAC 版本中出现。

AppleTalk 和 Banyan Vines SQL 网络库

如果正在使用 AppleTalk 或 Banyan Vines SQL 网络库，您应该修改应用程序以便使用其他 SQL 网络库，如 TCP/IP。AppleTalk 和 Banyan Vines SQL 网络库在这一版本中已废弃不用，并且不会在以后的 MDAC 版本中出现。

16 位 ODBC 支持

如果仍在使用 16 位数据源，您需要迁移到 32 位数据源。16 位功能在这一版本中已经废弃不用，并且不会在以后的 MDAC 版本中出现。

© 1998-2002 Microsoft Corporation。保留所有权利。


您有关于 MDAC 文档的反馈吗？

MDAC 文档开发小组欢迎您针对我们的文档和范例提出建议和评论。您可以通过电子邮件或 Universal Data Access 网站快速而直接地发送反馈。本文档的这一版本便采纳了读者的很多建议。

注意 如果需要技术支持，请参阅“从 Microsoft 产品支持服务获得帮助”。MDAC 文档开发小组不能回答技术支持问题，但是我们欢迎您就文档的表达、准确性和详尽性提出反馈和改进意见。

电子邮件

MDAC 文档现在在每个主题的顶部包含一个“文档反馈”按钮。单击此按钮即可方便地将电子邮件反馈发送给 MDAC 文档开发小组。下面还列出了 MDAC 文档各个部分的地址。

文档 | 地址
MDAC 概述 | mdacdoc@microsoft.com
ADO | adodoc@microsoft.com
OLE DB 和提供者 | oledbdoc@microsoft.com
ODBC 和驱动程序 | odbcdoc@microsoft.com
MDAC 技术文章 | datech@microsoft.com
MDAC 范例 | dacode@microsoft.com

Universal Data Access 网站

关于产品或文档的反馈，请使用 Universal Data Access Web 站点处的表单。此表单专门用于有关网站的反馈，但所有文档和范例问题都将被转送至相应的开发小组。


疑难解答

当您遇到 MDAC 技术问题时，请尝试下列资源，以便在致电 Microsoft 产品支持服务之前获得帮助。

  • MDAC 技术文章 可以在 Platform SDK 中找到许多与 MDAC 相关的技术文章。
  • 网站 Universal Data Access 网站和 MSDN Library 提供了文章和技术信息，可能会对您有所帮助。
  • Microsoft 知识库 此数据库中的文章提供了关于 Microsoft Data Access 组件的特定的解决方案、工作区和相关信息。
  • 公用新闻组：microsoft.public.data.ado 和其他。


安装和重新分发 ADO

从 Windows 2000 开始，MDAC 现在已集成到操作系统中。未来的操作系统版本将包含 MDAC 组件。MDAC SDK 可以在平台 SDK 中找到。英语和 18 种其他语言的 Microsoft Data Access Components 的重分发版本可以从 Microsoft Universal Data Access Web 站点下载。

若要将 Windows 95、Windows 98、Windows NT 4.0、Windows 2000 或 Windows Millennium Edition 更新到 MDAC 2.7，可以从 UDA 网站下载可重新分发的安装程序 Mdac_typ.exe。MDAC 2.7 会作为 SQL Server 2000 的一部分进行安装。Mdac_typ.exe 可重新分发文件包含在 SQL Server 2000 光盘中。该程序将安装应用程序在使用 MDAC 中的技术时所需的所有文件。可重新分发程序不提供有选择地安装组件的选项；要么全部安装，要么全部不安装。因此，所有组件均以 Microsoft 最后测试时所用的相同配置进行安装，从而减少了由于 DLL 版本不匹配而导致的问题。

MDAC 是系统组件，应当将安装 MDAC 视为类似于系统升级。如果不替换由 MDAC 安装程序所升级的操作系统文件，就无法删除 MDAC。很多应用程序（包括 Microsoft Internet Explorer、Visual Studio、SQL Server 和 Office）需要有 MDAC 以便实现数据绑定和其他应用程序功能。删除 MDAC 将对这些应用程序带来负面影响，或者损坏这些程序。但是，在某些环境下，Microsoft 产品支持服务可以帮助您解决安装和行为问题。详细信息，请参阅安装 MDAC Q&A（位于Microsoft Universal Data Access 网站。

© 1998-2002 Microsoft Corporation。保留所有权利。


引用 ADO 库

与提供类型库的任何库一样，您必须设置对需要在 Visual Basic 工程中使用的 ADO 库的引用。ADO 当前版本的类型库包含在 ADO DLL，msado15.dll 中。（为满足使用某些更早版本编写的应用程序的要求，该类型库的更早版本也可以通过所提供的 msado20.tlb、msado21.tlb 和 msado25.tlb 文件来引用。）

若要将 ADO 库引用在 Visual Basic 工程中，请打开“工程”菜单，然后单击“引用”。向下滚动选择 Microsoft ActiveX Data Objects 2.7 Library。如果在装有 ADO 2.5 的系统上编译的应用程序必须在装有 ADO 的先前版本的计算机上运行，它就需要使用一种向后兼容类型库。添加对适当的 .tlb 文件的引用，而不是对 msado15.dll 的引用。

© 1998-2002 Microsoft Corporation。保留所有权利。


运行地址簿 SQL 脚本

必须使用 ISQL/查询分析器命令行实用程序或 SQL Server Enterprise Manager 来运行包含的 SQL 脚本 (Sampleemp.sql)：

  • 在默认设备上创建新数据库 AddrBookDB。
  • 连接数据库 AddrBookDB。
  • 创建 Employee 表。
  • 用范例数据预置表。
  • 运行简单的 SELECT 语句以验证数据库表的预置。
  • 设置名为“adcdemo”、密码为“adcdemo”的用户帐户。

运行 Sampleemp.sql 脚本的步骤

在 Microsoft SQL Server 6.5 中：

  1. 单击“开始”，指向“程序”，再指向“Microsoft SQL Server 6.5”。单击“SQL Enterprise Manager”。
  2. 在“工具”菜单中单击“SQL 查询工具”。
  3. 单击“加载 SQL 脚本”，并定位到 c:\Platform SDK\Samples\DataAccess\RDS\AddrBook。
  4. 选择文件 Sampleemp.sql，单击“打开”。
  5. 单击“执行查询”按钮（工具栏上的绿色箭头）。
  6. 执行该文件后，请关闭“查询”和“Enterprise Manager”窗口。

在 Microsoft SQL Server 7.0 中：

  1. 单击“开始”，指向“程序”，再指向“Microsoft SQL Server 7.0”。 单击“Enterprise Manager”。
  2. 确保从已在 Enterprise Manager 中注册的服务器列表中选定了要使用的 SQL 服务器。
  3. 在“工具”菜单中单击“SQL Server 查询分析器”。
  4. 单击“加载 SQL 脚本”按钮（工具栏上打开的文件夹）并定位到 c:\Platform SDK\Samples\DataAccess\RDS\AddressBook。
  5. 选择文件 Sampleemp.sql，单击“打开”。
  6. 单击“执行查询”按钮（工具栏上的绿色箭头）或按 F5。
  7. 执行该文件后，请关闭“查询”、“查询分析器”和“Enterprise Manager”窗口。

请参阅

运行地址簿范例应用程序

© 1998-2002 Microsoft Corporation。保留所有权利。


范例应用程序

范例应用程序与 ADO 和 RDS 的 MDAC SDK 包含在一起。这些范例旨在帮助客户学习如何使用 ADO 和 RDS，而不是要在产品服务器上展开这些范例。

注意 范例中所用的公司、名称以及数据除特别注明外均属虚构。

ADO 包含几个范例应用程序。将这些范例应用程序从 Microsoft Platform SDK 根文件夹中安装到 C:\Program Files\Microsoft Platform SDK\Samples\DataAccess。有关安装和定位 Platform SDK 中项目的详细信息，请参阅“定位 MDAC 组件”。

要学习使用 ADO 和 RDS 范例应用程序，请分别打开 ADO 和 RDS 范例文件夹中的 default.htm。这些文件描述了每个可用的范例应用程序，并解释了如何配置和运行范例、如何浏览范例源代码。

请参阅

ADO 代码范例 | Microsoft Visual Basic 中的 ADO 代码范例 | Microsoft Visual Basic Scripting Edition 中的 ADO 代码范例 | Microsoft Visual C++ 中的 ADO 代码范例 | Microsoft Visual J++ 中的 ADO 代码范例

© 1998-2002 Microsoft Corporation。保留所有权利。


CommandStreams

ADO 2.5

命令流

ADO 通常支持由 CommandText 属性指定的字符串格式的命令输入。作为一种可选方案，通过 ADO 2.5，您还可以使用命令输入的信息流，方法是将流指定给 CommandStream 属性。您可以指定一个 ADO Stream 对象，或者支持 COM IStream 接口的任何对象。

命令流的内容只是从 ADO 传递给提供者，因此，提供者必须支持按流的命令输入以便使用该功能。例如，SQL Server 2000 支持以 Transact-SQL 的 XML 模板或 OpenXML 扩展形式的查询。有关 SQL Server 中流命令支持的详细信息，请参阅 SQL Server 联机图书中的“SQL Server XML 功能的 ADO 支持”。

由于流的细节必须由提供者解释，因此您必须通过设置 Dialect 属性指定命令方言。Dialect 的值是包含 GUID 的字符串，由提供者定义。有关提供者所支持的 Dialect 有效值的信息，请参阅提供者文档。有关 SQL Server 2000 所支持的方言的信息，请参阅 SQL Server 联机图书中的“将流用于命令输入”。

XML 模板查询范例

在 VBScript 中将以下范例编写到 SQL Server 2000 Northwind 数据库。

首先，初始化并打开要用来包含查询流的 Stream 对象：

Dim adoStreamQuery
Set adoStreamQuery = Server.CreateObject("ADODB.Stream")
adoStreamQuery.Open

查询流的内容将成为一个 XML 模板查询。有关 XML 模板查询的详细信息，请参阅 XML SDK。

该模板查询需要引用 <sql:query> 标记的 sql: 前缀所标识的 XML 名称空间。SQL SELECT 语句将作为 XML 模板的内容包含于其中，并被赋予了如下的字符串变量：

sQuery = "<ROOT xmlns:sql='urn:schemas-microsoft-com:xml-sql'>
<sql:query> SELECT * FROM PRODUCTS ORDER BY PRODUCTNAME </sql:query>
</ROOT>"

接下来，将字符串写入到流中：

adoStreamQuery.WriteText sQuery, adWriteChar
adoStreamQuery.Position = 0

将 adoStreamQuery 赋值给 ADO Command 对象的 CommandStream 属性。

Dim adoCmd
Set adoCmd  = Server.CreateObject("ADODB.Command"")
adoCmd.CommandStream = adoStreamQuery

指定命令语言 Dialect，它指示了 SQL Server OLE DB Provider 解释命令流的方式。该方言由提供者特定的 GUID 指定：

adoCmd.Dialect = "{5D531CB2-E6Ed-11D2-B252-00C04F681B71}"

最后，执行该查询并将结果返回到 Recordset 对象：

Set objRS = adoCmd.Execute

© 1998-2002 Microsoft Corporation。保留所有权利。


RDS 方案

地址簿应用程序是一个方案，它说明了如何使用远程数据服务 (RDS) 来建立简单的、数据识别的 Web 应用程序（联机的企业地址簿）。本方案适用于想学习如何将数据识别 ActiveX 控件与 RDS 配合使用的 Microsoft Visual Basic Scripting Edition (VBScript) 和 COM 程序员，以及想建立以数据为中心的 Web 应用程序的更有经验的应用程序开发人员。

本方案假定您已了解如何使用基本的 HTML 布局标记、DHTML 数据绑定技术以及 ActiveX 控件编程。

如果已安装了 Platform SDK，可在 <驱动器>:\Platform SDK\samples\dataaccess\rds\AddrBook\AddrBook.asp 上找到地址簿范例应用程序的完整源代码。要查看地址簿方案，可在 Internet Explorer 4.0 或更新版本中键入 http://webserver/RDS/AddrBook/AddrBook.asp，此处 webserver 是给定运行 Internet Information Services (IIS) 和 ASP 的 Windows NT 4.0 或 Windows 2000 Web 服务器的名称。

地址簿简介

地址簿范例应用程序提供了一个简单的联机地址簿，您可以用它在 Intranet 上发布可搜索的目录。地址簿使用户可以在一个或多个字段中输入搜索字符串，以请求有关雇员的信息。为了说明远程数据服务的基本功能，范例应用程序应尽量短小，并使用最少数量的对象和搜索字段。

应用程序接口包含如下部分：

  • 不可见的 RDS.DataControl 数据绑定对象，客户端用它来连接数据库。
  • HTML 文本框，作为雇员属性搜索条件的输入字段。
  • HTML 命令按钮，用于建立查询、清除搜索字段、更新雇员信息数据库、取消挂起的更改，以及定位显示在网格中的数据行。
  • DHTML 数据绑定，用于显示对表中的后端数据库（通过 RDS.DataControl 数据绑定对象）进行查询所返回的数据。
  • VBScript 例程，连接上面的每个元素并允许它们交互作用。VBScript 代码还可用来初始化 RDS.DataControl 对象，并可根据 RDS.DataControl 记录集字段的名称来动态地创建 HTML 表格的列标题。

跟随下面的链接逐步设置和运行方案，并进一步了解此方案的工作原理。

请参阅

地址簿应用程序的系统需求 | ActiveX Data Objects 开始页 | RDS 基础 | RDS 教程

© 1998-2002 Microsoft Corporation。保留所有权利。


将结果集检索到流中

与在传统的 Recordset 对象接收结果不同，ADO 可将查询结果检索到流中。ADO Stream 对象（或其他支持 COM IStream 接口的对象，如 ASP Request 和 Response 对象）可用于包含这些结果。此功能的一个用途就是以 XML 格式检索结果。例如，使用 SQL Server 2000，XML 结果可以多种方式返回（如使用带有 SQL SELECT 查询的 FOR XML 子句或使用 XPath 查询）。

若要以流格式而不是 Recordset 接收查询结果，则必须将 ExecuteOptionEnum 中的 adExecuteStream 常量指定为 Command 对象的 Execute 方法的一个参数。如果提供者支持此功能，则结果在执行时将返回到流中。在代码执行前，您可能需要指定其他特定提供者的属性。例如，使用 Microsoft OLE DB Provider for SQL Server 时，诸如 Command 对象的 Properties 集合中的 Output Stream 之类的属性必须被指定。有关与此功能相关的 SQL Server 特有动态属性的详细信息，请参阅 SQL Server 联机书籍中的 XML 相关属性。

FOR XML 查询范例

以下范例用 VBScript 写入 SQL Server 2000 Northwind 数据库中：

<!-- BeginRecordAndStreamVBS -->
<%@ LANGUAGE = VBScript %>
<%  Option Explicit      %>

<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Developer Studio"/>
<META HTTP-EQUIV="Content-Type" content="text/html"; charset="iso-8859-1">
<TITLE>FOR XML Query Example</TITLE>

<STYLE>
   BODY
   {
      FONT-FAMILY: Tahoma;
      FONT-SIZE: 8pt;
      OVERFLOW: auto
   }

   H3
   {
      FONT-FAMILY: Tahoma;
      FONT-SIZE: 8pt;
      OVERFLOW: auto
   }
</STYLE>

<!-- #include file="adovbs.inc" -->
<%
   Response.Write "<H3>Server-side processing</H3>"

   Response.Write "Page Generated @ " & Now() & "<BR/>"

   Dim adoConn
   Set adoConn = Server.CreateObject("ADODB.Connection")

   Dim sConn
   sConn = "Provider=SQLOLEDB;Data Source=BWILLETT1;Initial Catalog=Northwind;Integrated Security=SSPI;"

   Response.write "Connect String = " & sConn & "<BR/>"

   adoConn.ConnectionString = sConn
   adoConn.CursorLocation = adUseClient

   adoConn.Open

   Response.write "ADO Version = " & adoConn.Version & "<BR/>"
   Response.write "adoConn.State = " & adoConn.State & "<BR/>"

   Dim adoCmd
   Set adoCmd = Server.CreateObject("ADODB.Command")
   Set adoCmd.ActiveConnection = adoConn

   Dim sQuery
   sQuery = "<ROOT xmlns:sql='urn:schemas-microsoft-com:xml-sql'><sql:query>SELECT * FROM PRODUCTS WHERE ProductName='Gumbr Gummibrchen' FOR XML AUTO</sql:query></ROOT>"

   Response.write "Query String = " & sQuery & "<BR/>"

   Dim adoStreamQuery
   Set adoStreamQuery = Server.CreateObject("ADODB.Stream")
   adoStreamQuery.Open
   adoStreamQuery.WriteText sQuery, adWriteChar
   adoStreamQuery.Position = 0

   adoCmd.CommandStream = adoStreamQuery
   adoCmd.Dialect = "{5D531CB2-E6Ed-11D2-B252-00C04F681B71}"

   Response.write "Pushing XML to client for processing "  & "<BR/>"

   adoCmd.Properties("Output Stream") = Response
   Response.write "<XML ID='MyDataIsle'>"
   adoCmd.Execute , , 1024
   Response.write "</XML>"

%>

<SCRIPT language="VBScript" For="window" Event="onload">
   Dim xmlDoc
   Set xmlDoc = MyDataIsle.XMLDocument
   xmlDoc.resolveExternals=false
   xmlDoc.async=false

   If xmlDoc.parseError.Reason <> "" then
      Msgbox "parseError.Reason = " & xmlDoc.parseError.Reason
   End If

   Dim root, child
   Set root = xmlDoc.documentElement
   For each child in root.childNodes
      dim OutputXML
      OutputXML = document.all("log").innerHTML
      document.all("log").innerHTML = OutputXML & "<LI>" & child.getAttribute("ProductName") & "</LI>"
   Next
</SCRIPT>

</HEAD>

<BODY>

   <H3>Client-side processing of XML Document MyDataIsle</H3>
   <UL id=log>
   </UL>

</BODY>
</HTML>
<!-- EndRecordAndStreamVBS -->

已将新的 FOR XML 子句添加到 SQL Server 2000 中的 SELECT 语句。FOR XML 子句指示 SQL Server 以 XML 文档的形式返回数据。有关 SQL Server FOR XML 查询的详细信息，请参阅 SQL Server 联机书籍中的使用 FOR XML 检索 XML 数据。

FOR XML 语法

FOR XML [RAW|AUTO|EXPLICIT]

FOR XML RAW 生成带有列值作为属性的常规行元素。FOR XML AUTO 使用启发方式生成带有基于表名称的元素名称的分级树。FOR XML EXPLICIT 生成带有元数据完全说明的关系的统一表。

SQL SELECT FOR XML 语句范例如下所述：

SELECT * FROM PRODUCTS ORDER BY PRODUCTNAME FOR XML AUTO

该命令可能在如上所述分配给 CommandText 的字符串中指定，或以分配给 CommandStream 的 XML 模板查询的形式指定。有关 XML 模板查询的详细信息，请参阅 ADO 中的命令流或 SQL Server 联机书籍中的使用命令输入的流。

作为 XML 模板查询，FOR XML 查询将按照如下方式显示：

<sql:query> SELECT * FROM PRODUCTS ORDER BY PRODUCTNAME FOR XML AUTO </sql:query>

本例为 Output Stream 属性指定 ASP Response 对象：

adoCmd.Properties("Output Stream") = Response

下一步，指定 Execute 的 adExecuteStream 参数。本例隐藏 XML 标记中的流以创建 XML 数据岛。有关 XML 数据岛的详细信息，请参阅 XML SDK：

Response.write "<XML ID=MyDataIsle>"
adoCmd.Execute , , adExecuteStream
Response.write "</XML>"

在这一点上，XML 已被传递到客户端浏览器，并且准备就绪，可以显示。这可通过以下方式实现：使用客户端 VBScript 将 XML 文档绑定到 DOM 的实例并且遍历各个子节点以建立 HTML 中的“产品”列表。

© 1998-2002 Microsoft Corporation。保留所有权利。


Execute 方法 (RDS)

执行请求并创建用于 ADO 2.5 和更新版本的 ADO 记录集。

语法

object.Execute(ConnectionString As String, HandlerString As String, QueryString As String, lMarshalOptions As Long, Properties, TableId, lExecuteOptions As Long, pParameters, [lcid As Long], [pInformation])

参数

ConnectionString
字符串，用于连接到发送执行请求的 OLE DB 提供者。如果使用 HandlerString 指定处理程序，则可编辑或替换连接字符串。
HandlerString
字符串，标识用于此执行的处理程序。该字符串包含两部分。第一部分包含要使用的处理程序的名称 (ProgID)。第二部分包含要传递给处理程序的参数。参数字符串的解释方式取决于处理程序。两部分在字符串中的第一个实例处由逗号分隔开（虽然参数字符串可包含额外的逗号）。参数是可选的。
QueryString
连接字符串中标识的 OLE DB 提供者提供的命令语言中的命令。对于基于 SQL 的提供者，该命令可能包含 T-SQL 命令语句，但对于非 SQL 提供者（如 MSDataShape），不能为 T-SQL 查询语句。

如果正在使用某个处理程序，则该处理程序可以更改或替换 QueryString 中指定的值。例如，处理程序通常使用其 .ini 文件的查询字符串替换 QueryString。默认情况下，使用 Msdfmap.ini 文件。

注意 强烈建议使用处理程序。有关使用 RDS 自定义处理程序功能的详细信息，请参阅“使用 RDS 2.1 中的自定义处理程序”。
lMarshalOptions
用于设置返回行集合/记录集的调度选项。
TableID
VT_EMPTY 或 VT_BSTR 类型的 variant。如果此值为 VT_EMPTY 类型，则忽略该值。如果为 VT_BSTR 类型，则使用此处指定值的 adCmdTableDirect 创建记录集，并且忽略 QueryString 参数。
lExecuteOptions
下列执行选项的位掩码：
  • 1=ReadOnly – 使用 adLockReadOnly 打开记录集。
  • 2=NoBatch – 使用 adLockOptimistic 打开记录集。
  • 4=AllParamInfoSupplied - 调用者确保提供了 pParameters 中的所有参数的参数信息。
  • 8=GetInfo – 查询参数信息将从 OLE DB 提供者中获取并且返回到 pParameters 参数中。不执行查询并且不返回任何记录集。
  • 16=GetHiddenColumns – 使用 adLockBatchOptimistic 打开记录集，并且在记录集中包括任何隐藏列。

虽然 ReadOnly、NoBatch 和 GetHiddenColumns 为互斥选项，但是对于它们中选项设置的数目超过一个时并不会产生错误。如果设置了多个选项，则 GetHiddenColumns 优先级最高，其次是 ReadOnly。如果没有指定任何选项，默认情况下使用 adLockBatchOptimistic 打开记录集，但不在记录集中包括隐藏列。

pParameters
包含一个安全的参数定义数组的 variant。如果在 lExecuteOptions 中指定了 GetInfo 选项，则此参数用于返回从 OLE DB 提供者中获取的参数定义。否则，此参数为空。
lcid
LCID 用于 pInformation 中返回的任何错误。
pInformation
Execute 返回的信息错误的指针。如果为 NULL，则不返回任何错误信息。

说明

HandlerString 参数可为 NULL。这种情况下所出现的结果取决于 RDS 服务器的配置方式。处理程序字符串“MSDFMAP.handler”表示应该使用 Microsoft 提供的处理程序 (Msdfmap.dll)。处理程序字符串“MASDFMAP.handler,sample.ini”表示应该使用 Msdfmap.dll 处理程序，并且将参数“sample.ini”传递给该处理程序。MSDFMAP.dll 将解释该参数以提供指导，从而使用 sample.ini 来检查连接和查询字符串。

请参阅

应用于：DataFactory 对象 (RDSServer)

© 1998-2002 Microsoft Corporation。保留所有权利。


Execute21 方法 (RDS)

执行请求并创建用于 ADO 2.1 的 ADO 记录集。

语法

object.Execute21(ConnectionString As String, HandlerString As String, QueryString As String, lMarshalOptions As Long, Properties, TableId, lExecuteOptions As Long, pParameters)

参数

ConnectionString
字符串，用于连接到发送执行请求的 OLE DB 提供者。如果使用 HandlerString 指定处理程序，则可编辑或替换连接字符串。
HandlerString
字符串，标识用于此执行的处理程序。该字符串包含两部分。第一部分包含要使用的处理程序的名称 (ProgID)。第二部分包含要传递给处理程序的参数。参数字符串的解释方式取决于处理程序。两部分在字符串中的第一个实例处由逗号分隔开（虽然参数字符串可包含额外的逗号）。参数是可选的。
QueryString
连接字符串中标识的 OLE DB 提供者提供的命令语言中的命令。对于基于 SQL 的提供者，该命令可能包含 T-SQL 命令语句，但对于非 SQL 提供者（如 MSDataShape），不能为 T-SQL 查询语句。

如果正在使用某个处理程序，则该处理程序可以更改或替换 QueryString 中指定的值。例如，处理程序通常使用其 .ini 文件的查询字符串替换 QueryString。默认情况下，使用 Msdfmap.ini 文件。

注意 强烈建议使用处理程序。有关使用 RDS 自定义处理程序功能的详细信息，请参阅“使用 RDS 2.1 中的自定义处理程序”。
lMarshalOptions
用于设置返回行集合/记录集的调度选项。
TableID
VT_EMPTY 或 VT_BSTR 类型的 variant。如果此值为 VT_EMPTY 类型，则忽略该值。如果为 VT_BSTR 类型，则使用基于此处指定值的 adCmdTableDirect 创建记录集，并且忽略 QueryString 参数。
lExecuteOptions
下列执行选项的位掩码：
  • 1=ReadOnly – 使用 adLockReadOnly 打开记录集。
  • 2=NoBatch – 使用 adLockOptimistic 打开记录集。
  • 4=AllParamInfoSupplied - 调用者确保提供了 pParameters 中的所有参数的参数信息。
  • 8=GetInfo – 查询参数信息将从 OLE DB 提供者中获取并且返回到 pParameters 参数中。不执行查询并且不返回任何记录集。
  • 16=GetHiddenColumns – 使用 adLockBatchOptimistic 打开记录集，并且在记录集中包括任何隐藏列。

    虽然 ReadOnly、NoBatch 和 GetHiddenColumns 为互斥选项，但是对于它们中选项设置的数目超过一个时并不会产生错误。如果设置了多个选项，则 GetHiddenColumns 优先级最高，其次是 ReadOnly。如果没有指定任何选项，默认情况下使用 adLockBatchOptimistic 打开记录集，但不在记录集中包括隐藏列。

pParameters
包含一个安全的参数定义数组的 variant。如果在 lExecuteOptions 中指定了 GetInfo 选项，则此参数用于返回从 OLE DB 提供者中获取的参数定义。否则，此参数为空。

说明

HandlerString 参数可为 NULL。这种情况下所出现的结果取决于 RDS 服务器的配置方式。处理程序字符串“MSDFMAP.handler”表示应该使用 Microsoft 提供的处理程序 (Msdfmap.dll)。处理程序字符串“MASDFMAP.handler,sample.ini”表示应该使用 Msdfmap.dll 处理程序，并且将参数“sample.ini”传递给该处理程序。MSDFMAP.dll 将解释该参数以提供指导，从而使用 sample.ini 来检查连接和查询字符串。

注意 Execute21 方法只是一个版本的 Execute 方法 (RDS)。需要使用 Execute 方法与 ADO 2.1 通讯时，则将调用 Execute21 方法。ADO 2.5 和更新版本中 Execute 方法的功能 是 ADO 2.1 中相同方法提供的功能的超集。

请参阅

应用于：DataFactory 对象 (RDSServer)

© 1998-2002 Microsoft Corporation。保留所有权利。


Synchronize 方法 (RDS)

使给定的记录集与连接字符串指定的数据库同步，以在 ADO 2.5 或更高版本中使用。

语法

object.Synchronize(ConnectionString As String, HandlerString As String, lSynchronizeOptions As Long, ppRecordset As Object, pStatusArray, [lcid As Long], [pInformation)

参数

ConnectionString
字符串，用于连接到将要发送请求的 OLE DB 提供者。如果使用处理程序，处理程序可以编辑或替换连接字符串。
HandlerString
字符串，标识此执行要使用的处理程序。该字符串包含两个部分。第一部分包含要使用的处理程序的名称 (ProgID)。第二部分包含要传递到处理程序的参数。参数字符串的解释方法取决于处理程序。这两部分以字符串中逗号的第一个实例分隔开（尽管参数字符串可能还包含其他逗号）。参数是可选的。
lSynchronizeOptions
同步选项的位掩码如下：
  • 1=UpdateTransact – 对数据库的更新被封装在事务中。如果任何一次更新失败，事务都将被终止。
  • 2=RefreshWithUpdate – 如果未设置 Refresh 或 RefreshConflicts，将导致返回行状态。
  • 4=Refresh – 用数据库中的当前数据刷新记录集。挂起的更新不会被推送到数据库。如果未设置此位，将不会刷新记录集，也不会将任何挂起的更新推送到数据库。
  • 8=RefreshConflicts – 挂起更改的任何行的更新都会失败。用数据库中的当前数据刷新这些更新失败的行。
ppRecordset
一个指向要同步的记录集的指针的指针。
pStatusArray
Variant，用于返回受 Synchronize 方法影响的行的行状态安全数组。如果未设置下列同步选项：RefreshWithUpdate、Refresh 或 RefreshConflicts，将不设置该参数。
lcid
LCID，用于生成在 pInformation 中返回到的任何错误。
pInformation
指针，指向 Execute 方法返回的信息错误。如果为 NULL，则不返回任何错误信息。

说明

HandlerString 参数可以为 NULL。在这种情况下发生的事件取决于 RDS 服务器的配置方式。处理程序字符串 "MSDFMAP.handler" 指示应当使用 Microsoft 提供的处理程序 (Msdfmap.dll)。处理程序字符串 "MASDFMAP.handler,sample.ini" 指示应当使用 Msdfmap.dll 处理程序，并且应当将参数 "sample.ini" 传递到处理程序。然后，Msdfmap.dll 将该参数解释为使用 sample.ini 检查连接和查询字符串的指示。

请参阅

适用于：DataFactory 对象 (RDSServer)

© 1998-2002 Microsoft Corporation。保留所有权利。


Synchronize21 方法 (RDS)

使给定的记录集与连接字符串指定的数据库同步，以在 ADO 2.1 中使用。

语法

object.Synchronize21(ConnectionString As String, HandlerString As String, lSynchronizeOptions As Long, ppRecordset As Object, pStatusArray)

参数

ConnectionString
字符串，用于连接到将要发送请求的 OLE DB 提供者。如果使用处理程序，处理程序可以编辑或替换连接字符串。
HandlerString
字符串，标识此执行要使用的处理程序。该字符串包含两个部分。第一部分包含要使用的处理程序的名称 (ProgID)。第二部分包含要传递到处理程序的参数。参数字符串的解释方法取决于处理程序。这两部分以字符串中逗号的第一个实例分隔开（尽管参数字符串可能还包含其他逗号）。参数是可选的。
lSynchronizeOptions
同步选项的位掩码如下：
  • 1=UpdateTransact – 对数据库的更新被封装在事务中。如果任何一次更新失败，事务都将被终止。
  • 2=RefreshWithUpdate – 如果未设置 Refresh 或 RefreshConflicts，将导致返回行状态。
  • 4=Refresh – 用数据库中的当前数据刷新记录集。挂起的更新不会被推送到数据库。如果未设置此位，将不会刷新记录集，也不会将任何挂起的更新推送到数据库。
  • 8=RefreshConflicts – 挂起更改的任何行的更新都会失败。用数据库中的当前数据刷新这些更新失败的行。
ppRecordset
指针，指向要同步的记录集。
pStatusArray
Variant，用于返回受 Synchronize 方法影响的行的行状态安全数组。如果未设置下列同步选项：RefreshWithUpdate、Refresh 或 RefreshConflicts，将不设置该参数。

说明

HandlerString 参数可以为 NULL。在这种情况下发生的事件取决于 RDS 服务器的配置方式。处理程序字符串 "MSDFMAP.handler" 指示应当使用 Microsoft 提供的处理程序 (Msdfmap.dll)。处理程序字符串 "MASDFMAP.handler,sample.ini" 指示应当使用 Msdfmap.dll 处理程序，并且应当将参数 "sample.ini" 传递到处理程序。然后，Msdfmap.dll 将该参数解释为使用 sample.ini 检查连接和查询字符串的指示。

注意 Synchronize21 方法只是 Synchronize 方法 (RDS) 的一个版本。对于需要使用 Synchronize 方法与 ADO 2.1 进行通讯的情况，都可以调用 Synchronize21 方法来代替。Synchronize 方法在 ADO 2.5 或更高版本中的功能是该方法在 ADO 2.1 中提供的功能的一个超集。

请参阅

适用于：DataFactory 对象 (RDSServer)

© 1998-2002 Microsoft Corporation。保留所有权利。


CommandStream 属性 (ADO)

ADO 2.5 API 参考

Command 属性

指示用作 Command 对象输入的流。

设置和返回值

设置或返回用作 Command 对象输入的流。这种流的格式是提供者特有的，有关详细信息，请参阅提供者的文档。此属性类似于 CommandText 属性，后者用于指定 Command 输入的字符串。

说明

CommandStream 和 CommandText 是相互排斥的。如果用户设置了 CommandStream 属性，就要将 CommandText 属性设置为空字符串 ("")。如果用户设置了 CommandString 属性，就要将 CommandStream 属性设置为 Nothing。

Command.Parameters.Refresh 和 Command.Prepare 方法的行为是由提供者定义的。因此不能刷新流中参数的值。

输入流不适用于返回 Command 源的其他 ADO 对象。例如，如果将 Recordset 的 Source 属性设置为以流作为输入的 Command 对象，Recordset.Source 将继续返回 CommandText 属性，其中包含空字符串 ("")，而不是 CommandStream 属性的流内容。

使用命令流（如 CommandStream 指定的流），CommandType 属性的唯一有效的 CommandTypeEnum 值是 adCmdText 和 adCmdUnknown。其他任何值都将导致错误。

请参阅

CommandText 属性 | Dialect 属性 | CommandTypeEnum

适用于：Command 对象

© 1998-2002 Microsoft Corporation。保留所有权利。


Dialect 属性 (ADO)

ADO 2.5 API 参考

Dialect 属性

指示 CommandText 或 CommandStream 属性的方言。方言定义提供者用来对字符串或流进行语法分析的语法和通用规则。

设置和返回值

Dialect 属性包含有效的表示命令文本或流的 GUID。此属性的默认值为 {C8B521FB-5CF3-11CE-ADE5-00AA0044773D}，该默认值指示提供者选择解释命令文本或流的方式。

说明

当用户读取此属性的值时，ADO 不查询提供者；它返回当前存储在 Command 对象中的值的字符串表示形式。

当用户设置 Dialect 属性时，ADO 将验证 GUID，如果提供的值不是有效的 GUID，将产生错误。要确定 Dialect 属性支持的 GUID 值，请参阅提供者的文档。

请参阅

CommandStream 属性 | CommandText 属性 | Execute 方法 (ADO Command)

适用于：Command

© 1998-2002 Microsoft Corporation。保留所有权利。


NamedParameters 属性 (ADO)

ADO 2.5 API 参考

NamedParameters 属性

指示是否将参数名称传递给提供者。

说明

如果此属性为 True，ADO 将传递 Command 的 Parameter 集合中每个参数的 Name 属性值。提供者用参数名称匹配 CommandText 或 CommandStream 属性中的参数。如果此属性为 False（默认值），则忽略参数名称。提供者用参数顺序匹配 CommandText 或 CommandStream 属性中参数的值。

请参阅

CommandText 属性 | CommandStream 属性 | Parameters 集合

适用于：Command 对象

© 1998-2002 Microsoft Corporation。保留所有权利。


Microsoft OLE DB Simple Provider

Microsoft OLE DB Simple Provider (OSP) 允许 ADO 访问已使用 OLE DB Simple Provider Toolkit 为其编写了提供者的任何数据。简单提供者用于访问只需要基本 OLE DB 支持的数据源，如内存中的数组或 XML 文档。

连接字符串参数

要连接到 OLE DB Simple Provider DLL，请将 ConnectionString 属性的 Provider 参数设置为：

MSDAOSP

也可以使用 Provider 属性设置或读取此值。

使用已注册的提供者的名称（由提供者的编写者确定）可以连接到已注册为完全的 OLE DB 提供者的简单提供者。

典型连接字符串

此提供者的典型连接字符串是：

"Provider=MSDAOSP;Data Source=serverName"

该字符串由下列关键字组成：

关键字 | 说明
Provider | 指定 OLE DB Provider for SQL Server。
Data Source | 指定服务器的名称。

XML 文档范例

MDAC 2.7 中的 OLE DB Simple Provider (OSP) 已经增强，可以支持在任意 XML 文件中打开分级的 ADO Recordset。这些 XML 文件可能包含 ADO XML 持久性模式，但这并不是必需的。通过将 OSP 连接到 MSXML2.DLL 可以实现这一点，因此，需要 MSXML2.DLL 或更新版本。

下列范例中使用的 portfolio.xml 文件包含下面的树：

Portfolio
   Stock
      Shares
      Symbol
      Price
      Info
         Company Name
         WebSite

XML DSO 使用内置启发式技术将 XML 树中的节点转换为分级 Recordset 中的子集。

使用这些内置启发式技术，可以将 XML 树转换为一个两级的分级 Recordset，形式如下：

Parent Recordset
Shares, Symbol, Price, $Text
   Child Recordset
      Company Name, WebSite, $Text

注意，分级 Recordset 中不显示 Portfolio 和 Info 标记。有关 XML DSO 是如何将 XML 树转换为分级 Recordset 的说明，请参阅下列规则。下文讨论了 $Text 列。

将 XML 元素和属性分配给列和行的规则

XML DSO 遵循在数据绑定应用程序中将元素和属性分配给列和行的过程。将 XML 模型化成树，树中一个标记包含整个分级结构。例如，一本书的 XML 说明可能包含章标记、图标记和节标记。最高级别的是书标记，其中包含章、图和节等子元素。当 XML DSO 将 XML 元素映射到行和列时，将转换这些子元素，而不是最高级别的元素。

XML DSO 使用以下过程转换子元素：

  • 每个子元素和属性对应于分级结构中某个 Recordset 中的一列。
  • 列的名称与子元素或属性的名称相同，但排除父元素拥有同名属性和子元素的情况，在这种情况下，将在子元素的列名称前面加一个“!”。
  • 每一列既可以是包含标量值（通常是字符串）的“简单”列，也可以是包含子 Recordset 的 Recordset 列。
  • 与属性相对应的列通常是简单的。
  • 如果子元素拥有自己的子元素和/或属性，或者子元素的父将多个子元素实例作为子，那么与子元素相对应的列将是 Recordset 列，否则该列将是简单列。
  • 当存在多个子元素实例（属于不同的父）时，如果“任一”实例包含 Recordset 列，那么子元素的列就是 Recordset 列；仅当“所有”实例都包含简单列时，它的列才是简单列。
  • 所有 Recordsets 都具有名为 $Text 的附加列。

有关 XML DSO 的详细信息，请参阅 XML SDK。

构造 Recordset 所需的代码如下：

   Dim adoConn as ADODB.Connection
   Dim adoRS as ADODB.Recordset

   Set adoRS = New ADODB.Connection
   Set adoRS = New ADODB.Recordset

   adoConn.Open "Provider=MSDAOSP; Data Source=MSXML2.DSOControl.2.6;"
   adoRS.Open "http://WebServer/VRoot/portfolio.xml, adoConn
注意 可以使用四种不同的命名约定指定数据文件的路径。
   'HTTP://
   adoRS.Open "http://WebServer/VRoot/portfolio.xml", adoConn
   'FILE://
   adoRS.Open "file:/// C:\\Directory\\portfolio.xml", adoConn
   'UNC Path
   adoRS.Open "\\ComputerName\ShareName\portfolio.xml", adoConn
   'Full DOS Path
   adoRS.Open "C:\Directory\portfolio.xml", adoConn

一旦打开 Recordset，即可使用常用的 ADO Recordset 导航命令。

OSP 生成的 Recordset 具有以下几点限制：

  • 不支持客户端游标 (adUseClient)。
  • 不能使用 Recordset.Save 持久保留在任意 XML 中创建的分级 Recordset。
  • 使用 OSP 创建的 Recordset 是只读的。
  • XMLDSO 向分级结构中的每个 Recordset 添加一个附加列 Data ($Text)。

有关 OLE DB Simple Provider 的详细信息，请参阅 MDAC SDK 文档“OLE DB”一节中的“OLE DB Simple Provider Toolkit”。

代码范例

下列 Visual Basic 代码演示了如何打开任意 XML 文件、构造分级 Recordset 以及递归编写每个 Recordset 的每个记录以调试窗口。

以下是一个简单的包含股票报价的 XML 文件。下列代码使用此文件构造一个二级的分级 Recordset。

<portfolio>
   <stock>
      <shares>100</shares>
      <symbol>MSFT</symbol>
      <price>$70.00</price>
      <info>
         <companyname>Microsoft Corporation</companyname>
         <website>http://www.microsoft.com</website>
      </info>
   </stock>
   <stock>
      <shares>100</shares>
      <symbol>AAPL</symbol>
      <price>$107.00</price>
      <info>
         <companyname>Apple Computer, Inc.</companyname>
         <website>http://www.apple.com</website>
      </info>
   </stock>
   <stock>
      <shares>100</shares>
      <symbol>DELL</symbol>
      <price>$50.00</price>
      <info>
         <companyname>Dell Corporation</companyname>
         <website>http://www.dell.com</website>
      </info>
    </stock>
    <stock>
       <shares>100</shares>
       <symbol>INTC</symbol>
       <price>$115.00</price>
       <info>
          <companyname>Intel Corporation</companyname>
          <website>http://www.intel.com</website>
       </info>
   <stock>
</portfolio>

以下是两个 Visual Basic 子过程。第一个子过程创建了 Recordset，并将其传递给 WalkHier 子过程，WalkHier 子过程以递归方式执行分级结构，将每个 Recordset 中每个记录中的每个 Field 写入到调试窗口中。

Private Sub BrowseHierRecordset()
' Add ADO 2.5 to Project/References
' No need to add MSXML2, ADO just passes the ProgID through to the OSP.

    Dim adoConn As ADODB.Connection
    Dim adoRS As ADODB.Recordset
    Dim adoChildRS As ADODB.Recordset

    Set adoConn = New ADODB.Connection
    Set adoRS = New ADODB.Recordset
    Set adoChildRS = ADODB.Recordset

    adoConn.Open "Provider=MSDAOSP; Data Source=MSXML2.DSOControl.2.6;"
    adoRS.Open "http://bwillett3/Kowalski/portfolio.xml", adoConn

    Dim iLevel As Integer
    iLevel = 0
    WalkHier iLevel, adoRS

End Sub

Sub WalkHier(ByVal iLevel As Integer, ByVal adoRS As ADODB.Recordset)
    iLevel = iLevel + 1
    PriorLevel = iLevel
    While Not adoRS.EOF
        For ndx = 0 To adoRS.Fields.Count - 1
            If adoRS.Fields(ndx).Name <> "$Text" Then
                If adoRS.Fields(ndx).Type = adChapter Then
                    Set adoChildRS = adoRS.Fields(ndx).Value
                    WalkHier iLevel, adoChildRS
                Else
                    Debug.Print iLevel & ": adoRS.Fields(" & ndx & _
                       ") = " & adoRS.Fields(ndx).Name & " = " & _
                       adoRS.Fields(ndx).Value
                End If
            End If
        Next ndx
        adoRS.MoveNext
    Wend
    iLevel = PriorLevel
End Sub

© 1998-2002 Microsoft Corporation。保留所有权利。


从 Microsoft 产品支持服务获得帮助

ADO 2.5

从 Microsoft 产品支持服务网站获得帮助

如果在 Microsoft Data Access Components (MDAC) 文档中找不到所需的答案，通过访问 Microsoft 产品支持服务 Web 站点 http://www.microsoft.com/support 则可以快速解决问题。

有关使用 Microsoft 产品和技术进行开发的其他技术资源和信息，请访问 MSDN Online，网址为 http://msdn.microsoft.com。