VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)
首页 - 经验之谈 - VB5.0 中 远 程 数 据 库 的 访 问
发表评论(0)作者:, 平台:, 阅读:13975, 日期:2000-03-12






VB5.0 中 远 程 数 据 库 的 访 问

国 防 大 学 研 究 生 院许 蔓 舒





在VB5.0 中, 用Microsoft Jet 数 据 库 引 擎 和 数 据 访 问 对 象DAO

(Data Access Object) 可 以 创 建 功 能 强 大 的 客 户/ 服 务 器 应 用

程 序。 对 远 程 数 据 库 的 访 问 是 开 发 这 类 应 用 程 序 的 关 键

环 节, 本 文 将 介 绍 在VB5.0 中 用DAO 通 过Miscrosoft Jet 数 据 库 引

擎 访 问 远 程 数 据 库 的 方 法。


用DAO 访 问 远 程 数 据 库 大 体 上 可 以 通 过 三 步 来 实 现, 即

数 据 连 接、 数 据 处 理 和 断 开 连 接。 下 面 主 要 介 绍 数 据 连 接

和 数 据 处 理 的 具 体 操 作。


一、 数 据 连 接

DAO 一 般 通 过 链 接 远 程 表 的 方 式 来 进 行 数 据 连 接。 这

样, 数 据 虽 然 驻 留 在 远 程 数 据 源 上, 但 在 本 地 的Microsoft

Jet 数 据 库 中 可 以 存 储 与 远 程 数 据 的 永 久 性 连 接, 同 时 缓

存 链 接 的 表 结 构 信 息, 从 而 在 下 一 次 访 问 该 表 时, 不 用 再

次 从 服 务 器 中 检 索 这 些 结 构 信 息, 加 快 了 连 接 速 度。 一 旦

链 接 了 一 个 表, 该 链 接 便 会 保 留 在 各 会 话 期 间, 直 到 连 接

断 开。 链 接 远 程 表 的 具 体 操 作 是:

用OpenDatabase 方 法 打 开 将 要 包 含 该 链 接 的 本 地Microsoft

Jet 数 据 库


用CreateTableDef 方 法 在 该 数 据 库 中 创 建 一 个 新 的TableDef

对 象


将TableDef 对 象 的Connect 属 性 设 置 为 一 个 合 法 的 连 接 字

符 串, 标 识 要 访 问 的 远 程 数 据 库 类 型、 数 据 文 件 的 路 径 以

及 用 户 名 和 远 程 数 据 源 密 码 等。


将TableDef 对 象 的SourceTableName 属 性 设 置 为 远 程 数 据 库 中

要 访 问 的 表 的 名 称。


添 加TableDef 对 象 到TableDefs 集 合 中。


实 现 链 接 远 程 表 操 作 的 过 程 如 下:


Public Sub LinkTable(strDB As String, strRoDB As


String, strCn As String, strTdf As String, _


linkTdfName As String)


Dim linkTdf As New TableDef


Set dbs = OpenDatabase(strDB)


linkTdf.Name = linkTdfName


100


tempTable = UCase(linkTdf.Name)


For i = 0 To dbs.TableDefs.Count - 1


If UCase(dbs.TableDefs(i).Name) = tempTable Then


If MsgBox(linkTdfName + " 已 存 在, 是 否 删 除 ?", _


vbQuestion + vbYesNo) = vbYes Then


dbs.TableDefs.Delete linkTdf.Name


Exit For


Else: MsgBox " 重 新 输 入 新 表 名"


linkTdfName = InputBox(" 新 表 名")


GoTo 100


End If


End If


Next i


Set linkTdf = dbs.CreateTableDef(linkTdfName) ' 链 接 远 程 表


linkTdf.Connect = ";database=" + strCn


linkTdf.SourceTableName = strTdf


dbs.TableDefs.Append linkTdf


End Sub



上 述 过 程 用 来 实 现 远 程 表 的 连 接, 它 有5 个 参 数, 其 中

strRoDB 是 要 访 问 的 远 程 数 据 库 名( 包 括 路 径);strTdf 是 该

数 据 库 中 的 表 名;strDB 是 要 链 接 的 本 地 数 据 库( 包 括 路 径)

;linkTdfName 是 本 地 数 据 库 的 一 个 新 表 名, 用 来 建 立 远 程 表

的 链 接;strCn 是 指 定 连 接 信 息 的 字 符 串。 需 要 特 别 注 意 的

是, 除 了 在 访 问 远 程Microsoft Jet 数 据 库 时, 连 接 字 符 串 要

以 分 号(;) 开 头 外, 指 定 连 接 信 息 的 字 符 串 都 必 须 以 所

访 问 的 远 程 数 据 库 类 型 开 头。DAO 可 以 访 问 的 远 程 数 据 源

有 以 下 三 类:

.Microsoft Jet 数 据 源, 如:Access 数 据。


.IISAM( 可 安 装 的 索 引 化 顺 序 访 问 方 法) 格 式 数 据 源,

如:FoxPro、Paradox、dBASE 数 据。


.ODBC 数 据 源, 如:SQL Server 数 据、Oracle 数 据。


例 如: 设 网 络 服 务 器 名 为server, 共 享 目 录 为C:\Sales 的

FoxPro 3.0 数 据 库, 连 接 字 符 串 应 为


strCn="FoxPro3.0;database=\\server\c$\Sales\Region1"


此 外,DAO 通 过Microsoft Jet 数 据 库 引 擎 访 问 远 程 数 据 时,

还 可 以 用OpenDatabase 方 法 直 接 打 开 远 程 表。 在 本 地 数 据 库

中 并 未 存 储 与 远 程 数 据 源 建 立 连 接 所 需 要 的 信 息。 如 果

使 用 链 接 方 式 访 问 数 据, 则 不 必 在 每 次 会 话 开 始 时 提 供

连 接 信 息, 从 而 可 以 提 高 效 率。


二、 数 据 处 理

数 据 连 接 建 立 后, 可 以 用OpenRecordset 方 法 打 开 一 个 记

录 集, 并 可 用DBGrid 控 件 和Data 控 件 方 便 地 浏 览 整 个 记 录 集。

如 果 使 用 表 类 型(Table-type) 记 录 对 象, 则 对 应 的 是 一 个

实 际 存 在 的 数 据 库 表, 在 多 用 户 环 境 下, 其 它 用 户 对 数 据

的 修 改 会 立 即 反 映 到 表 中; 如 果 使 用 动 态 集 类 型(Dynaset-

type) 记 录 对 象, 则 对 应 的 既 可 以 是 一 个 表 中 全 部 记 录,

又 可 以 是 一 个 查 询 的 结 果, 并 且 可 以 更 新 记 录 集 中 的 记

录; 如 果 使 用 快 照 类 型(Snapshot-type) 记 录 对 象, 则 对 应 的

可 以 是 表 中 的 全 部 记 录, 也 可 以 是 一 个 查 询 结 果, 但 不 能

进 行 记 录 的 增 加、 删 除 和 修 改 操 作。 此 外, 还 可 以 建 立 其

它 类 型 的 记 录 对 象, 如 仅 向 前 型(ForwardOnly-type) 记 录 对 象

和 动 态 型(Dynamic-type) 记 录 对 象。

下 面 是 打 开 动 态 集 记 录 对 象 并 显 示 记 录 的 过 程:


Public Sub rst_display(strDB As String, strRst As String, strForm As

Form)


Set dbs = OpenDatabase(strDB)


Set rst = dbs.OpenRecordset(strRst, dbOpenDynaset)


strForm!Data1.DatabaseName = dbs.Name


strForm!Data1.RecordSource = rst.Name


strForm!Data1.Refresh


strForm!DBGrid1.ReBind


End Sub



上 述 过 程 有 三 个 参 数, 其 中strDB 用 来 指 定 本 地 数 据 库

名( 包 括 路 径),linkTdfName 是 在 本 地 数 据 库 中 新 建 的 链 接

远 程 表 的 表 名,strForm 是 网 格 控 件 和 数 据 控 件 所 在 的 窗 体

名。 调 用 此 过 程 可 以 基 于 新 表 建 立 一 个 动 态 集 类 型 的 记

录 对 象, 并 可 在 网 格 中 浏 览 各 个 记 录。

断 开 连 接 可 以 通 过 关 闭 应 用 程 序 或 设 置 连 接 超 时 来

实 现。 注 意: 如 果 对 数 据 库 对 象 使 用Close 方 法, 则 由 于 在

Miscrosoft Jet 数 据 库 引 擎 内 部 缓 存 了 连 接, 实 际 上 连 接 并

未 取 消。


三、 应 用 举 例

以 上 介 绍 了 用DAO 访 问 远 程 数 据 库 的 具 体 操 作, 下 面 通

过 一 个 例 子 说 明 链 接 远 程 表 和 建 立 记 录 集 对 象 的 方 法。

首 先 建 立 一 个 新 工 程, 在 窗 体 上 画5 个 命 令 按 钮,1 个

数 据 控 件 和1 个 数 据 网 格 控 件(DBGrid), 如 图1 所 示。 各 对 象

的 属 性 设 置 见 表1。


表1 窗 体1 对 象 属 性 设 置


对 象 标 题(Caption) 名 称(Name)

窗 体 远 程 数 据 访 问 Form1

命 令 按 钮1 链 接 远 程 表 cmd 链 接

命 令 按 钮2 添 加 cmdAdd

命 令 按 钮3 删 除 cmdDel

命 令 按 钮4 修 改 cmdModify

命 令 按 钮5 结 束 cmdEnd

数 据 控 件 Data1 Data1

数 据 网 格 DBGrid1


其 中DBGrid1 中 的DataSource 属 性 设 为Data1, 命 令 按 钮2,3,4

的Visible 属 性 设 为False。

编 写 如 下 事 件 过 程:


Private Sub cmdAdd_Click() ' 添 加 记 录 子 过 程


On Error GoTo errHandler


With rst


.AddNew


For i = 0 To .Fields.Count - 1 ' 遍 历 记 录 集 中 的 每 个 字 段


' 在 输 入 框 中 输 入 各 字 段 的 数 据


.Fields(i).Value = InputBox


(" 输 入 记 录 信 息" & vbCr + " 字 段 名:" + .Fields(i).Name)


Next i


.Update


End With


Data1.Refresh


DBGrid1.ReBind


errHandler: ' 错 误 处 理


Select Case Err


Case 3022, 3421


MsgBox (Error + vbCr + " 输 入 无 效")


Exit Sub


Case Else


Response = 0


Exit Sub


End Select


End Sub




Private Sub cmdDel_Click() ' 删 除 记 录 过 程


On Error GoTo errHandler


BeginTrans ' 事 务 处 理


With Data1.Recordset


If .BOF And .EOF Then Exit Sub


' 如 果 没 有 记 录, 退 出 过 程


.Delete ' 删 除


If .BOF And .EOF Then


' 如 果 没 有 记 录, 退 出 过 程


Exit Sub


ElseIf .EOF Then .MoveLast


' 如 果 删 除 的 是 最 后 一 条 记 录, 光 标 移 至 最 后 一 记




Else: .MoveNext


' 移 至 下 一 条 记 录


End If


End With


If MsgBox(" 确 实 要 删 除 这 一 记 录 ?",


vbQuestion + vbYesNo) = vbYes Then


CommitTrans ' 确 认


Data1.Refresh


Else


Rollback ' 撤 消 改 动


Data1.Refresh


End If


errHandler: ' 错 误 处 理


Select Case Err


Case 3021 ' 无 当 前 记 录


MsgBox (" 无 当 前 记 录, 请 选 择 要 删 除 的 记 录")


Exit Sub


Case Else


MsgBox (Error)


Exit Sub


End Select


End Sub




Private Sub cmdEnd_Click()


End ' 结 束 应 用 程 序


End Sub




Private Sub cmdModify_Click()


DBGrid1.AllowUpdate = True ' 允 许 修 改


End Sub




Privatev Sub cmd 链 接_Click()


Form1.Hide


Form2.Show


End Sub




Private Sub DBGrid1_AfterColUpdate(ByVal ColIndex As Integer)


' 数 据 修 改 后 触 发 该 事 件


On Error GoTo err1


Data1.Refresh


err1:


Select Case Err


Case 0


Response = 0


Case Else


Exit Sub


End Select


End Sub




Private Sub DBGrid1_BeforeColUpdate


(ByVal ColIndex As Integer, OldValue As Variant, Cancel As Integer)


' 数 据 修 改 前 触 发 该 事 件


On Error GoTo errHandler:


BeginTrans


If MsgBox(" 确 实 要 修 改


这 一 内 容 ?", vbQuestion + vbYesNo) = vbYes Then


CommitTrans


Else


Rollback


Data1.Refresh


End If


errHandler:


Select Case Err


Case 0


Response = 0


Case Else


MsgBox (Error)


Exit Sub


End Select


End Sub




Private Sub Form_Load()


' 在 窗 体 装 入 时, 网 格 中 的 数 据 不 可 添 加, 修 改


DBGrid1.AllowAddNew = False


DBGrid1.AllowUpdate = False


End Sub




Private Sub Form_Resize()


On Error Resume Next


' 当 窗 体 调 整 时 会 调 整 网 格


DBGrid1.Height = Me.ScaleHeight - Data1.Height - cmd 删 除.Height - 30


End Sub



在 工 程 中 添 加 一 个 窗 体, 在 窗 体 上 画6 个 标 签,1 个 命

令 按 钮( 标 题 为“ 确 认”, 名 称 为cmd 确 认),3 个 文 本 框 和1

个 组 合 框, 如 图1 所 示。


在 窗 体 的 声 明 部 份 输 入 以 下 代 码:


' 声 明 窗 体 层 变 量


Dim rodbs As Database


Dim strDB As String, strRoDB As String, strCn As String, strTdf As

String


Dim linkTdfName As String




编 写 如 下 事 件 过 程:


Private Sub cmd 确 认_Click()


On Error GoTo errHandler:


strDB = text2.Text


' 本 地 数 据 库 名 及 路 径


linkTdfName = Text3.Text


' 本 地 数 据 库 中 新 建 的 链 接 远 程 表 的 表 名




strCn = strRoDB ' 连 接 字 符 串


strTdf = Combo1.Text ' 指 定 远 程 数 据 库 中 要 访 问 的 表


' 调 用LinkTable 过 程


Call LinkTable(strDB, strRoDB, strCn, strTdf, linkTdfName)


' 调 用rst_display 过 程


Call rst_display(strDB, linkTdfName, Form1)


Form2.Hide


Form1.Show


Form1.Caption = " 远 程 数 据:" + strCn + "-" + strTdf


' 显 示“ 添 加”,“ 删 除”,“ 修 改” 控 件


Form1.cmdAdd.Visible = True


Form1.cmdDel.Visible = True


Form1.cmdModify.Visible = True


errHandler:


Select Case Err


Case 0


Response = 0


Case Else


MsgBox (Error + vbr + " 重 新 输 入")


Exit Sub


End Select


End Sub




Private Sub Combo1_GotFocus()


strRoDB = text1.Text ' 指 定 远 程 数 据 库 名 及 路 径


Set rodbs = OpenDatabase(strRoDB) ' 打 开 远 程 数 据 库


' 删 除combo1 中 的 内 容


If Combo1.ListCount >= 1 Then


For i = Combo1.ListCount - 1 To 0 Step -1


Combo1.RemoveItem i


Next i


End If


' 把 数 据 库 中 的 表 名 加 到combo1 中


For i = 0 To rodbs.TableDefs.Count - 1


Combo1.AddItem rodbs.TableDefs(i).Name


Next i


End Sub



运 行 结 果 如 图2所 示。





中国计算机世界出版服务公司版权所有