ADO指南

ADO 对象编程模型

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

      步骤 1:打开连接

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

ADO 打开连接的主要方法是使用 Connection.Open 方法。另外也可在同一个操作中调用快捷方法 Recordset.Open 打开连接并在该连接上发出命令。以下是 Visual Basic 中用于两种方法的语法:

connection.Open ConnectionString, UserID, Password, OpenOptions
recordset.Open Source, ActiveConnection, CursorType, LockType, Options

比较这两种方法将有益于加深对 ADO 方法操作数的总体了解。

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

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

与此相反,连接字符串中的关键字操作数 uidpwd 可为 Connection 对象设置 UserIDPassword 参数。

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

connection.Open "DSN=pubs;uid=sa;pwd=;database=pubs"

步骤 2:创建命令

查询命令要求数据源返回含有所要求信息行的 Recordset 对象。命令通常使用 SQL 编写。

  1. 如上所述,“命令字符串”之类的操作数可表示为:
    • 代表字符串的文字串或变量。本教程可使用命令字符串“SELECT * from authors”查询 pubs 数据库中的 authors 表中的所有信息。
    • 代表命令字符串的对象。在这种情况下,Command 对象的 CommandText 属性的值设置为命令字符串。
      Command cmd = New ADODB.Command;
      cmd.CommandText = "SELECT * from authors"
      
  2. 使用占位符‘?’指定参数化命令字符串。

    尽管 SQL 字符串的内容是固定的,您也可以创建“参数化”命令,这样在命令执行时占位符‘?’子字符串将被参数所替代。

    使用 Prepared 属性可以优化参数化命令的性能,参数化命令可以重复使用,每次只需要改变参数。

    例如,执行以下命令字符串将对所有姓“Ringer”的作者进行查询:

    Command cmd = New ADODB.Command
    cmd.CommandText = "SELECT * from authors WHERE au_lname = ?"
    
  3. 指定 Parameter 对象并将其追加到 Parameter 集合。

    每个占位符‘?’将由 Command 对象 Parameter 集合中相应的 Parameter 对象值替代。 可将“Ringer”作为值来创建 Parameter 对象,然后将其追加到 Parameter 集合:

    Parameter prm = New ADODB.Parameter
    prm.Name = "au_lname"
    prm.Type = adVarChar
    prm.Direction = adInput
    prm.Size = 40
    prm.Value = "Ringer"
    cmd.Parameters.Append prm
    
  4. 使用 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"
    

    返回 Recordset 的方法有三种:Connection.ExecuteCommand.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.Command — Text 属性中指定。另外,此命令可含有参数符号 ('?'),它可以由“参数”VARIANT 数组参数中的相应参数替代。
    • Recordset.Open 方法中,命令是 Source 参数,它可以是字符串或 Command 对象。

    每种方法可根据性能需要替换使用:

    • Execute 方法针对(但不局限)于执行不返回数据的命令。
    • 两种 Execute 方法都可返回快速只读、仅向前 Recordset 对象。
    • Command.Execute 方法允许使用可高效重复利用的参数化命令。
    • 另一方面,Open 方法允许指定 CursorType (用于访问数据的策略及对象)和 LockType (指定其他用户的 isolation 级别以及游标是否在 immediatebatch modes 中支持更新)。

    请深入了解这些选项,它们在很大程度上体现了 Recordset 的功能。

    本教程使用动态游标对 Recordset 的所有变更进行批处理,请使用以下方法:

    Recordset rs = New ADODB.Recordset
    rs.Open cmd, conn, adOpenDymanic, adLockBatchOptimistic
    

    大量 Recordset 对象方法和属性可用于对 Recordset 数据行进行检查、定位以及操作。

    Recordset 可看作行数组,在任意给定时间可进行测试和操作的行为“当前行”,在 Recordset 中的位置为“当前行位置”。每次移动到另一行时,该行将成为新的当前行。

    有多种方法可在 Recordset 中显式移动或“定位”(Move 方法)。一些方法(Find 方法)在其操作的附加效果中也能够做到。此外,设置某个属性(Bookmark 属性)同样可以更改行的位置。

    Filter 属性用于控制可访问的行(即这些行是“可见的”)。Sort 属性用于控制所定位的 Recordset 行中的顺序。

    Recordset 有一个 Fields 集合,它是在行中代表每个字段或列的 Field 集,可从 Field 对象 的 Value 属性中为字段赋值或检索数据。作为选项,可访问大量字段数据(GetRowsUpdate 方法)。

    在本教程中,您将要:

    • 将假设区号为“415”、局号以“5”开头的电话号码区号改为“777”。
    • 设置 au_lname Field 对象的 Optimize 属性以提高存储和筛选性能。
    • 按作者的姓将 Recordset 排序。
    • 筛选 Recordset,使作者电话区号为“415”、局号为“5”的行成为仅可访问(即可见)的行。

    使用 Move 方法从头至尾对经过排序和筛选的 Recordset 定位。当 Recordset EOF 属性表明已经到达最后一行时停止。在 Recordset 中移动时,显示作者的姓和名以及原始电话号码,然后将 phone 字段中的区号改为“777”。(phone 字段中的电话号码属于窗体“aaa xxx-yyyy”,其中 aaa 为区号,xxx 为局号。)

    rs!au_lname.Optimize = TRUE
    rs.Sort = "au_lname ASCENDING"
    rs.Filter = "phone LIKE '415 5*'"
    rs.MoveFirst
    Do 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.MoveNext
    Loop
    

    您刚刚对 Recordset 若干行中的数据进行了修改,ADO 有两种基本途径用于添加、删除和修改数据行。

    其一是更改不是立即对 Recordset 进行而是对“复制缓冲区”进行,当您不想更改时,复制缓冲区中的改动将被放弃;如果想保留更改,复制缓冲区中的改动将应用于 Recordset

    其二是当您声明行的工作已经完成时(即“立即”模式)将更改立刻传给数据源,否则将收集对行集合的所有更改,直到您声明该行集合的工作已经完成(即“批”模式)。这些模式将由 CursorLocationLockType 属性加以控制。

    在“立即”模式中,每个 Update 方法的调用都将更改传送给数据源,而在“批”模式中,虽然每个 Update 调用和当前行位置移动都将更改存放在 Recordset 中,但只有 UpdateBatch 方法才可将更改传送给数据源。由于打开 Recordset 使用的是批模式,因此更新也使用批模式。

    注意    Update 可采用简捷的形式将更改用于单个字段或将一组更改用于一组字段,然后再进行更改,这样可以一步完成更新操作。

    可选择在“事务”中进行更新。实际上,您可以使用事务来确保多个相互关联的操作或者全部成功执行,或者全部取消。在此情况下,事务不是必须的。

    事务可在一段相当长的时间内分配和保持数据源上的有限资源,因此建议事务的存在时间越短越好。(这便是本教程不在进行连接之初就开始事务的原因。)

    为使用教程,将您的批更新括在事务中:

    conn.BeginTrans
    rs.UpdateBatch
    ...

    假设批更新中含有错误,错误的解决则取决于错误的性质和严重性以及应用程序的逻辑关系。如果数据库是与其他用户共享的,典型的错误则是他人在您之前更改了数据字段,这种类型的错误称为“冲突”。ADO 将检测到这种请况并报告错误。

    在本教程中,这个步骤分为两部分:如果不存在更新错误则“提交”事务,结束更新。

    如果错误存在,它们会被错误处理例程捕获。可使用 adFilterConflictingRecords 常数对 Recordset 进行筛选,将冲突行显示出来。要纠正错误只需打印作者的姓和名(au_fnameau_lname),然后回卷事务,放弃成功的更新。由此结束更新。

    ...
    conn.CommitTrans
    ...
    On Error
    rs.Filter = adFilterConflictingRecords
    rs.MoveFirst
    Do While Not rs.EOF
       Debug.Print "Conflict: Name: " & rs!au_fname " " & rs!au_lname
       rs.MoveNext
    Loop
    conn.Rollback
    Resume Next
    ...
    

转载于:https://www.cnblogs.com/zizhuyuan/archive/2011/01/20/1940726.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值