VB备忘录(21)ADO概念

ADO是一个接口,它的主要功能就是让你忘记复杂的内部操作,用这个接口来操作数据库。


                   用户<--->ADO<--------->OLEDB<---------->ODBC<--------->各种数据库

   

       如上所示,用户通过ADO,与OLEDB相连,OLEDB再与驱动ODBC相连,最后自动连接到各种的数据库,完成与数据库的通信。

      只须记住:   ADO与各种数据库打交道即可。


用户操作ADO来与数据库获取数据或者存取数据,有一些要考虑:

       1、数据库有游标(相当于指针,指向一条记录),这个游标是什么类型,只可向下移动?上下移动?游标是服务器上的还是本地的?

        2、几个用户同时修改数据库时,对相同记录怎么处理?先锁定再修改?不管别人修改我自动修改?按权限级别修改生效?

        3、对于图片等怎么存储、获取?二进制法进行存储和获取?怎么一个方式(流样式)?

        4、对于事务怎么来操作?怎么生效和回滚?


数据库操作的几个典型现象:

         1、连接到数据库.

          2、获取数据集

          3、处理数据集

          4、关闭连接



ADO主要有三个对象Connection,Command,Recordset,其模型如下:








Connection 对象
            

Connection 对象代表打开的、与数据源的连接。
注意 当需要使命令文本具有持久性并重新执行,或使用查询参数的时候,则必须使用 Command 对象。

1、打开到数据源的连接。
connection.Open ConnectionString, UserID, Password, Options

     Options: adConnectUnspecified(默认,同步),adAsyncConnect(异步)
     后面若有用户名及密码,将覆盖前面参数中对应的用户及密码
     用Close进行关闭连接,仅释放相关资源,并非删除对象(删除用设置成nothing)

2、执行指定的查询、SQL 语句、存储过程或特定提供者的文本等内容。
connection.Execute CommandText, RecordsAffected, Options   (不返回值)
Set recordset = connection.Execute (CommandText, RecordsAffected, Options)   (返回行集)

     附带一个返回参数RecordsAffected(受影响的行数)Long型
     Options可选,长整型值。ADO会智能判断类型,但指明类型会加快速度。
          AdCmdText       指示提供者应按命令的文本定义计算 CommandText。 
           AdCmdTable     指示 ADO 应生成 SQL 查询以便从 CommandText 命名的表中返回所有行。 
          AdCmdTableDirect 指示提供者应从 CommandText 命名的表中返回所有行。 
           AdCmdTable     指示提供者应按表名计算 CommandText。 
          AdCmdStoredProc 指示提供者应按存储过程计算 CommandText。 
           AdCmdUnknown    指示 CommandText 参数中的命令类型未知。 
          adAsyncExecute  指示命令应该异步执行。 
           adAsyncFetch   指示对在 CacheSize 属性指定的初始数量之后的剩余行使用异步提取。
     功能限制:返回的 Recordset 对象始终为只读、仅向前的游标







Command 对象
            

Command 对象定义了将对数据源执行的指定命令。返回 Recordset 对象中的记录。

使用 CommandText 属性定义命令(例如,SQL 语句)的可执行文本。
通过 Parameter 对象和 Parameters 集合定义参数化查询或存储过程参数。
可使用 Execute 方法执行命令并在适当的时候返回 Recordset 对象。
执行前应使用 CommandType 属性指定命令类型以优化性能。
使用 Prepared 属性决定提供者是否在执行前保存准备好(或编译好)的命令版本。
使用 CommandTimeout 属性设置提供者等待命令执行的秒数。
通过设置 ActiveConnection 属性使打开的连接与 Command 对象关联。
设置 Name 属性将 Command 标识为与 Connection 对象关联的方法。

多个 Command 对象与同一个连接关联,则必须显式创建并打开 Connection 对象,这样即可将 Connection 对象赋给对象变量。
如果没有将 Command 对象的ActiveConnection 属性设置为该对象变量,则即使使用相同的连接字符串,
ADO 也将为每个 Command 对象创建新的 Connection 对象。

如果在相同连接上执行两个或多个 Command 对象,并且某个 Command 对象是带输出参数的存储过程,这时会发生错误。要执行各个 Command 对象,请使用独立的连接或将所有其他 Command 对象的连接断开。

     
执行在 CommandText 属性中指定的查询、SQL 语句或存储过程。
对于按行返回的 Command:
       Set recordset = command.Execute( RecordsAffected, Parameters, Options )
对于非按行返回的 Command:
       command.Execute RecordsAffected, Parameters, Options
  返回 Recordset 对象引用或 Nothing。

  
    RecordsAffected 可选。Long 变量,提供者向其返回受操作影响的记录的数目。故查询不能返回此值(查询用RecordCount 属性)。
    Parameters 可选。用 SQL 语句传递的参数值的 Variant 数组。(用此参数传递时,输出参数将不能返回正确的值。) 
    Options 可选。Long 值,指示提供者计算 Command 对象的 CommandText 属性的方式。该值可为使用 CommandTypeEnum 和/或

                                                 ExecuteOptionEnum 值生成的位掩码值。例如,如果您希望 ADO 计算作为文本的 CommandText 属性值,

                                                并且指示执行命令文本时放弃且不返回任何可能生成的文本,则要将 adCmdText 和 adExecuteNoRecords 配合使用。 
      CommandTypeEnum指定解释命令参数的方法。同Connection的option的功效
        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 组合。
     
      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 指示未指定命令。 


Command对象Execute 方法的参数始终使用最近的值,除非用 Execute 调用传递的参数值覆盖它们
可以在调用 Execute 方法时通过省略某些参数的新值来覆盖参数子集。指定参数的次序与此方法传递这些参数的次序相同。例如,
如果有四个(或更多)参数,用户只希望传递第一个和第四个参数的新值,那么可以将 Array(var1,,,var4) 作为 Parameters 的参数传递。






Recordset 对象
            

Recordset 对象表示的是来自基本表或命令执行结果的记录全集。
          任何时候,Recordset 对象所指的当前记录均为集合内的单个记录。

在 ADO 中定义了四种不同的游标类型: 
 
         动态游标 — 用于查看其他用户所作的添加、更改和删除,并用于不依赖书签的 Recordset 中各种类型的移动。
                     如果提供者支持,可使用书签。
         键集游标 — 其行为类似动态游标,不同的只是禁止查看其他用户添加的记录,并禁止访问其他用户删除的记录,
                     其他用户所作的数据更改将依然可见。它始终支持书签,因此允许 Recordset 中各种类型的移动。
         静态游标 — 提供记录集合的静态副本以查找数据或生成报告。它始终支持书签,因此允许 Recordset 中各种类
                     型的移动。其他用户所作的添加、更改或删除将不可见。这是打开客户端 (ADOR) Recordset 对象时
                     唯一允许使用的游标类型。
         仅向前游标 — 除仅允许在记录中向前滚动之外,其行为类似静态游标。这样,当需要在 Recordset 中单程移动时
                       就可提高性能。

在打开 Recordset 之前设置 CursorType 属性来选择游标类型,或使用 Open 方法传递 CursorType 参数。如果没有指定游标类型,ADO 将默认打开仅向前游标。
如果 CursorLocation 属性被设置为 adUseClient 后打开 Recordset,则在返回的 Recordset 对象中,Field 对象的 UnderlyingValue 属性不可用。
同多个command使用同一个连接一样,在同一连接上打开多个rs,若没显示指明连接,ADO 仍然创建 Connection 对象,但它不将该对象赋给对象变量,ADO 也将为每个新的 Recordset 创建新的 Connection 对象
打开 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 对象。就是前面的“持久性”




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。
          adOpenDynamic 2 使用动态游标。其他用户所做的添加、更改或删除均可见,而且允许 Recordset 中的
                          所有移动类型(如果提供者不支持书签,则书签除外)。 
          adOpenForwardOnly 0 默认值。使用仅向前游标。除了在记录中只能向前滚动外,与静态游标相同。当只需要在 
                              Recordset 中进行一个传递时,用它可提高性能。 
          adOpenKeyset 1      使用键集游标。尽管从您的 Recordset 不能访问其他用户删除的记录,但除无法查看其他用户添加
                              的记录外,它和动态游标相似。其他用户所做的数据更改依然可见。 
          adOpenStatic 3     使用静态游标。一组记录的静态副本,可用于查找数据或生成报告。其他用户所做的添加、更改或
                              删除不可见。 
          adOpenUnspecified -1 不指定游标类型。 

  LockType 可选。LockTypeEnum 值,确定在打开 Recordset 时提供者应使用的锁定(并发)类型。默认值为 adLockReadOnly。 
         adLockBatchOptimistic 4 指示开放式批更新。需要批更新模式。 
         adLockOptimistic 3 指示逐个记录开放式锁定。提供者使用开放式锁定,仅在调用 Update 方法时锁定记录。 
         adLockPessimistic 2 指示逐个记录保守式锁定。提供者要确保记录编辑成功,通常在编辑之后立即在数据源锁定记录。 
         adLockReadOnly 1 指示只读记录。无法改变数据。 
         adLockUnspecified -1 未指定锁定类型。创建副本时,副本与源对象使用相同的锁定类型。 

  Options 可选。Long 值,指示提供者计算 Source 参数的方式(如果该参数表示除 Command 对象之外的某些内容),
               或者指示 Recordset 应该从以前保存过的文件中恢复。可以是一个或多个 CommandTypeEnum 或 ExecuteOptionEnum 值,
               这些值可以用位 AND 操作符组合。 

说明
ADO Recordset 的默认游标是位于服务器上的仅向前的只读游标。

在 Recordset 对象上使用 Open 方法打开游标,该游标表示基本表中的记录、查询的结果或以前保存的 Recordset。

使用可选的 Source 参数指定数据源,这些数据源使用下列之一:Command 对象变量、SQL 语句、存储过程、表名、URL 或完整的文件路径名。如果 Source 是文件路径名,它可以是完整路径(“c:\dir\file.rst”)、相对路径(“..\file.rst”)或 URL(“http://files/file.rst”)。

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

在设置 ActiveConnection 属性之前,调用没有操作数的 Open 可以创建 Recordset 的实例,这些 Recordset 是通过将字段追加到 Recordset 的 Fields 集合中创建的。




Stream 对象   表示二进制数据或文本的流。


在诸如文件系统或电子邮件系统这样的树状分级结构中,Record 可能有一个与之相关联的位的默认二进制流,其中包含文件或电子邮件的内容。Stream 对象可用于对包含这些数据流的字段或记录进行操作。可以通过下列方式获取 Stream 对象: 

通过将 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 的访问模式。 
--------------------
Charset 
指示用于转换文本 Stream 内容的字符集,以将其存储在 Stream 对象的内部缓冲区中。

设置和返回值
设置或返回 String 值,该值指定用于转换 String 内容的字符集。默认值为“Unicode”。所允许的值是作为 Internet 字符集字符串(例如,“iso-8859-1”,“Windows-1252”等)被传递到接口的典型字符串。有关系统支持的字符集字符串的列表,请参阅 Windows 注册表中 HKEY_CLASSES_ROOT\MIME\Database\Charset 的子键。

对于打开的 Stream,其当前 Position 必须位于 Stream (0) 的开始处,这样才能设置 Charset。
Charset 只能与文本 Stream 对象(Type 为 adTypeText)一起使用。如果 Type 为 adTypeBinary,则忽略此属性。

----------------------
EOS 属性
指示当前位置是否在流的结尾处。

返回值
返回 Boolean 值,指示当前位置是否在流的结尾处。如果流中没有其他字节,则 EOS 返回 True;如果当前位置后还有其他字节,则返回 False。

若要设置流的结尾位置,请使用 SetEOS 方法。若要确定当前位置,请使用 Position 属性。


------------------------------
SetEOS 方法  设置流的结尾位置。
语法  Stream.SetEOS
说明  SetEOS 通过使当前 Position 成为流的结尾来更新 EOS 属性的值。当前位置后面的所有字节或字符都将被截断。

由于 Write、WriteText 和 CopyTo 不截断现有 Stream 对象中多余的值,因此可以通过用 SetEOS 设置新的流结尾位置来截断这些字节或字符。

警告   如果将 EOS 设置到流的实际结尾前面的位置,那么新的 EOS 位置后面的所有数据都将丢失。


---------------------------
LineSeparator 属性
指示要在文本 Stream 对象中用作分行符的二进制字符。

设置和返回值
设置或返回 LineSeparatorsEnum 值,指示用在 Stream 中的分行符。默认值为 adCRLF。

说明
读取文本 Stream 的内容时,LineSeparator 用于解释行。可以用 SkipLine 方法跳过行。

LineSeparator 只能与文本 Stream 对象(Type 为 adTypeText)一起使用。如果 Type 为 adTypeBinary,则忽略此属性。


---------------------
SaveToFile 方法
把 Stream 的二进制内容保存到文件。

语法
Stream.SaveToFile FileName, SaveOptions

-----------------------
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 的大小与加载它的文件的大小可能不完全相同。




---------------------
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 从文件加载数据,可以将数据动态地添加到流。




Dim cn  As New ADODB.Connection
Dim rs  As New ADODB.Recordset
Dim stm As New ADODB.Stream

Private Sub Form_Load()
    cn.Open "Provider=SQLOLEDB.1;Password=123;Persist Security Info=True;User ID=sa;Initial Catalog=book;Data Source=ZHENG"
    Set MSHFlexGrid1.DataSource = cn.Execute("select * from 图书销售员")
    cn.Close
End Sub

Private Sub MSHFlexGrid1_GotFocus()
    MSHFlexGrid1_SelChange
End Sub

Private Sub MSHFlexGrid1_SelChange()
    cn.Open
    rs.Open "select * from 图书销售员 where 员工号='" & MSHFlexGrid1.TextMatrix(MSHFlexGrid1.Row, 1) & "'", cn, adOpenKeyset

    If Not rs.EOF Then
        If IsNull(rs.Fields(3)) Then
            Image1.Picture = LoadPicture("")
        Else
            stm.Open
            stm.Type = adTypeBinary
            stm.Write rs.Fields(3)     '写进stream,注意stream是承受者
            stm.SaveToFile App.Path & "\ly.gif", adSaveCreateOverWrite
            Image1.Picture = LoadPicture(App.Path & "\ly.gif")
            stm.Close
        End If
    End If

    rs.Close
    cn.Close
End Sub


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值