ado数据库编程用(用Visual C++开发数据库应用程序(3))

2026-05-27 03:45:01 :0

ado数据库编程用(用Visual C++开发数据库应用程序(3))

今天给各位分享用Visual C++开发数据库应用程序(3)的知识,其中也会对用Visual C++开发数据库应用程序(3)进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录

用Visual C++开发数据库应用程序(3)


6、使用ADO
6.1 概述
ADO是ActiveX数据对象(ActiveX Data Object),这是Microsoft开发数据库应用程序的面向对象的新接口。ADO访问数据库是通过访问OLE DB数据提供程序来进行的,提供了一种对OLE DB数据提供程序的简单高层访问接口。
ADO技术简化了OLE DB的操作,OLE DB的程序中使用了大量的COM接口,而ADO封装了这些接口。所以,ADO是一种高层的访问技术。
ADO技术基于通用对象模型(COM),它提供了多种语言的访问技术,同时,由于ADO提供了访问自动化接口,所以,ADO可以用描述的脚本语言来访问VBScript,VCScript等。
6.2 在VC中使用ADO
可以使用VC6提供的ActiveX控件开发应用程序,还可以用ADO对象开发应用程序。使用ADO对象开发应用程序可以使程序开发者更容易地控制对数据库的访问,从而产生符合用户需求的数据库访问程序。
使用ADO对象开发应用程序也类似其它技术,需产生与数据源的连接,创建记录等步骤,但与其它访问技术不同的是,ADO技术对对象之间的层次和顺序关系要求不是太严格。在程序开发过程中,不必选建立连接,然后才能产生记录对象等。可以在使用记录的地方直接使用记录对象,在创建记录对象的同时,程序自动建立了与数据源的连接。这种模型有力的简化了程序设计,增强了程序的灵活性。下面讲述使用ADO对象进行程序设计的方法。
6.21 引入ADO库文件
使用ADO前必须在工程的stdafx.h文件里用直接引入符号#import引入ADO库文件,以使编译器能正确编译。代码如下所示:
#define INITGUID
#import "c:program filescommon filessystemadomsado15.dll" no_namespace rename("EOF","EndOfFile")
#include "icrsint.h"
这行语句声明在工程中使用ADO,但不使用ADO的名字空间,并且为了避免冲突,将EOF改名为EndOfFile。
6.22 初始化ADO环境
在使用ADO对象之前必须先初始化COM环境。初始化COM环境可以用以下代码完成:
在初始化COM环境后,就可以使用ADO对象了,如果在程序前面没有添加此代码,将会产生COM错误。
在使用完ADO对象后,需要用以下的代码将初始化的对象释放:
此函数清除了为ADO对象准备的COM环境。
6.23 接口简介
ADO库包含三个基本接口:
__ConnectionPtr接口、
__CommandPtr接口、
__RecordsetPtr接口,
__ConnectionPtr接口返回一个记录集或一个空指针。通常使用它来创建一个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。用__ConnectionPtr接口返回一个记录集不是一个好的使用方法。通常同CDatabase一样,使用它创建一个数据连接,然后使用其它对象执行数据输入输出操作。
__CommandPtr接口返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用__CommandPtr接口时,可以利用全局__ConnectionPtr接口,也可以在__CommandPtr接口里直接使用连接串。如果只执行一次或几次数据访问操作,后者是比较好的选择。但如果要频繁访问数据库,并要返回很多记录集,那么,应该使用全局__ConnectionPtr接口创建一个数据连接,然后使用__CommandPtr接口执行存储过程和SQL语句。
__RecordsetPtr是一个记录集对象。与以上两种对象相比,它对记录集提供了更多的控制功能,如记录锁定,游标控制等。同__CommandPtr接口一样,它不一定要使用一个已经创建的数据连接,可以用一个连接串代替连接指针赋给__RecordsetPtr的connection成员变量,让它自己创建数据连接。如果要使用多个记录集,最好的方法是同Command对象一样使用已经创建了数据连接的全局—ConnectionPtr接口,然后使用__Recordse7tPtr执行存储过程和SQL语句。
6、24 使用ADO访问数据库
__ConnectionPtr是一个连接接口,首先创建一个__ConnectionPtr接口实例,接着指向并打开一个ODBC数据源或OLE DB数据提供者(Provider)。以下代码分别创建一个基于DSN和非DSN的数据连接。
//使用__ConnectionPtr(基于DSN)
__ConnectionPtr MyDb;
MyDb.CreateInstance(__uuidof(Connection));
MyDb-〉Open("DSN=samp;UID=admin;PWD=admin","","",-1);
//使用—ConnectionPtr (基于非DSN)
__ConnectionPtr MyDb;
MyDb.CreateInstance(__uuidof(Connection));
MyDb.Open("Provider=SQLOLEDB;SERVER=server;DATABASE=samp;UID=admin;PWD=admin","","",-1);
//使用__RecordsetPtr执行SQL语句
__RecordsetPtr MySet;
MySet.CreateInstance(__uuidof(Recordset));
MySet-〉Open("SELECT *_ FROM some__table",
MyDb.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
现在我们已经有了一个数据连接和一个记录集,接下来就可以使用数据了。从以下代码可以看到,使用ADO的__RecordsetPtr接口,就不需要像DAO那样频繁地使用大而复杂的数据结构VARIANT,并强制转换各种数据类型了,这也是ADO的优点之一。假定程序有一个名称为m__List的ListBox控件,下面代码我们用__RecordsetPtr接口获取记录集数据并填充这个ListBox控件:
__variant__t Holder
try{while(!MySet-〉adoEOF)
{ Holder = MySet-〉GetCollect("FIELD__1");
if(Holder.vt!=VT__NULL)
m__List.AddString((char_)__bstr__t(Holder));
MySet-〉MoveNext();} }
catch(__com__error _ e)
{ CString Error = e-〉ErrorMessage();
AfxMessageBox(e-〉ErrorMessage());
} catch(...)
{ MessageBox("ADO发生错误!");}
必须始终在代码中用try和catch来捕获ADO错误,否则ADO错误会使你的应用程序崩溃。当ADO发生运行错误时(如数据库不存在),OLE DB数据提供者将自动创建一个__com__error对象,并将有关错误信息填充到这个对象的成员变量。
6.25 类型转换
由于COM对象是跨平台的,它使用了一种通用的方法来处理各种类型的数据,因此CString 类和COM对象是不兼容的,我们需要一组API来转换COM对象和C++类型的数据。__vatiant__t和__bstr__t就是这样两种对象。它们提供了通用的方法转换COM对象和C++类型的数据。
6.3 在VB中使用ADO
ADO 提供执行以下操作的方式:
1、连接到数据源。同时,可确定对数据源的所有更改是否已成功或没有发生。
2、指定访问数据源的命令,同时可带变量参数,或优化执行。
3、执行命令。
3、如果这个命令使数据按表中的行的形式返回,则将这些行存储在易于检查、操作或更改的缓存中。
4、适当情况下,可使用缓存行的更改内容来更新数据源。
5、提供常规方法检测错误(通常由建立连接或执行命令造成)。
在典型情况下,需要在编程模型中采用所有这些步骤。但是,由于 ADO 有很强的灵活性,所以最后只需执行部分模块就能做一些有用的工作。
以下元素是 ADO 编程模型中的关键部分:
6.31 连接
通过“连接”可从应用程序访问数据源,连接是交换数据所必需的环境。对象模型使用 Connection 对象使连接概念得以具体化。
“事务”用于界定在连接过程中发生的一系列数据访问操作的开始和结束。ADO 可明确事务中的操作造成的对数据源的更改或者成功发生,或者根本没有发生。如果取消事务或它的一个操作失败,则最终的结果将仿佛是事务中的操作均未发生,数据源将会保持事务开始以前的状态。对象模型无法清楚地体现出事务的概念,而是用一组 Connection 对象方法来表示。ADO 从 OLE DB 提供者访问数据和服务。Connection 对象用于指定专门的提供者和任意参数。
6.32 命令
通过已建立的连接发出的“命令”可以某种方式来操作数据源。一般情况下,命令可以在数据源中添加、删除或更新数据,或者在表中以行的格式检索数据。对象模型用 Command 对象来体现命令概念。使用 Command 对象可使 ADO 优化命令的执行。
参数
通常,命令需要的变量部分即“参数”可以在命令发布之前进行更改。例如,可重复发出相同的数据检索命令,但每一次均可更改指定的检索信息。
参数对与函数活动相同的可执行命令非常有用,这样就可知道命令是做什么的,但不必知道它如何工作。例如,可发出一项银行过户命令,从一方借出贷给另一方。可将要过户的款额设置为参数。
对象模型用 Parameter 对象来体现参数概念。
6.33 记录集
如果命令是在表中按信息行返回数据的查询(行返回查询),则这些行将会存储在本地。
对象模型将该存储体现为 Recordset 对象。但是,不存在仅代表单独一个 Recordset 行的对象。
记录集是在行中检查和修改数据最主要的方法。
6.34 字段
一个记录集行包含一个或多个“字段”。如果将记录集看作二维网格,字段将排列构成“列”。每一字段(列)都分别包含有名称、数据类型和值的属性,正是在该值中包含了来自数据源的真实数据。
对象模型以 Field 对象体现字段。
要修改数据源中的数据,可在记录集行中修改 Field 对象的值,对记录集的更改最终被传送给数据源。作为选项,Connection 对象的事务管理方法能够可靠地保证更改要么全部成功,要么全部失败。
6.35 错误
错误随时可在应用程序中发生,通常是由于无法建立连接、执行命令或对某些状态(例如,试图使用没有初始化的记录集)的对象进行操作。
对象模型以 Error 对象体现错误。
任意给定的错误都会产生一个或多个 Error 对象,随后产生的错误将会放弃先前的 Error 对象组。
6.36 属性
每个 ADO 对象都有一组唯一的“属性”来描述或控制对象的行为。
属性有内置和动态两种类型。内置属性是 ADO 对象的一部分并且随时可用。动态属性则由特别的数据提供者添加到 ADO 对象的属性集合中,仅在提供者被使用时才能存在。
对象模型以 Property 对象体现属性。
6.37 集合
ADO 提供“集合”,这是一种可方便地包含其他特殊类型对象的对象类型。使用集合方法可按名称(文本字符串)或序号(整型数)对集合中的对象进行检索。
ADO 提供四种类型的集合:
Connection 对象具有 Errors 集合,包含为响应与数据源有关的单一错误而创建的所有 Error 对象。
Command 对象具有 Parameters 集合,包含应用于 Command 对象的所有 Parameter 对象。
Recordset 对象具有 Fields 集合,包含所有定义 Recordset 对象列的 Field 对象。
此外,Connection、Command、Recordset 和 Field 对象都具有 Properties 集合。它包含所有属于各个包含对象的 Property 对象。
ADO 对象拥有可在其上使用的诸如“整型”、“字符型”或“布尔型”这样的普通数据类型来设置或检索值的属性。然而,有必要将某些属性看成是数据类型“COLLECTION OBJECT”的返回值。相应的,集合对象具有存储和检索适合该集合的其他对象的方法。
6.38 事件
ADO 2.0 支持事件,事件是对某些操作将要或已经发生的通知。
有两类事件:ConnectionEvent 和 RecordsetEvent。Connection 对象产生 ConnectionEvent 事件,而 Recordset 对象则产生 RecordsetEvent 事件。
事件由事件处理程序例程处理,该例程在某个操作开始之前或结束之后被调用。
某些事件是成对出现的。开始操作前调用的事件名格式为 WillEvent(Will 事件),而操作结束后调用的事件名格式为 EventComplete(Complete 事件)。其余的不成对事件只在操作结束后发生。(其名称没有任何固定模式。)事件处理程序由状态参数控制。附加信息由错误和对象参数提供。
可以请求事件处理程序不接受第一次通知以后的任何通知。例如,可以选择只接收 Will 事件或 Complete 事件。
下面的代码显示了一个使用ADO的例子。
首先加入Microsoft ActiveX Data Object 2.0 Library引用。
Dim db As Connection
Set db = New Connection
db.CursorLocation = adUseClient
db.Open "PROVIDER=MSDASQL;DSN=TestDatabase", "sa", "", -1
Dim i As Long
Dim id As Long
Dim value As Single
Dim rst As New Recordset
Set rst = New Recordset
rst.Open "select * from 模拟量变化历史表", db, adOpenDynamic, adLockOptimistic
rst.MoveFirst
For i = 0 To rst.RecordCount - 1
id = rst.Fields("ID")
value=rst.Fields(“VALUE”)
rst.MoveNext
Next i
rst.Close
Set rst = Nothing
db.Close
6.4总结
ADO技术是访问数据库的新技术,具有易于使用、访问灵活、应用广泛的特点。用ADO访问数据源的特点可总结如下:
易于使用
这是ADO技术的最重要的一个特征。由于ADO是高层应用,所以相对于OLE DB或者ODBC来说,它具有面向对象的特性。同时,在ADO的对象结构中,其对象之间的层次关系并不明显。相对于DAO等访问技术来讲,又不必关心对象的构造顺序和构造层次。对于要用的对象,不必选建立连接、会话等对象,只需直接构造即可,方便了应用程序的编制。
高速访问数据源
由于ADO技术基于OLE DB,所以,它也继承了OLE DB访问数据库的高速性。
可以访问不同数据源
ADO技术可以访问包括关系数据库和非关系数据库的所有文件系统。此特点使应用程序有很多的灵活性和通用性。
可以用于Microsoft ActiveX页
ADO技术可以以ActiveX控件的形式出现,所以,可以被用于Microsoft ActiveX页,此特征可简化WEB页的编程。
程序占用内存少
由于ADO是基于组件对象模型(COM)的访问技术,所以,用ADO产生的应用程序占用内存少。
7、总结
要在访问数据时判断出应该使用哪一种技术,这并不容易。可能需要公用实用程序来处理多个数据库类型;部分数据可能出现在本地硬盘驱动器上,部分在网络上,还有一部分在主机上。甚至客户安装在设备上的产品也会使这种选择更加困难。例如,你所期待的ODBC支持级别也许依赖于所安装的Microsoft Office的版本,因为这个产品不提供ODBC支持。你还会发现,ADO类提供的对象和方法要比ODBC类多。ADO可以提供程序中绝对必须具有的一些特性枣例如,你会发现OLE-DB和ADO两者都支持DFX_Currency,但在ODBC中没有对应的功能,但你要想掌握它们也必须付出一定的努力。
选择OLE-DB或ODBC时,有几条一般的规则。因为ADO实际上只是OLE-DB的包装,所以这些规则也适用于它。下面提供一些基本的原则,可以用来帮助你决定选择OLE-DB还是ODBC。
非OLE环境 如果要访问支持ODBC的数据库,而该数据库又在不支持OLE的服务器上,那么ODBC是最好的选择。
非SQL环境 ODBC在处理SQL时非常出众。处理非SQL数据库时,OLE-DB则具有非常明显的优势。
OLE环境 对支持OLE的服务器来说,选择OLE-DB还是ODBC也许是希望各半。如果有ODBC驱动程序可供利用,那么使用ODBC是一个好主意;否则,就只有选择OLE-DB了。
所需的互操作性 如果需要可互操作的数据库部件,那么只有选择OLE-DB。

使用ADO.NET设计数据库应用程序

   认识ADO和ADO Net     ActiveX Data Object(简称ADO)是微软提供的数据访问模型 依据这个模型可很轻松的操作数据库 同时ADO受到微软所以开发工具的支持 所以无论是VB VC ASP开发都可以使用 所以开发ASP数据库应用程序 只需在代码中嵌入SQL(结构化查询语言)命令 用户就可以很轻松的输入 更新 和删除后台的数据库记录 当用户端的浏览器填好表单所要求输入的资料并按下 Submit(确认) 按钮后 经过互联网 内联网传送HTTP请求到WEB服务器 该请求在WEB服务器执行一个表单所指定的Active Server Pages程序(后缀名为 ASP的文档)     从ADO Net不仅仅是ADO的一个简单升级 它是微软 NET战略的一个重要组成部分 那么到底和以前有什么不同呢?现在就让本文来告诉你     以前在ADO中进行数据处理的主要方法是OLEDB 现在在ADO Net中也是如此 但是微软为了更好地支持目前广泛使用的两个数据库Oracle和SQL Server对OLEDB做了专门的扩展 它们分别是OracleClient和SQLClient 类 当然由于数据库产品很多 为了便于以前的OLEDB的程序升级 故也对OLEDB本身做了升级处理 在 Net中表现为OLEDB类     那么这三个类——OLEDB OracleClient和SQLClient在编程使用上到底有什么不同呢?值得庆幸的是在 Net中进行数据库的编程时 不管你使用上面提到的 个类中的哪一个类 这 个类在语法和用法上都大同小异 可以用一通百通来形容      怎样学习ADO Net技术     笔者在学习和使用了ADO Net编程后 总结出下面 个必需的步骤 而且这 个步骤的顺序是绝对不可以调换的 如果在以后的编程中发现 个步骤的顺序换了或缺了一个步骤 那么你的代码肯定是错的      使用对应类中的连接方法来连接数据库 如使用SQLClient类 那么就用SqlConnection 建立数据库的链接      打开此链接      执行对应类中的命令方法来指定要执行的SQL语句 如使用SQLClient类就使用SqlCommand执行指定的SQL语句     下面举出的两个例子就是在 Net中使用ADO Net编程的代码 由于SQL Server 在使用中比Oracle简单 所以这里的数据库使用Microsoft的SQL Server 原因是它在安装后无须配置就可以直接使用 既然访问的是SQL Server 那么使用的类当然是SQLClient类 这两个例子是      在数据库中对数据进行添加 删除 修改      利用ADO技术建立一个SQL Server 的数据库     例 一    启动SQL Server 然后建立一个数据库和一个表 并且在表中一定要有主键 随便输入一些数据 完成后保存此表     本文使用的表结构如下   

 

  表名 使用系统默认的表名table     然后打开VS Net建立一个新的工程 并从工具箱中将 SqlDataAdapter 控件拖动到窗口底部 随后 数据适配器配置向导 窗口会自动运行 按照向导提示完成操作(如图)   

 

  需要注意的是 在出现的 生成SQL语句 窗口中要输入标准的select语句 在本例中我们将从表Table 中返回id和d这两列 所以应该输入 SELECT id d FROM Table 语句 当然单击 查询生成器 按钮系统也可以自动生成这条语句     当完成 数据适配器配置向导 后 你会在窗口的底部发现系统自动添加了 SqlConnection 接下来右击 SqlDataAdapter 在快捷菜单中选择 生成数据集 随后可以看见 生成数据集 设置窗口 保持默认设置并单击 确定 现在又会发现在设计窗口下多了一个 Dataset     到此为止 就差最后一个控键 SqlCommand 我们只要在工具栏中将它拖放过来并修改其属性的 Connection 设置为 SqlConnection 并在 CommandText 属性中利用 查询生成器 为其生成select语句即可 到现在为止 我们就完成了ADO Net访问数据库的一大半了     网格是显示数据的最好方法 为了让数据显示在网格中我们需要添加此控件并且修改其属性 添加的方法就是直接从工具箱中将它拖过来即可 不过它的属性设置倒是很简单 只要将 Datasource 设置为 Dataset table 即可 table是表示表的名字     最后添加两行代码即可完成对数据的添加 删除 修改的操作     在Form _Load部分加入 Sql DataAdapter FillDataSet  ″Table ″ 代码     Private Sub Form _LoadByVal sender As System Object ByVal e As System EventArgs Handles MyBase Load  SqlDataAdapter FillDataSet  ″Table ″ 将表中的数据添加到DataSet 中   End Sub    添加一个Button 在Button _Click中加入 SqlDataAdapter UpdateDataSet  ″Table ″ 代码     Private Sub Button _ClickByVal sender As System Object ByVal e As System EventArgs Handles Button Click  SqlDataAdapter UpdateDataSet ″Table ″ 完成数据库的添加 删除 修改功能   End Sub    程序说明 其中SqlDataAdapter Fil语句是把表中具体的数据添入DataSet 后 而SqlDataAdapter Update是表示当完成对数据的修改后使用Update进行数据库的更新 使修改的数据生效 按 F 运行程序 你就可以看见表中的数据都显示出来了 同时你可以随意对它们进行修改 如要删除数据 只要按下键盘上的 del 键即可     例一中使用控件的简单介绍   

  lishixinzhi/Article/program/net/201311/13743

VC++中使用ADO操作ACCESS数据库


ADO(ActiveX Data Object)是Microsoft数据库应用程序开发的新接口,是建立在OLE DB之上的高层数据库访问技术,即使你对OLE DB,COM不了解也能轻松对付ADO,因为它非常简单易用,甚至比你以往所接触的ODBC API、DAO、RDO都要容易使用,并不失灵活性。本文详细地介绍在Visual C++开发环境下如何使用ADO来进行数据库应用程序开发,并给出示例代码。为了使读者朋友都能测试本例提供的代码,我们采用Access数据库,您可以直接在我们提供的示例代码中找到这个test.mdb。程序编译运行后的效果如图一所示:
一、实现方法
万事开头难,任何一种新技术对于初学者来说最重要的还是"入门",掌握其要点。让我们来看看ADO数据库开发的基本流程吧!它的基本步骤如下:
(1)初始化COM库,引入ADO库定义文件
(2)用Connection对象连接数据库
(3)利用建立好的连接,通过Connection、Command对象执行SQL命令,或利用Recordset对象取得结果记录集进行查询、处理。
(4)使用完毕后关闭连接释放对象。
下面我们将详细介绍上述步骤并给出相关代码。
1、COM库的初始化
我们可以使用AfxOleInit()来初始化COM库,这项工作通常在CWinApp::InitInstance()的重载函数中完成,请看如下代码:
BOOL CADOTest1App::InitInstance()
{
AfxOleInit();
......
}
2、用#import指令引入ADO类型库
为了引入ADO类型库,需要在项目的stdafx.h文件中加入如下语句:
#import "c:program filescommon filessystemadomsado15.dll"
no_namespace rename("EOF","adoEOF")
这一语句有何作用呢?其最终作用同我们已经十分熟悉的#include类似,编译的时候系统会为我们生成msado15.tlh,ado15.tli两个C++头文件来定义ADO库。
需要读者朋友注意的是:您的开发环境中msado15.dll不一定在这个目录下,请按实际情况修改;在编译的时候可能会出现如下警告,对此微软在MSDN中作了说明,并建议我们不要理会这个警告:msado15.tlh(405) : warning C4146: unary minus operator applied to unsigned type, result still unsigned。
3、创建Connection对象并连接数据库
为了首先我们需要添加一个指向Connection对象的指针_ConnectionPtr m_pConnection,下面的代码演示了如何创建Connection对象实例及如何连接数据库并进行异常捕捉:
BOOL CADOTest1Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
HRESULT hr;
try
{
hr = m_pConnection.CreateInstance("ADODB.Connection");///创建Connection对象
if(SUCCEEDED(hr))
{
hr = m_pConnection-Open("Provider=Microsoft.Jet.OLEDB.4.0;
Data Source=test.mdb","","",adModeUnknown);///连接数据库
//上面一句中连接字串中的Provider是针对ACCESS2000环境的,对于ACCESS97,
//需要改为:Provider=Microsoft.Jet.OLEDB.3.51;
}
}
catch(_com_error e)///捕捉异常
{
CString errormessage;
errormessage.Format("连接数据库失败! 错误信息:%s",e.ErrorMessage());
AfxMessageBox(errormessage);///显示错误信息
}
在这段代码中我们是通过Connection对象的Open方法来进行连接数据库的,下面是该方法的原型:
HRESULT Connection15::Open ( _bstr_t ConnectionString, _bstr_t UserID, _bstr_t Password, long Options );
上述函数中参数ConnectionString为连接字串;参数UserID是用户名;参数Password是登陆密码;参数Options是连接选项,用于指定Connection对象对数据的更新许可权,一般情况下Options可以是如下几个常量:
adModeUnknown:缺省。当前的许可权未设置
adModeRead:只读
adModeWrite:只写
adModeReadWrite:可以读写
adModeShareDenyRead:阻止其它Connection对象以读权限打开连接
adModeShareDenyWrite:阻止其它Connection对象以写权限打开连接
adModeShareExclusive:阻止其它Connection对象以读写权限打开连接
adModeShareDenyNone:阻止其它Connection对象以任何权限打开连接
我们给出一些常用的连接方式供大家参考:
(1)通过JET数据库引擎对ACCESS2000数据库的连接:
m_pConnection-Open("Provider=Microsoft.Jet.OLEDB.4.0;
Data Source=C:est.mdb","","",adModeUnknown);
(2)通过DSN数据源对任何支持ODBC的数据库进行连接:
m_pConnection-Open("Data Source=adotest;UID=sa;PWD=;","","",adModeUnknown);
(3)不通过DSN对SQL SERVER数据库进行连接:
m_pConnection-Open("driver={SQL Server};Server=127.0.0.1;DATABASE=vckbase;
UID=sa;PWD=139","","",adModeUnknown);
其中Server是SQL服务器的名称,DATABASE是库的名称。
Connection对象除Open()方法外还有许多方法,我们先介绍Connection对象中两个有用的属性ConnectionTimeOut与State。ConnectionTimeOut用来设置连接的超时时间,需要在Open之前调用,例如:
m_pConnection-ConnectionTimeout = 5;///设置超时时间为5秒
m_pConnection-Open("Data Source=adotest;","","",adModeUnknown);
State属性指明当前Connection对象的状态,0表示关闭,1表示已经打开,我们可以通过读取这个属性来作相应的处理,例如:
if(m_pConnection-State)
m_pConnection-Close(); ///如果已经打开了连接则关闭它
4、执行SQL命令并取得结果记录集
为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset"),SQL命令的执行可以采用多种形式,下面我们一一进行阐述。
(1)利用Connection对象的Execute方法执行SQL命令
Execute()方法的原型如下所示:
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options )
其中CommandText是命令字串,通常是SQL命令。参数RecordsAffected是操作完成后所影响的行数, 参数Options表示CommandText中内容的类型,Options可以取如下值之一:adCmdText表明CommandText是文本命令;adCmdTable表明CommandText是一个表名;adCmdProc表明CommandText是一个存储过程;adCmdUnknown表明CommandText内容未知。Execute()函数执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明:
_variant_t RecordsAffected;
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday
m_pConnection-Execute("CREATE TABLE users(ID INTEGER,username
TEXT,old INTEGER,birthday DATETIME)",RecordsAffected,adCmdText);
///往表格里面添加记录
m_pConnection-Execute("INSERT INTO users(ID,username,old,birthday)
VALUES (1, ’Washington’,25,’1970/1/1’)",RecordsAffected,adCmdText);
///将所有记录old字段的值加一
m_pConnection-Execute("UPDATE users SET old = old+1",RecordsAffected,adCmdText);
///执行SQL统计命令得到包含记录条数的记录集
m_pRecordset = m_pConnection-Execute("SELECT COUNT(*) FROM
users",RecordsAffected,adCmdText);
_variant_t vIndex = (long)0;
_variant_t vCount = m_pRecordset-GetCollect(vIndex);///取得第一个字段的值放入vCount变量
m_pRecordset-Close();///关闭记录集
CString message;
message.Format("共有%d条记录",vCount.lVal);
AfxMessageBox(message);///显示当前记录条数(2)利用Command对象来执行SQL命令
_CommandPtr m_pCommand;
m_pCommand.CreateInstance("ADODB.Command");
_variant_t vNULL;
vNULL.vt = VT_ERROR;
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
m_pCommand-ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
m_pCommand-CommandText = "SELECT * FROM users";///命令字串
m_pRecordset = m_pCommand-Execute(vNULL,vNULL,adCmdText);
//执行命令取得记录集
在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
(3)直接用Recordset对象进行查询取得记录集,例如:
m_pRecordset-Open("SELECT * FROM users",_variant_t((IDispatch *)m_pConnection,true),
adOpenStatic,adLockOptimistic,adCmdText);
Open()方法的原型如下:
HRESULT Recordset15::Open ( const _variant_t
Source, const _variant_t
ActiveConnection, enum CursorTypeEnum CursorType, enum LockTypeEnum LockType, long Options )
上述函数中参数Source是数据查询字符串;参数ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象);参数CursorType光标类型,它可以是以下值之一;请看这个枚举结构:
enum CursorTypeEnum
{
adOpenUnspecified = -1,///不作特别指定
adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
};
参数LockType表示数据库的锁定类型,它可以是以下值之一,请看如下枚举结构:
enum LockTypeEnum
{
adLockUnspecified = -1,///未指定
adLockReadOnly = 1,///只读记录集
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
adLockBatchOptimistic = 4,乐观分批更新。时记录不会锁定,更改、插入及删除是在批处理模式下完成。
};
参数Options的含义请参考本文中对Connection对象的Execute()方法的介绍。
5、记录集的遍历、更新
根据我们刚才通过执行SQL命令建立好的users表,它包含四个字段:ID,username,old,birthday
以下的代码实现:打开记录集,遍历所有记录,删除第一条记录,添加三条记录,移动光标到第二条记录,更改其年龄数据,保存到数据库。
_variant_t vUsername,vBirthday,vID,vOld;
_RecordsetPtr m_pRecordset;
m_pRecordset.CreateInstance("ADODB.Recordset");
m_pRecordset-Open("SELECT * FROM users",_variant_t((IDispatch*)m_pConnection,true),
adOpenStatic,adLockOptimistic,adCmdText);
while(!m_pRecordset-adoEOF)
///这里为什么是adoEOF而不是EOF呢?还记得rename("EOF","adoEOF")这一句吗?
{
vID = m_pRecordset-GetCollect(_variant_t((long)0));///取得第1列的值,从0开始计数,你也可以直接给出列的名称;
vUsername = m_pRecordset-GetCollect("username");///取得username字段的值
vOld = m_pRecordset-GetCollect("old");
vBirthday = m_pRecordset-GetCollect("birthday");
///在DEBUG方式下的OUTPUT窗口输出记录集中的记录
if(vID.vt != VT_NULL
vUsername.vt != VT_NULL
vOld.vt != VT_NULL
vBirthday.vt != VT_NULL)
TRACE("id:%d,姓名:%s,年龄:%d,生日:%s ",vID.lVal,(LPCTSTR)(_bstr_t)vUsername,vOld.lVal,(LPCTSTR)(_bstr_t)vBirthday);
m_pRecordset-MoveNext();///移到下一条记录
}
m_pRecordset-MoveFirst();///移到首条记录
m_pRecordset-Delete(adAffectCurrent);///删除当前记录
///添加三条新记录并赋值
for(int i=0;i3;i++)
{
m_pRecordset-AddNew();///添加新记录
m_pRecordset-PutCollect("ID",_variant_t((long)(i+10)));
m_pRecordset-PutCollect("username",_variant_t("叶利钦"));
m_pRecordset-PutCollect("old",_variant_t((long)71));
m_pRecordset-PutCollect("birthday",_variant_t("1930-3-15"));
}
m_pRecordset-Move(1,_variant_t((long)adBookmarkFirst));///从第一条记录往下移动一条记录,即移动到第二条记录处
m_pRecordset-PutCollect(_variant_t("old"),_variant_t((long)45));///修改其年龄
m_pRecordset-Update();///保存到库中
6、关闭记录集与连接
记录集或连接都可以用Close()方法来关闭:
m_pRecordset-Close();///关闭记录集
m_pConnection-Close();///关闭连接
至此,我想读者朋友已经熟悉了ADO操作数据库的大致流程,也许您已经胸有成竹,也许您还有点胡涂,不要紧!建议你尝试写几个例子,这样会更好地熟悉ADO,最后我给大家写了一个小例子,例子实现的功能是读出所有记录并放到列表控件中,同时可以添加、删除、修改记录。
二、编程步骤
1、 启动Visual C++6.0,生成一个基于对话框的应用程序,将该程序命名为ADOTest1;
2、 在对话框界面上放置显示记录列表控件和添加、删除记录用的的、按钮控件,具体设置参加代码中的对话框资源部分;
3、 使用Class Wizard为添加、修改数据库记录的按钮添加消息响应函数;
4、 添加成程序代码,编译运行程序。

在Visual C++中用ADO进行数据库编程


1. 生成应用程序框架并初始化OLE/COM库环境
创建一个标准的MFC AppWizard(exe)应用程序,然后在使用ADO数据库的InitInstance函数中初始化OLE/COM库(因为ADO库是一个COM DLL库)。
本例为:
BOOL CAdotestDlg::OnInitDialog()
{
}
程序最后要调用 ::CoUninitialize();//释放程序占用的COM 资源。
另外:
m_pRecordset-Close(); 注意!!!不要多次关闭!!!!!!!!!!!!
m_pConnection-Close();
m_pRecordset = NULL;
m_pConnection = NULL;
2. 引入ADO库文件
使用ADO前必须在工程的stdafx.h文件最后用直接引入符号#import引入ADO库文件,以使编译器能正确编译。代码如下:
#import "C:Program Filescommon filessystemadomsado15.dll" no_namespace rename("EOF","adoEOF")
ADO类的定义是作为一种资源存储在ADO DLL(msado15.dll)中,在其内部称为类型库。类型库描述了自治接口,以及C++使用的COM vtable接口。当使用#import指令时,在运行时Visual C++需要从ADO DLL中读取这个类型库,并以此创建一组C++头文件。这些头文件具有。tli 和。tlh扩展名,读者可以在项目的目录下找到这两个文件。在C++程序代码中调用的ADO类要在这些文件中定义。
程序的第三行指示ADO对象不使用名称空间。在有些应用程序中,由于应用程序中的对象与ADO中的对象之间可能会出现命名冲突,所以有必要使用名称空间。如果要使用名称空间,则可把第三行程序修改为: rename_namespace("AdoNS")。第四行代码将ADO中的EOF(文件结束)更名为adoEOF,以避免与定义了自己的EOF的其他库冲突。
3.利用智能指针进行数据库操作
在CaboutDlg头文件中定义两个ADO智能指针类实例,并在对话框中加入一个ListCtrl.
class CAdotestDlg : public CDialog
{
_ConnectionPtr m_pConnection;
_RecordsetPtr m_pRecordset;
ClistCtrl m_List;
}
ADO库包含三个智能指针:_ConnectionPtr、_CommandPtr和_RecordsetPtr.
_ConnectionPtr通常被用来创建一个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。
_CommandPtr返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和SQL语句。在使用_CommandPtr接口时,可以利用全局_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。 _RecordsetPtr是一个记录集对象。与以上两种对象相比,它对记录集提供了更多的控制功能,如记录锁定、游标控制等。
在使用ADO程序的事件响应中OnButton1加入以下代码:
void CAdotestDlg::OnButton1()
{
m_List.ResetContent();
m_pConnection.CreateInstance(_uuidof(Connection)); //初始化Connection指针
m_pRecordset.CreateInstance(_uuidof(Recordset));//初始化Recordset指针
try
{
m_pConnection-Open("DSN=ADOTest","","",0); //连接叫作ADOTest的ODBC数据源
//注意:这是连接不需要用户ID或密码的open 函数
// 否则形式为 -Open("DSN=test;uid=sa;pwd=123;","","",0);
// 执行SQL语句得到一个记录集把其指针赋值给m_pRecordset
CString strSql="select * from middle";
BSTR bstrSQL = strSql.AllocSysString();
m_pRecordset-Open(bstrSQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,
adCmdText);
//adOpenDynamic:动态 adLockOptimistic乐观封锁法 adCmdText:文本查询语句
while(!m_pRecordset-adoEOF)//遍历所有记录
{
//取纪录字段值方式之一
_variant_t TheValue; //VARIANT数据类型
TheValue = m_pRecordset-GetCollect("BIG_NAME");//得到字段BIG_NAME的值
if(TheValue.vt!=VT_NULL)
m_List.AddString((char*)_bstr_t(TheValue));
//将该值加入到列表控件中
//取纪录字段值方式之二
// _bstr_t TheValue1=m_pRecordset-Fields-GetItem("BIG_NAME")-Value;
// CString temp=TheValue1.copy();
// m_List.AddString(temp);
//数据类型转换
_variant_t vUsername,vBirthday,vID,vOld;
TRACE("id:%d,姓名:%s,年龄:%d,生日:%s",
vID.lVal,(LPCTSTR)(_bstr_t)vUsername,vOld.lVal,(LPCTSTR)(_bstr_t)vBirthday);
m_pRecordset-MoveNext();//转到下一条纪录
}
m_pRecordset-Close();
m_pConnection-Close();
}
catch (_com_error e)//异常处理
{
AfxMessageBox(e.ErrorMessage());
}
m_pRecordset-Close(); //注意!!!不要多次关闭!!!!否则会出错
m_pConnection-Close();
m_pRecordset = NULL;
m_pConnection = NULL;
}
程序中通过_variant_t和_bstr_t转换COM对象和C++类型的数据, _variant_t类封装了OLE自治VARIANT数据类型。在C++中使用_variant_t类要比直接使用VARIANT数据类型容易得多。
好,编译后该程序就能运行了,但记住运行前要创建一个叫ADOTest的ODBC数据源。该程序将把表middle中的BIG_NAME字段值显示在列表控件中。
4.执行SQL命令并取得结果记录集
为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");
SQL命令的执行可以采用多种形式,下面我们一进行阐述。
(1)利用Connection对象的Execute方法执行SQL命令
Execute方法的原型如下所示:
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected,
long Options )
其中CommandText是命令字串,通常是SQL命令。
参数RecordsAffected是操作完成后所影响的行数,
参数Options表示CommandText中内容的类型,Options可以取如下值之一:
adCmdText:表明CommandText是文本命令
adCmdTable:表明CommandText是一个表名
adCmdProc:表明CommandText是一个存储过程
adCmdUnknown:未知
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
_variant_t RecordsAffected;
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,
整形old,日期型birthday
m_pConnection-Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday
DATETIME)",
RecordsAffected,
adCmdText);
///往表格里面添加记录
m_pConnection-Execute("INSERT INTO users(ID,username,old,birthday) VALUES
(1, ’’’’Washington’’’’,25,’’’’1970/1/1’’’’)",RecordsAffected,adCmdText);
///将所有记录old字段的值加一
m_pConnection-Execute("UPDATE users SET old = old+1",RecordsAffected,adCmdText);
///执行SQL统计命令得到包含记录条数的记录集
m_pRecordset = m_pConnection-Execute("SELECT COUNT(*) FROM users",RecordsAffected,adCmdText);
_variant_t vIndex = (long)0;
_variant_t vCount = m_pRecordset-GetCollect(vIndex);///取得第一个字段的值放入vCount变量
上两句可以写成- _variant_t vCount = m_pRecordset-GetCollect((_variant_t)((long)0));
m_pRecordset-Close();///关闭记录集
CString message;
message.Format("共有%d条记录",vCount.lVal);
AfxMessageBox(message);///显示当前记录条数
(2)利用Command对象来执行SQL命令
_CommandPtr m_pCommand;
m_pCommand.CreateInstance("ADODB.Command");
_variant_t vNULL;
vNULL.vt = VT_ERROR;
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
m_pCommand-ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
m_pCommand-CommandText = "SELECT * FROM users";///命令字串
m_pRecordset = m_pCommand-Execute(vNULL,vNULL,adCmdText);///执行命令,取得记录集
在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
(3)直接用Recordset对象进行查询取得记录集
实例--
void CGmsaDlg::OnDBSelect()
{
// TODO: Add your control notification handler code here
_RecordsetPtr Rs1; //定义Recordset对象
_bstr_t Connect("DSN=GMS;UID=sa;PWD=;");//定义连接字符串
_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句
HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );
//省略对返回值hr的判断
Rs1-Open( Source,
Connect,
adOpenForwardOnly,
adLockReadOnly,
-1 );
_variant_t temp=Rs1-GetCollect(_variant_t((long)0));
CString strTemp=(char* )(_bstr_t)temp;
MessageBox("OK!"+strTemp);
}
例如
m_pRecordset-Open("SELECT * FROM users",
_variant_t((IDispatch *)m_pConnection,true),
adOpenStatic,
adLockOptimistic,
adCmdText);
Open方法的原型是这样的:
HRESULT Recordset15::Open ( const _variant_t
Source,
const _variant_t
ActiveConnection,
enum CursorTypeEnum CursorType,
enum LockTypeEnum LockType,
long Options )
其中:
①Source是数据查询字符串
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:
enum CursorTypeEnum
{
adOpenUnspecified = -1,///不作特别指定
adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方
式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操
作对你是可见的。
adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你
的记录集来说是不可见的。
};
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:
enum LockTypeEnum
{
adLockUnspecified = -1,///未指定
adLockReadOnly = 1,///只读记录集
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做
数据的更新、插入、删除等动作
adLockBatchOptimistic = 4,乐观分批更新。时记录不会锁定,更改、插入及删除是在批处理模
式下完成。
};
⑤Options可以取如下值之一:
adCmdText:表明CommandText是文本命令
adCmdTable:表明CommandText是一个表名
adCmdProc:表明CommandText是一个存储过程
adCmdUnknown:未知
5. 记录集的遍历、更新
根据我们刚才通过执行SQL命令建立好的users表,它包含四个字段:ID,username,old,birthday
以下的代码实现:打开记录集,遍历所有记录,删除第一条记录,添加三条记录,移动光标到第二条记录,
更改其年龄,保存到数据库。
_variant_t vUsername,vBirthday,vID,vOld;
_RecordsetPtr m_pRecordset;
m_pRecordset.CreateInstance("ADODB.Recordset");
m_pRecordset-Open("SELECT * FROM users",
_variant_t((IDispatch*)m_pConnection,true),
adOpenStatic,
adLockOptimistic,
adCmdText);
while(!m_pRecordset-adoEOF)
{
vID = m_pRecordset-GetCollect(_variant_t((long)0));///取得第1列的值,从0开始计数,
///你也可以直接给出列的名称,如下一行
vUsername = m_pRecordset-GetCollect("username");///取得username字段的值
vOld = m_pRecordset-GetCollect("old");
vBirthday = m_pRecordset-GetCollect("birthday");
///在DEBUG方式下的OUTPUT窗口输出记录集中的记录
if(vID.vt != VT_NULL
vUsername.vt != VT_NULL
vOld.vt != VT_NULL
vBirthday.vt
!= VT_NULL)
TRACE("id:%d,姓名:%s,年龄:%d,生日:%s",
vID.lVal,
(LPCTSTR)(_bstr_t)vUsername,
vOld.lVal,
(LPCTSTR)(_bstr_t)vBirthday);
m_pRecordset-MoveNext();///移到下一条记录
}
m_pRecordset-MoveFirst();///移到首条记录
m_pRecordset-Delete(adAffectCurrent);///删除当前记录
///添加三条新记录并赋值
for(int i=0;i3;i++)
{
m_pRecordset-AddNew();///添加新记录
m_pRecordset-PutCollect("ID",_variant_t((long)(i+10)));
m_pRecordset-PutCollect("username",_variant_t("叶利钦"));
m_pRecordset-PutCollect("old",_variant_t((long)71));
m_pRecordset-PutCollect("birthday",_variant_t("1930-3-15"));
}
m_pRecordset-Move(1,_variant_t((long)adBookmarkFirst));///从第一条记录往下移动一条记录,即移动
到第二条记录处
m_pRecordset-PutCollect(_variant_t("old"),_variant_t((long)45));///修改其年龄
m_pRecordset-Update();///保存到库中
备注:多次查询可把查询过程做成一个函数ExecuteSQL让m_pRecordset获得连接指针m_pConnection查询结果
void ExecuteSQL(_ConnectionPtr m_pConnection, _RecordsetPtr m_pRecordset,CString strSql)
{
//执行Select 语句
BSTR bstrSQL = strSql.AllocSysString();
try
{
m_pRecordset-Open(bstrSQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,
adCmdText);
//adOpenDynamic:动态 adLockOptimistic乐观封锁法 adCmdText:文本查询语句
}
catch(_com_error error)
{
CString errorMessage;
errorMessage.Format("%s",(LPTSTR)error.Description());
AfxMessageBox(errorMessage);
}
}
//出错处理:
3127--没有找到目标表
3092--目标表已经存在
例如:
catch(const _com_error e)
{
AfxMessageBox(e.Description());
long errorCode=e.WCode();
if(3127==errorCode) AfxMessageBox("表不存在");
if(3092==errorCode) AfxMessageBox("表已经存在");
return FALSE;
}

掌握Visual Basic中的ADO数据对象编程


ADO是ActiveX Data Objects 的缩写,是一项新的数据库的存取技术。相对于VB5.0中的DAO他具有更为简化的对象模型,无论是存取本地的还是远程的数据,都提供了一致的接口.就我本人而言,ADO的确比DAO要好用得多。
今天只就ADO的对象模型谈一谈.ADO定义了一个可编程的对象集合.
ADO对象模型如图所示:
对于ADO其中对象来说,我觉得比较重要的是:Command,Connection,Recordset对象。
虽然严格的说这是不准确的,但根据我的实际经验确实如此.下面就分别来谈一下。
(1) Connection对象
Connection对象用于建立与数据库的连接.通过连接可从应用程序访问数据源.它保存诸如指针类型,连接字符串,查询超时,连接超时和缺省数据库这样的连接信息.
(2) Command对象
在建立Connection后,可以发出命令操作数据源.一般情况下,Command对象可以在数据库中添加,删除或更新数据,或者在表中进行数据查询.Command对象在定义查询参数或执行一个有输出参数的存储过程时非常有用。
(3) Recordset对象
Recordset对象只代表一个记录集,这个记录集是一个连接的数据库中的表,或者是Command对象的执行结果返回的记录集.在ADO对象模型中,是在行中检查和修改数据的最主要的方法,所有对数据的操作几乎都是在Recordset对象中完成的.Record对象用于指定行,移动行,添加,更改,删除记录。
下面就具体地说说如何用ADO存取数据:
在实际编程过程中使用ADO的一个典型的存取数据的步骤为:
(1) 连接数据源
(2) 打开记录集对象
(3) 使用记录集
(4) 断开连接
那么具体怎么是用呢?分别来看。(我在最后将给出一个完整的使用ADO的实例给大家参考.)
(1) 如何连接数据源
利用Connection对象可以创建一个数据源的连接.应用的方法是Connection对象的Open方法。
语法:
Connection对象.Open ConnectionString, UserID, PassWord, OpenOptions
其中:
·Connection对象为你定义的Connection对象的实例;
·ConnectionString为可选项,包含了连接的数据库的信息;
·UserID 可选项,包含建立连接的用户名;
·PassWord为可选项,包含建立连接的用户密码;
·OpenOptions为可选项,假如设置为adConnectAsync,则连接将异步打开.
(2)打开记录集对象
实际上记录集返回的是一个从数据库取回的查询结果集.因此他有两种打开方法:一种使用记录集的Open方法,另一种是用Connection对象的Execute方法。
(a)记录集的Open方法
语法:
Recordset.Open Source, ActiveConnection, CursorType, LockType, Options
其中:
·Recordset为所定义的记录集对象的实例。
·Source可选项,指明了所打开的记录源信息.可以是合法的命令,对象变量名,SQL语句,表名,存储过程调用,或保存记录集的文件名。
·ActiveConnection可选项,合法的已打开的Connection对象的变量名,或者是包含ConnectionString参数的字符串。
·CursorType可选项,确定打开记录集对象使用的指针类型。
·LockType可选项 确定打开记录集对象使用的锁定类型。
(b)Connection对象的Execute方法
语法:
Set recordset=Connection.Execute(CommandText,RecordsAffected,Options)
参数说明:
·CommandText 一个字符串,返回要执行的SQL命令,表名,存储过程或指定文本。
·RecordsAffected 可选项,Long类型的值,返回操作影响的记录数。
·Options 可选项,Long类型值,指明如何处理CommandText参数。
介绍完了如何打开数据库下面说说怎么使用吧.
(3)使用记录集
(a)添加新的记录:
在ADO中添加新的记录用的方法为:AddNew 它的语法为:
Recordset.AddNew FieldList, Values
·Recordset为记录集对象实例
·FieldList为一个字段名,或者是一个字段数组.
·Values为给要加信息的字段赋的值,如果FiledList为一个字段名,那么Values应为一个单个的数值,假如FiledList为一个字段数组,那么 Values必须也为一个个数,类型与FieldList相同的数组。
再用完AddNew方法为记录集添加新的记录后,应使用UpDate将所添加的的数据存储在数据库中.不过你最好在用UpDate方法之前使用CancelUpdate方法来取消该项操作。
(b)修改记录集
其实修改核对记录集中的数据重新赋值没有什么太大的区别,只要用SQL语句将要修改的字段的一个数据找出来重新赋值就可以了.这里不再细说了。
(c)删除记录
在ADO中删除记录集中的数据的方法为:Delete方法,这与DAO对象的方法相同,但是在ADO中它的能力增强了,可以删掉一组记录了.
#p#副标题#e#
它的语法如下:
Recordset.Delete AffectRecords
其中的,AffectRecords参数是确定Delete方法作用的方式的,它的取值如下:
·adAffectCurrent 只删除当前的记录
·adAffectGroup 删除符合Filter属性设置的那些记录.为了一次能删除一组数据,应设置Filter属性.
(d)查询记录
在ADO中查询的方法很灵活,有几种查询的方法.
·使用连接对象的Execute方法执行SQL命令,返回查询记录集.
·使用Command对象的Execute方法执行CommandText属性中设置的SQL命令,返回查询记录集.
第一个方法的具体语法在前面数据连接时已经介绍过了,下面就第二方法具体说一下.
Command对象的Execute方法的语法如下:
Command.Execute RecordsAffected, Parameters, Options ’不返回记录集
或者 Set Rscordset=cmmnad.Execute(RecordsAffected,Parameters,Options) ’返回记录集
CommandText的语法为:
Command.CommandText=stringvariable
其中: stringvariable为字符串变量,包含SQL语句,表名或存储过程.
(4) 断开连接
在应用程序结束之前,应该释放分配给ADO对象的资源,操作系统回收这些资源并可以再分配给其他应用程序。
使用的方法为:Close方法。
语法如下:
Object.Close ’ Object为ADO对象
好了,说了那么多的理论,下面我们就应用一下吧!
#p#副标题#e#

vb ado数据库编程

Dim rs As New ADODB.Recordset ’定义记录集
Dim conn As New ADODB.Connection ’定义数据连接
Private Sub Command1_Click()
rs.Open "insert into CargoManagement (产品ID,产品名称,产品说明,供应商ID,库存量,日期)values(’" & Text1.Text & "’,’" & Text2.Text & "’,’" & Text3.Text & "’,’" & Text4.Text & " ’,’" & Text5.Text & "’,’" & Text6.Text & "’)", conn, adOpenStatic, adLockOptimistic
MsgBox "添加数据成功", vbOKOnly + vbInformation, "系统提示"
Text1.Text = ""
Text2.Text = ""
Text3.Text = ""
Text4.Text = ""
Text5.Text = ""
Text6.Text = ""
End Sub
Private Sub Command2_Click()
rs.Open "delete * from CargoManagement where 产品ID=" & Text1.Text & ""
End Sub
Private Sub Command3_Click()
Dim rs1 As New ADODB.Recordset
rs1.CursorLocation = adUseClient
rs1.Open "select * from CargoManagement", conn, adOpenKeyset, adLockReadOnly ’设置数据源表
Set DataGrid1.DataSource = rs1 ’设置列表数据源
DataGrid1.Refresh ’刷新列表
End Sub
Private Sub Command5_Click()
rs.Open "SELECT * FROM CargoManagement WHERE 产品ID=" & Text1.Text & "", conn, adOpenStatic, adLockOptimistic ’根据条件搜索筛选数据
If rs.RecordCount 》 0 Then ’判断是否有以下内容有就显示搜索内容
Text2.Text = rs!产品名称
Text3.Text = rs!产品说明
Text4.Text = rs!供应商ID
Text5.Text = rs!库存量
Text6.Text = rs!日期
Else
MsgBox "无相关数据", vbOKOnly + vbExclamation, "系统提示"
End If
rs.Close
End Sub
Private Sub Command6_Click()
conn.Execute "update CargoManagement set 产品名称=’" & Trim(Text2.Text) & "’,产品说明=’" & Trim(Text3.Text) & "’,供应商ID=’" & Trim(Text4.Text) & "’,库存量=’" & Trim(Text5.Text) & "’,日期=’" & Trim(Text6.Text) & "’ where 产品ID=" & Text1.Text & ""
End Sub
Private Sub Form_Load()
Text1.Text = ""
Text2.Text = ""
Text3.Text = ""
Text4.Text = ""
Text5.Text = ""
Text6.Text = ""
’所有文本清空
conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;data Source=D:\CargoManagement.mdb"
rs.CursorLocation = adUseClient
rs.Open "select * From CargoManagement", conn, adOpenKeyset, adLockPessimistic
rs.Close
End Sub

在DELPHI程序中使用ADO对象存取ODBC数据库

  作为一个ASP爱好者 笔者经常在ASP页面中使用ADO对象操作ODBC数据库 觉得用ASP创建Web应用系统确实是挺方便的 虽然在编程生涯中 笔者更喜欢Borland系列产品 对微软产品有点排斥 但对ASP却是例外 某天 忽然想到 ADO对象是一个标准OLE对象 如果在Delphi应用程序中能利用ADO操作数据库 应该挺不错 尤其在用DELPHI做网络数据库应用程序时 如果所在的Web站点是WINNT站点并且支持ASP页面 那就可以用ADO对象访问ODBC数据库 而不用把那么大的BDE再上载到站点上去 这样就可充分利用DELPHI和ASP的编程优势 做出更好的ISAPI/NSAPI/CGI 经过编程和测试 在Delphi中可以成功地用ADO对象存取ODBC数据库 现将本人的使用经验写出来 与大家共享 让我们多一个访问ODBC数据库的方法

  在 位的Delphi中 可以声明一个variant变量(如AVariant) 然后通过CreateOleObject创建一个OLE对象 如AVariant:=CreateOleObject ( ADODB Connection )可以获得一个数据库连接对象的实例 然后就可以利用该对象的方法和属性来操作ODBC数据库了   下面简单介绍一下访问ODBC数据库所用到的ADO对象及其方法和属性

   数据库连接对象(ADODB Connection)  该对象用于与ODBC数据库建立连接 所有对数据库的操作均通过该连接进行   数据库连接对象ADODB Connection的作用象Delphi中的TDatabase对象   建立一个连接对象的方法为(AConnection为Variant类型变量) AConnection:=CreateOleObject( A DODB Connection )  用于建立连接的方法为Open 使用语法为(以对象AConnection为例) AConnection Open( ConnectionString UserId Password )  三个参数均为字符串类型 其中UserId和Password为用户名称和用户密码 用于访问数据库使用时可以省略 因为在ConnectionString同样可以指定用户名称和用户密码 ConnectionString是用来说明ODBC数据源信息的字符串 其格式为 Provider=ProviderName; DSN=DSNName; DRIVER=driver; SERVER=server; DATABASE=database; UID=user; PWD=password   其中 Provider 数据提供者 默认状态下为MSDASQL 为微软OLEDB 通常省略 DSN 要打开的数据库对应的OBDC系统数据源(DSN) 是可选参数 DRIVER 要打开的数据库所用的驱动程序名称 如Access对应Microsoft Access Driver (* mdb) 是可选参数 SERVER 要打开的数据库所在的服务器名称 本机可用(local) 是可选参数 DATABASE 要打开的数据库名称 是可选参数 UID 用户名称 用来访问数据库 是可选参数 PWD 用户密码 用来访问数据库 是可选参数   以上参数均为可选参数 但必须提供足够的信息来描述一个系统数据源   假如已经定义了一个ODBC的系统DSN 名称为MyDsn 那么就可用以下语句建立一个数据库连接 AConnection Open( DSN=MyDsn );  为了防止DSN不存在或其设置被他人修改时造成应用程序运行错误 可以用ADODB Connection 创建一个临时ODBC数据源 这样可以保证我们使用的系统DSN的参数设置是正确的 下面的语句可以创建一个临时ODBC系统DSN 对应一个ACCESS数据库 路径为C:\Inetpub\ root\ test mdb AConnection open( Driver= {Microsoft Access Driver (* mdb)};DBQ=C:\inetpub \root\test mdb )  建立一个ADODB Connection后 如果不需要返回操作结果(如删除 修改 更新等操作)就可以对数据库进行正常的SQL操作了 此时应用ADODB Connection的另外一个方法Execute 使用语法为 AConnection Execute( strSQL );  其中strSQL为执行操作的SQL语句 如删除操作可以为 delete from wfjmu 用AConnection Close关闭一个数据库连接    数据集对象(ADODB RecordSet)  如果要执行查询操作并返回查询结果 或者要更方便地操作数据表 那就需要用到数据集对象了   数据集对象ADODB RecordSet的作用象Delphi中的TTable或TQuery对象   建立一个数据集对象的方法为(ARecordSet为Variant类型变量) ARecordSet:=CreateOleObject ( ADODB RecordSet )  从数据表取得数据的方法为Open方法 具体使用方法为 ARecordSet Open( strCommand ActiveConnection int CursorType intLockType intCommandType );  其中 strCommand 字符串 为命令参数 可以是一个Table名称 可以是一个SQL语句 也可以是一个服务器上的存储过程(StoredProc)名称 具体需要后面的参数intCommandType来指定 ActiveConnection 要使用的数据库连接 是一个ADODB Connection对象 intCursorType 长整数 数据集的Cursor类型 可选参数 请参见程序中注释 intLockType 长整数 对数据表的加锁类型 可选参数 请参见程序中注释 intCommandType 长整数 命令参数的类型 用来指明strCommand的作用 可以指定strCommand为命令(如SQL语句)或数据表(TTable)或储存过程(StoredProc) 可选参数 请参见程序中注释   如执行一个SQL查询 可以采用如下语句 ARecordSet Open( Select * from wfjmu adOpenStatic ad LockOptimistic adCmdText);  其它常见属性和方法与TTable和TQuery相比较如下(具体请见ASP帮助文件) eof bof: eof bof.MoveFirst MoveLast: First LastMovePrevious MoveNext: Prior NextMove: MoveByAddNew: appendUpdate: PostClose: close   Delete加Update delete 所有对数据表的修改均须用Update使操作有效 这与Delphi不同 Fields: FieldByName( FieldName )   其他常见对象(与Delphi对应的对象) ADODB Field: TField ADODB Parameter: TPara ADODB Error: EDBEngineErrorADODB Command 无 ADODB Property 无  下面来看一个应用例子 procedure TForm Button Click(Sender: TObject);{*****************************************************用ADO操作ODBC数据库  本程序中 将创建一个临时的ODBC系统数据源 指向一个MsAccess数据库 然后对其中的数据表进行显示 增加 修改 删除和查询操作注意 请在Uses语句中包含ComObj单元*****************************************************}const{一些常量声明 详细请参见adovbs inc}{ CommandType的常量说明 }adCmdUnknown = ;//未知 需要系统来判断 速度慢 为缺省值adCmdText = ;//命令语句如SQL语句adCmdTable = ;//数据表名称adCmdStoredProc = ;//存储过程名称

{ CursorType的常量说明 }adOpenForwardOnly = ;//只能由前向后单向访问 为缺省值adOpenKeyset = ;//可见其他用户对数据的修改 但对其它用户的增加和删除不可见adOpenDynamic = ;//其他用户对数据的增加修改和删除均可见adOpenStatic = ;//其他用户对数据的增加修改和删除均不可见

{ LockType的常量说明 }adLockReadOnly = ;//只读 为缺省值adLockPessimistic = ;//在修改时 按单个记录锁定adLockOptimistic = ;//在修改后更新时 按单个记录锁定adLockBatchOptimistic = ;//在成批更新时记录锁定varAConnection ARecordSet : variant;longintTemp : integer;strTemp : string;intIndex : integer;begin{创建一个临时的ODBC数据源 指向一个MsAccess数据库 并利用此DSN建立一个数据库连接}AConnection := CreateOleObject( ADODB Connection );AConnection Open( Driver={Microsoft Access Driver (* mdb)};DBQ=C:\inetpub\root\test );

{建立一个数据集对象 并从数据表中提取数据}ARecordSet := CreateOleObject( ADODB RecordSet );ARecordSet open( wfjmu AConnection adOpenStatic adLockOptimistic adCmdTable );

memo lines clear;memo lines add( ********数据表原有的内容如下******** );{显示各个域的域名}strTemp := ;for intIndex := to ARecordSet Fields count dostrTemp := strTemp + ARecordSet Fields name+ ; ;memo lines add( strTemp );

{显示各个域的内容}while not ARecordSet eof dobeginstrTemp := ;for intIndex := to ARecordSet Fields count dostrTemp := strTemp + ARecordSet Fields value+ ; ;memo lines add( strTemp );ARecordSet MoveNext;//移到下条 Nextend;

{增加一个记录}ARecordSet AddNew;//增加 AppendARecordSet Fields value+ ; ;memo lines add( strTemp );ARecordSet MoveNext;//移到下条 Nextend;

{修改最后一条记录}ARecordSet MoveLast;ARecordSet Fields value+ ; ;memo lines add( strTemp );ARecordSet MoveNext;//移到下条 Nextend;

{删除最后一条记录}ARecordSet MoveLast;//移到末条 LastARecordSet delete;//删除 deleteARecordSet Update;//更新 在Delphi不需要ARecordSet MoveFirst;//移到首条 Firstmemo lines add( ********删除了最后一条记录后的数据表的内容如下******** );{显示各个域的内容}while not ARecordSet eof dobeginstrTemp := ;for intIndex := to ARecordSet Fields count dostrTemp := strTemp + ARecordSet Fields value+ ; ;memo lines add( strTemp );ARecordSet MoveNext;//移到下条 Nextend;

ARecordSet Close;{关闭数据集}

{用SQL语句进行查询 查询姓名为 张三 的记录}{注意 在SQL语句中 字符串应该用单引号包括起来}ARecordSet open( select * from wfjmu where AName = 张三 AConnection adOpenStatic adLockOptimistic adCmdText );memo lines add( ********张三的内容如下******** );memo lines add( 共有 + IntToStr( ARecordSet RecordCount ) + 条匹配的记录 );{显示各个域的内容}while not ARecordSet eof dobeginstrTemp := ;for intIndex := to ARecordSet Fields count dostrTemp := strTemp + ARecordSet Fields value+ ; ;memo lines add( strTemp );ARecordSet MoveNext;//移到下条 Nextend;

lishixinzhi/Article/program/Delphi/201311/25077

关于ado数据库编程用,用Visual C++开发数据库应用程序(3)的介绍到此结束,希望对大家有所帮助。

ado数据库编程用(用Visual C++开发数据库应用程序(3))

本文编辑:admin

更多文章:


自动发卡平台搭建(如何搭建一个权益卡网站平台)

自动发卡平台搭建(如何搭建一个权益卡网站平台)

大家好,关于自动发卡平台搭建很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于如何搭建一个权益卡网站平台的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!本文目录如

2025年11月7日 13:45

华为新品发布会(华为发布会2023新品发布时间)

华为新品发布会(华为发布会2023新品发布时间)

大家好,关于华为新品发布会很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于华为发布会2023新品发布时间的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!本文目录

2026年2月20日 18:00

如何用纯CSS实现接扎啤的特效(附源码)?如何使用纯CSS实现从按钮两侧滑入装饰元素的悬停特效(附源码)

如何用纯CSS实现接扎啤的特效(附源码)?如何使用纯CSS实现从按钮两侧滑入装饰元素的悬停特效(附源码)

大家好,关于特效源码很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于如何用纯CSS实现接扎啤的特效(附源码)的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!本文

2026年7月16日 02:15

adodb连接oracle数据库的server属性(如何用adodc和datagird连接数据库)

adodb连接oracle数据库的server属性(如何用adodc和datagird连接数据库)

大家好,如果您还对adodb连接oracle数据库的server属性不太了解,没有关系,今天就由本站为大家分享adodb连接oracle数据库的server属性的知识,包括如何用adodc和datagird连接数据库的问题都会给大家分析到,

2025年11月10日 18:00

pragmatics(pragmatics名词解释是什么)

pragmatics(pragmatics名词解释是什么)

大家好,如果您还对pragmatics不太了解,没有关系,今天就由本站为大家分享pragmatics的知识,包括pragmatics名词解释是什么的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!本文目录pragmatics

2026年7月14日 15:45

water tables(不可数名词有哪些, 怎么分辨)

water tables(不可数名词有哪些, 怎么分辨)

本篇文章给大家谈谈water tables,以及不可数名词有哪些, 怎么分辨对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。本文目录不可数名词有哪些, 怎么分辨table怎么读英语table-water怎么发音不可数名词有哪些, 怎么

2026年4月7日 08:30

evolving(英语这里evolving怎么翻译)

evolving(英语这里evolving怎么翻译)

今天给各位分享英语这里evolving怎么翻译的知识,其中也会对英语这里evolving怎么翻译进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录英语这里evolving怎么翻译envolve是什么意思啊evol

2025年6月12日 10:30

论坛代码是什么(code for forums什么意思)

论坛代码是什么(code for forums什么意思)

大家好,关于论坛代码是什么很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于code for forums什么意思的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!

2026年7月13日 09:00

建筑工地图片(建筑施工现场应该挂哪些标志牌在哪些地方挂设)

建筑工地图片(建筑施工现场应该挂哪些标志牌在哪些地方挂设)

大家好,关于建筑工地图片很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于建筑施工现场应该挂哪些标志牌在哪些地方挂设的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助

2026年1月18日 00:00

hadoop集群搭建公平(VMware搭建完全分布式Hadoop集群)

hadoop集群搭建公平(VMware搭建完全分布式Hadoop集群)

大家好,今天小编来为大家解答以下的问题,关于hadoop集群搭建公平,VMware搭建完全分布式Hadoop集群这个很多人还不知道,现在让我们一起来看看吧!本文目录VMware搭建完全分布式Hadoop集群hadoop集群搭建(Hadoop

2025年10月3日 16:15

vue强制刷新组件(vue中如何不刷新页面让组件重新渲染)

vue强制刷新组件(vue中如何不刷新页面让组件重新渲染)

大家好,关于vue强制刷新组件很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于vue中如何不刷新页面让组件重新渲染的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助

2026年3月10日 03:45

启动git服务(windows 怎样配置git服务器)

启动git服务(windows 怎样配置git服务器)

各位老铁们好,相信很多人对启动git服务都不是特别的了解,因此呢,今天就来为大家分享下关于启动git服务以及windows 怎样配置git服务器的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!本文目录windows 怎样

2026年7月22日 19:45

设计公司网站源码(别人给我们公司建的网站,我们没有源代码能自己设计吗)

设计公司网站源码(别人给我们公司建的网站,我们没有源代码能自己设计吗)

“设计公司网站源码”相关信息最新大全有哪些,这是大家都非常关心的,接下来就一起看看设计公司网站源码(别人给我们公司建的网站,我们没有源代码能自己设计吗)!本文目录别人给我们公司建的网站,我们没有源代码能自己设计吗向设计c# .net的网络公

2026年8月9日 01:15

汇编语言延时程序怎么写(用8086汇编语言,编写延时子程序)

汇编语言延时程序怎么写(用8086汇编语言,编写延时子程序)

“汇编语言延时程序怎么写”相关信息最新大全有哪些,这是大家都非常关心的,接下来就一起看看汇编语言延时程序怎么写(用8086汇编语言,编写延时子程序)!本文目录用8086汇编语言,编写延时子程序汇编语言延时程序问题求汇编语言延时程序,延时10

2025年6月20日 23:30

ai基础教程入门视频(哪里有一些比较全面的ai教程,视频的,一定要全面)

ai基础教程入门视频(哪里有一些比较全面的ai教程,视频的,一定要全面)

本篇文章给大家谈谈ai基础教程入门视频,以及哪里有一些比较全面的ai教程,视频的,一定要全面对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。本文目录哪里有一些比较全面的ai教程,视频的,一定要全面AI入门基础工具教程视频哪里有一些比较

2026年9月18日 22:30

网站在线客服系统怎么申请(企业自己做网站,怎么添加’在线客服系统呢)

网站在线客服系统怎么申请(企业自己做网站,怎么添加’在线客服系统呢)

本篇文章给大家谈谈网站在线客服系统怎么申请,以及企业自己做网站,怎么添加’在线客服系统呢对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。本文目录企业自己做网站,怎么添加’在线客服系统呢网上客服网上客服工作怎么找网站那种浮动的在线客服,

2026年9月6日 22:15

access词组(assess的短语搭配)

access词组(assess的短语搭配)

大家好,关于access词组很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于assess的短语搭配的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!本文目录ass

2025年7月18日 14:00

equivalent英文(请问:等于,不等于,大于,小于,大于等于,小于等于的英文English是什么)

equivalent英文(请问:等于,不等于,大于,小于,大于等于,小于等于的英文English是什么)

“equivalent英文”相关信息最新大全有哪些,这是大家都非常关心的,接下来就一起看看equivalent英文(请问:等于,不等于,大于,小于,大于等于,小于等于的英文English是什么)!本文目录请问:等于,不等于,大于,小于,大于

2025年10月21日 16:15

myeclipse注册码在哪里输入(myeclipse10,需要注册码怎么办)

myeclipse注册码在哪里输入(myeclipse10,需要注册码怎么办)

大家好,如果您还对myeclipse注册码在哪里输入不太了解,没有关系,今天就由本站为大家分享myeclipse注册码在哪里输入的知识,包括myeclipse10,需要注册码怎么办的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开

2025年9月20日 12:30

curl音标(根据音标写出单词以及汉语意思)

curl音标(根据音标写出单词以及汉语意思)

大家好,今天小编来为大家解答以下的问题,关于curl音标,根据音标写出单词以及汉语意思这个很多人还不知道,现在让我们一起来看看吧!本文目录根据音标写出单词以及汉语意思如图 根据音标写出单词和汉语意思curl的音标写成/k倒e:l/,不是/k

2025年7月5日 17:30

近期文章

本站热文

electronics软件(labcenter electronics是什么软件)
2025-05-22 23:45:02 浏览:134
博客是微博吗(博客是微博吗)
2025-05-22 22:45:01 浏览:111
diversity and distribution(悬赏英语短文)
2025-05-23 16:15:02 浏览:107
ios软件开发前景(iOS就业前景怎么样)
2025-05-22 23:00:01 浏览:102
next month(有The next month这个单词吗,和 next month有什么区别)
2025-05-23 02:30:01 浏览:102
patron(patron是什么意思)
2025-05-23 10:30:02 浏览:95
标签列表

热门搜索