yj_hust 发表于 2013-8-27 21:47:19

ADO 简单操作教程

本帖最后由 yj_hust 于 2013-8-27 21:52 编辑

结合网贴,整理了一个ADO操作的简单教程。刚开始接触ADO时会比较难理解,
有个总体的流程概念后,对其对象函数的选择和理解会更好些。
网上的代码多少VB和C++的,如果是用vlisp,可以参考修改。反正vlisp写,跟这两个语言写法差不多,都是用vlax函数来导入。


ADO 对象编程模型
[*]连接数据源 (Connection),可选择开始事务。
[*]可选择创建表示 SQL 命令的对象 (Command)。
[*]可选择指定列、表以及 SQL 命令中的值作为变量参数 (Parameter)。
[*]执行命令(Command、Connection 或 Recordset)。
[*]如果命令以行返回,将行存储在存储对象中 (Recordset)。
[*]可选择创建存储对象的视图以便进行排序、筛选和定位数据 (Recordset)。
[*]编辑数据。可以添加、删除或更改行、列 (Recordset)。
[*]在适当情况下,可以使用存储对象中的变更对数据源进行更新 (Recordset)。
[*]在使用事务之后,可以接受或拒绝在事务中所做的更改。结束事务 (Connection)。

步骤 1:打开连接(ADO 教程)

[*]连接数据源。
[*]可选择创建表示 SQL 查询命令的对象。
[*]可选择在 SQL 命令中将值指定为变量参数。
[*]执行命令。如果命令以行返回,将行存储在存储对象中。
[*]可选择对数据进行定位、检查、操作和编辑。
[*]适当情况下,可以使用存储对象中的变更对数据源进行更新。可选择在事务处理中嵌入更新数据。
[*]在使用事务之后,可以接受或拒绝在事务中所做的更改。结束事务。

讨论
如果需要一种途径以建立交换数据所必须的条件,那就是“连接”。所连接的数据源可在“连接字符串”中指定,但是对于不同的提供者和数据源而言,连接字符串中指定的参数会有所不同。

ADO 打开连接的主要方法是使用 Connection.Open 方法。另外也可在同一个操作中调用快捷方法 Recordset.Open 打开连接并在该连接上发出命令。以下是 Visual Basic 中用于两种方法的语法:
connection.Open ConnectionString, UserID, Password, OpenOptionsrecordset.Open Source, ActiveConnection, CursorType, LockType, Options
比较这两种方法将有益于加深对 ADO 方法操作数的总体了解。

ADO 提供了多种指定操作数的简便方式。例如:Recordset.Open 带有 ActiveConnection 操作数,该操作数可以是文字字符串(表示字符串的变量),或者是代表一个已打开的连接的 Connection 对象。

对象中的多数方法具有属性,当操作数缺省时属性可以提供参数。使用 Connection.Open,可以省略显式 ConnectionString 操作数并通过将 ConnectionString 的属性设置为“DSN=pubs;uid=sa;pwd=;database=pubs”隐式地提供信息。

与此相反,连接字符串中的关键字操作数 uid 和 pwd 可为 Connection 对象设置 UserID 和 Password 参数。

本教程使用显式连接字符串调用 Connection.Open 方法,数据源是“开放式数据库连接”(ODBC) pubs 数据库,它作为测试数据库与 Microsoft SQL Server 一同发布。(数据源的实际位置,如本地驱动器或远程服务器,在定义“数据源名称”(DSN) 时进行指定。)
connection.Open "DSN=pubs;uid=sa;pwd=;database=pubs"


步骤 2:创建命令(ADO 教程)


[*]连接数据源。
[*]可选择创建表示 SQL 查询命令的对象。
[*]可选择在 SQL 命令中将值指定为变量参数。
[*]执行命令。如果命令以行返回,将行存储在存储对象中。
[*]可选择对数据进行定位、检查、操作和编辑。
[*]适当情况下,可以使用存储对象中的变更对数据源进行更新。可选择在事务处理中嵌入更新数据。
[*]在使用事务之后,可以接受或拒绝在事务中所做的更改。结束事务。
讨论查询命令要求数据源返回含有所要求信息行的 Recordset 对象。命令通常使用 SQL 编写。

[*]如上所述,“命令字符串”之类的操作数可表示为:

[*]代表字符串的文字串或变量。本教程可使用命令字符串“SELECT * from authors”查询 pubs 数据库中的 authors 表中的所有信息。
[*]代表命令字符串的对象。在这种情况下,Command 对象的 CommandText 属性的值设置为命令字符串。Command cmd = New ADODB.Command;cmd.CommandText = "SELECT * from authors"
[*]使用占位符‘?’指定参数化命令字符串。尽管 SQL 字符串的内容是固定的,您也可以创建“参数化”命令,这样在命令执行时占位符‘?’子字符串将被参数所替代。使用 Prepared 属性可以优化参数化命令的性能,参数化命令可以重复使用,每次只需要改变参数。例如,执行以下命令字符串将对所有姓“Ringer”的作者进行查询:Command cmd = New ADODB.Commandcmd.CommandText = "SELECT * from authors WHERE au_lname = ?"
[*]指定 Parameter 对象并将其追加到 Parameter 集合。每个占位符‘?’将由 Command 对象 Parameter 集合中相应的 Parameter 对象值替代。 可将“Ringer”作为值来创建 Parameter 对象,然后将其追加到 Parameter 集合:Parameter prm = New ADODB.Parameterprm.Name = "au_lname"prm.Type = adVarCharprm.Direction = adInputprm.Size = 40prm.Value = "Ringer"cmd.Parameters.Append prm
[*]使用 CreateParameter 方法指定并追加 Parameter 对象。ADO 现在可提供简易灵活的方法在单个步骤中创建 Parameter 对象并将其追加到 Parameter 集合。cmd.Parameters.Append cmd.CreateParameter _"au_lname", adVarChar, adInput, 40, "Ringer"本教程将不使用参数化命令,因为需要使用 Command.Execute 方法以参数替代占位符‘?’,但该方法不允许指定 Recordset 游标类型和锁定选项。为此将使用如下代码:Command cmd = New ADODB.Command;cmd.CommandText = "SELECT * from authors"
下面列出表 authors 的模式以供查阅。

列名称数据类型(长度)是否可为空
au_idID (11)否
au_lnamevarchar(40)否
au_fnamevarchar(20)否
Phonechar(12)否
Addressvarchar(40)是
Cityvarchar(20)是
Statechar(2)是
Zipchar(5)是
Contractbit否




步骤 3:执行命令(ADO 教程)


[*]连接数据源。
[*]可选择创建表示 SQL 查询命令的对象。
[*]可选择在 SQL 命令中将值指定为变量参数。
[*]执行命令。如果命令以行返回,将行存储在存储对象中。
[*]可选择对数据进行定位、检查、操作和编辑。
[*]适当情况下,可以使用存储对象中的变更对数据源进行更新。可选择在事务处理中嵌入更新数据。
[*]在使用事务之后,可以接受或拒绝在事务中所做的更改。结束事务。
讨论返回 Recordset 的方法有三种:Connection.Execute、Command.Execute 以及 Recordset.Open。以下是它们的 Visual Basic 语法:
connection.Execute(CommandText, RecordsAffected, Options)command.Execute(RecordsAffected, Parameters, Options)recordset.Open Source, ActiveConnection, CursorType, LockType, Options通过优化这些方法可发挥特定对象的优势。
必须在发出命令之前打开连接,每个发出命令的方法分别代表不同的连接:
[*]Connection.Execute 方法使用由 Connection 对象自身表现的连接。
[*]Command.Execute 方法使用在其 ActiveConnection 属性中设置的 Connection 对象。
[*]Recordset.Open 方法所指定的或者是连接字符串,或者是 Connection 对象操作数;否则使用在其 ActiveConnection 属性中设置的 Connection 对象。
另一个不同点是命令在三种方法中的指定方式:
[*]在 Connection.Execute 方法中,命令是字符串。
[*]在 Command.Execute 方法中,命令是不可见的,它在 Command.CommandText 属性中指定。另外,此命令可含有参数符号 ('?'),它可以由“参数”VARIANT 数组参数中的相应参数替代。
[*]在 Recordset.Open 方法中,命令是 Source 参数,它可以是字符串或 Command 对象。
每种方法可根据性能需要替换使用:
[*]Execute 方法针对(但不局限)于执行不返回数据的命令。
[*]两种 Execute 方法都可返回快速只读、仅向前 Recordset 对象。
[*]Command.Execute 方法允许使用可高效重复利用的参数化命令。
[*]另一方面,Open 方法允许指定 CursorType (用于访问数据的策略及对象)和 LockType (指定其他用户的 isolation 级别以及游标是否在 immediate 或 batch modes 中支持更新)。
[*]请深入了解这些选项,它们体现了很多 Recordset 的功能。
本教程使用动态游标对 Recordset 的所有变更进行批处理,为此请使用以下方法:
Recordset rs = New ADODB.Recordsetrs.Open cmd, conn, adOpenDymanic, adLockBatchOptimistic   


步骤 4:操作数据(ADO 教程)


[*]连接数据源。
[*]可选择创建表示 SQL 查询命令的对象。
[*]可选择在 SQL 命令中将值指定为变量参数。
[*]执行命令。如果命令以行返回,将行存储在存储对象中。
[*]可选择对数据进行定位、检查、操作和编辑。
[*]适当情况下,可以使用存储对象中的变更对数据源进行更新。可选择在事务处理中嵌入更新数据。
[*]在使用事务之后,可以接受或拒绝在事务中所做的更改。结束事务。
讨论大量 Recordset 对象方法和属性可用于对 Recordset 数据行进行检查、定位以及操作。
Recordset 可看作行数组,在任意给定时间可进行测试和操作的行为“当前行”,在 Recordset 中的位置为“当前行位置”。每次移动到另一行时,该行将成为新的当前行。
有多种方法可在 Recordset 中显式移动或“定位”(Move 方法)。一些方法(Find 方法)在其操作的附加效果中也能够做到。此外,设置某个属性(Bookmark 属性)同样可以更改行的位置。
Filter 属性用于控制可访问的行(即这些行是“可见的”)。Sort 属性用于控制所定位的 Recordset 行中的顺序。
Recordset 有一个 Fields 集合,它是在行中代表每个字段或列的 Field 集,可从 Field 对象的 Value 属性中为字段赋值或检索数据。作为选项,可访问大量字段数据(GetRows 和 Update 方法)。
在本教程中,您将要:
[*]假定将区号为“415”局号并以“5”开头的电话号码更改为虚构的区号“777”。
[*]在 au_lname Field 对象的 Properties 集合中设置 Optimize 属性以提高存储和筛选性能。
[*]按作者的姓对 Recordset 使用 Sort(排序)操作。
[*]Filter(筛选)Recordset,使作者电话区号为“415”、局号为“5”的行成为仅可访问(即可见的)行。
使用 Move 方法从头至尾对经过排序和筛选的 Recordset 定位。当 Recordset EOF 属性表明已经到达最后一行时停止。在 Recordset 中移动时,显示作者的姓和名以及原始电话号码,然后将 phone 字段中的区号改为“777”。(phone 字段中的电话号码格式为“aaa xxx-yyyy”,其中 aaa 为区号,xxx 为局号。)
rs("au_lname").Properties("Optimize") = TRUErs.Sort = "au_lname ASC"rs.Filter = "phone LIKE '415 5*'"rs.MoveFirstDo While Not rs.EOF   Debug.Print "Name: " & rs("au_fname") & " " rs("au_lname") & _      "Phone: " rs("phone") & vbCr   rs("phone") = "777" & Mid(rs("phone"), 5, 11)   rs.MoveNextLoop


步骤 5:更新数据(ADO 教程)


[*]连接数据源。
[*]可选择创建表示 SQL 查询命令的对象。
[*]可选择在 SQL 命令中将值指定为变量参数。
[*]执行命令。如果命令以行返回,将行存储在存储对象中。
[*]可选择对数据进行定位、检查、操作和编辑。
[*]适当情况下,可以使用存储对象中的变更对数据源进行更新。可选择在事务处理中嵌入更新数据。
[*]在使用事务之后,可以接受或拒绝在事务中所做的更改。结束事务。
讨论
您刚刚对 Recordset 若干行中的数据进行了更改。对于添加、删除和修改数据行,ADO 有两个基本概念。
第一个概念是不立即更改 Recordset 而是将更改写入内部“复制缓冲区”。如果您不想进行更改,复制缓冲区中的更改将被放弃;如果想保留更改,复制缓冲区中的改动将应用到 Recordset。
第二个概念是只要您声明行的工作已经完成则将更改立刻传播到数据源(即“立即”模式)。或者只是收集对行集合的所有更改,直到您声明该行集合的工作已经完成(即“批”模式)。这些模式将由 CursorLocation 和 LockType 属性控制。
在“立即”模式中,每次调用 Update 方法都会将更改传播到数据源。而在“批”模式中,每次调用 Update 或移动当前行位置时,更改都被保存到 Recordset 中,只有 UpdateBatch 方法才可将更改传送给数据源。使用批模式打开 Recordset,因此更新也使用批模式。
注意   Update 可采用简捷的形式将更改用于单个字段或将一组更改用于一组字段,然后再进行更改,这样可以一步完成更新操作。可选择在“事务”中进行更新。实际上,您可以使用事务来确保多个相互关联的操作或者全部成功执行,或者全部取消。在此情况下,事务不是必需的。
事务可在一段相当长的时间内分配和保持数据源上的有限资源,因此建议事务的存在时间越短越好。(这便是本教程不在进行连接之初就开始事务的原因。)
为使用教程,将您的批更新括在事务中:
conn.BeginTransrs.UpdateBatch...


步骤 6:结束更新(ADO 教程)


[*]连接数据源。
[*]可选择创建表示 SQL 查询命令的对象。
[*]可选择在 SQL 命令中将值指定为变量参数。
[*]执行命令。如果命令以行返回,将行存储在存储对象中。
[*]可选择对数据进行定位、检查、操作和编辑。
[*]适当情况下,可以使用存储对象中的变更对数据源进行更新。可选择在事务处理中嵌入更新数据。
[*]在使用事务之后,可以接受或拒绝在事务中所做的更改。结束事务。
讨论假设批更新结束时发生错误,如何解决将取决于错误的性质和严重性以及应用程序的逻辑关系。如果数据库是与其他用户共享的,典型的错误则是他人在您之前更改了数据字段,这种类型的错误称为“冲突”。ADO 将检测到这种请况并报告错误。
本教程中的该步骤分为两部分:如果不存在更新错误则“提交”事务,结束更新。
如果错误存在,它们会被错误处理例程捕获。可使用 adFilterConflictingRecords 常数对 Recordset 进行筛选,将冲突行显示出来。要纠正错误只需打印作者的姓和名(au_fname 和 au_lname),然后回卷事务,放弃成功的更新。由此结束更新。
...conn.CommitTrans...On Errorrs.Filter = adFilterConflictingRecordsrs.MoveFirstDo While Not rs.EOF   Debug.Print "Conflict: Name: " & rs("au_fname") " " & rs("au_lname")   rs.MoveNextLoopconn.RollbackResume Next...
本教程到此结束。


caddog 发表于 2019-7-21 21:05:42

请教一下问题:
我写的一段读取DBF的代码,在同一台电脑上,CAD2008下运行正常,但在CAD2019下出错。
代码如下:

......
(setq conn (vlax-create-object "ADODB.Connection"));_创建并返回ADO RECORDSET对象
(setq conStr (strcat "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" $PathDbf ";Extended Properties=dbase 5.0;Persist Security Info=False"))
(vlax-invoke-method conn "Open" conStr nil nil -1)

在CAD2008中正常,在ACAD2019中出错,提示:
错误: Automation 错误。 未找到提供程序。该程序可能未正确安装。
请指教。谢谢。

dnbcgrass 发表于 2013-8-27 22:50:41

很不错的资料!谢谢分享!

saztu 发表于 2015-10-22 13:48:17

hejiho 发表于 2017-3-7 19:53:22

好一个藏龙卧虎之地呀{:1_1:}{:1_1:}{:1_1:}

点灯 发表于 2017-3-20 19:14:37

确实是难得好帖啊,顶先

csy0415 发表于 2019-3-12 09:22:22

感谢分享!

liaozhongshan 发表于 2019-9-14 23:24:06

很好的学习资料,感谢分享!

lsthz 发表于 2019-9-20 15:06:07

谢谢,受教了{:1_1:}

yxpxa 发表于 2020-10-20 18:13:41

本帖最后由 yxpxa 于 2020-10-21 13:14 编辑

caddog 发表于 2019-7-21 21:05
请教一下问题:
我写的一段读取DBF的代码,在同一台电脑上,CAD2008下运行正常,但在CAD2019下出错。
代 ...
2008是32位,2019可能是64位,平台驱动不通用,换成32位CAD试试。
或者你先安装64位Access ODBC驱动程序,CAD2019才能正确配置。
如果你的电脑里安装的是32位的office,安装64位的ACE驱动可能会出问题。
安装64位office时,又可能会使office运行一些32位VBA程序出毛病。
都是微软惹的祸,32/64有些混乱不兼容。

dcl1214 发表于 2023-6-18 21:09:45

caddog 发表于 2019-7-21 21:05
请教一下问题:
我写的一段读取DBF的代码,在同一台电脑上,CAD2008下运行正常,但在CAD2019下出错。
代 ...

2008调用的是jet驱动,操作系统是自带的,但是2019就必须调用ace驱动

kmliro_2017 发表于 2023-7-16 08:09:53

谢谢分享!!!!!!
页: [1]
查看完整版本: ADO 简单操作教程