用ADO管理SQL Server数据库及其设备

作者:不详 来源: 日期:2002-11-20
---- 微 软 公 司 的SQL Server 是 目 前 小 型 网 络 中 常 用 的 数 据 库 管 理 系 统 之 一。 面 向 这 种 网 络 数 据 库 的 应 用 程 序 也 在 日 益 增 多, 这 种 网 络 数 据 库 应 用 系 统 的 正 常 运 行, 一 般 都 依 赖 于 已 经 存 在 的 用 户 数 据 库。 创 建 数 据 库 的 工 作 当 然 可 以 用SQL Server 提 供 的SQL Enterprise Manager 工 具 来 完 成, 但 是, 如 果 能 够 提 供 一 种 定 制 的 数 据 库 管 理 工 具, 专 门 管 理 应 用 系 统 需 要 的 数 据 库 及 其 设 备, 对 用 户 来 说 无 疑 更 加 理 想。 

现 存 问 题
---- 我 们 知 道, 在 使 用CREATE DATABASE 语 句 创 建 一 个 数 据 库 之 前, 必 须 存 在 一 个 有 剩 余 空 间 的 数 据 库 设 备, 或 者 事 先 使 用DISK INIT 语 句 创 建 一 个 新 设 备。 但 是 这 些 语 句 含 有 很 多 必 需 的 参 数, 而 且 如 果 不 使 用SQL Server 的 管 理 工 具, 很 多 参 数 值 往 往 难 以 确 定。 
---- 以 创 建 数 据 库 设 备 的DISK INIT 语 句 为 例, 这 个 语 句 的 完 整 语 法 如 下: 

DISK INIT 
NAME = ‘logical_name',
PHYSNAME = ‘physical_name',
VDEVNO = virtual_device_number,
SIZE = number_of_2K_blocks
[, VSTART = virtual_address]

---- 其 中NAME 和SIZE 这 两 个 参 数 都 很 容 易 得 到, 麻 烦 的 是 物 理 名PHYSNAME 和 虚 拟 设 备 号VDEVNO 这 两 个 参 数。 前 者 要 求 是 一 个 服 务 器 上 的 物 理 文 件 全 路 径 名; 后 者 要 求 在1 ~255 之 间 找 一 个 没 有 被 别 的 设 备 占 用 的 号 码。 而 在 编 写 数 据 库 管 理 程 序 时, 用 户 的 服 务 器 上 有 哪 些 设 备 号 已 经 被 占 用,SQL Server 装 在 哪 个 驱 动 器 上, 都 是 无 法 预 料 的。 

---- 虽 然, 使 用SQL Server 的 管 理 工 具SQL Enterprise Manager, 可 以 非 常 方 便 地 创 建、 删 除 数 据 库 设 备, 或 者 扩 大 一 个 已 经 存 在 的 数 据 库, 也 可 以 非 常 方 便 地 创 建、 删 除 或 者 修 改 一 个 数 据 库, 但 是, 这 个 工 具 仍 然 要 求 我 们 输 入 很 多 不 太 常 用 的 参 数, 界 面 稍 显 复 杂。 

---- 所 以, 理 想 的 情 况 是: 用 户 只 需 要 按 下 一 个 命 令 按 钮, 应 用 程 序 需 要 的 数 据 库 及 其 设 备 都 能 立 即 自 动 地 创 建 好。 

解 决 方 案
---- 为 了 实 现 这 样 的 目 标, 我 们 必 须 想 办 法 解 决SQL 语 句 中 的 参 数 设 置 问 题。 
---- 1 . 创 建 设 备 的 语 句 参 数 

---- 创 建 设 备 的 语 句 即 前 面 提 到 的DISK INIT 语 句。 

---- 为 了 简 化 问 题, 我 们 可 以 指 定 与 数 据 库 名 相 同 的 设 备 文 件 名, 并 将 设 备 文 件 保 存 在master 设 备 所 在 的 子 目 录 中。 数 据 库 名 是 在 设 计 应 用 程 序 时 已 经 确 定; 而master 设 备 所 在 的 子 目 录, 可 以 从 系 统 表sysdevices 中 查 询 得 到。 这 样, 设 备 文 件 的 物 理 名 参 数 就 确 定 下 来 了。 

---- 虚 拟 设 备 号 的 问 题 则 比 较 复 杂, 因 为sysdevices 系 统 表 中 没 有“ 虚 拟 设 备 号” 这 样 一 个 字 段, 因 此, 必 须 另 想 办 法。 

---- 对SQL Server 的 系 统 存 储 过 程sp_helpdevice 进 行 分 析 之 后, 我 们 发 现, 虚 拟 设 备 号 是“ 隐 藏” 在sysdevices 系 统 表 的low 字 段 中 的, 借 助 另 一 个 系 统 表spt_values, 可 以 找 到 每 个 设 备 的 虚 拟 设 备 号。 这 样, 我 们 只 需 要 在 一 个 循 环 中 找 一 下 某 个 设 备 号 是 否 存 在 于sysdevices 中, 就 可 以 确 定 我 们 现 在 可 用 的 虚 拟 设 备 号。 

---- 至 于 数 据 库 设 备 的 大 小, 我 们 不 妨 设 得 大 一 些, 或 者 让 用 户 指 定 一 下 也 可 以。 

---- 2 . 创 建 数 据 库 的 语 句 参 数 

---- 创 建 数 据 库 的 语 句 如 下: 

CREATE DATABASE database_name
[ON {DEFAULT | database_device} [= size]
[, database_device [= size]]...]
[LOG ON database_device [= size]
[, database_device [= size]]...]
[FOR LOAD]

---- 其 中, 大 部 分 参 数 都 是 可 选 的, 我 们 只 需 要 指 定 一 个 设 备 名 及 数 据 库 的 大 小 即 可, 而 数 据 库 名、 设 备 名、 大 小 在 创 建 设 备 的 时 候 已 经 确 定 好 了, 所 以, 这 个 语 句 的 参 数 不 存 在 问 题。 

具 体 实 现
---- 使 用 普 通 的 应 用 开 发 工 具Visual Basic, 我 们 就 可 以 实 现 一 个 定 制 的 数 据 库 管 理 程 序。 
---- 为 了 实 现 与 数 据 库 服 务 器 的 连 接, 我 们 必 须 选 择 一 种 数 据 库 访 问 接 口。 虽 然 从VB 访 问SQL Server 有 很 多 接 口 可 供 选 择, 但 微 软 最 新 的 数 据 库 访 问 接 口ADO(Active Data Objects) 无 疑 是 最 有 前 途 的, 因 为 它 为 基 于 浏 览 器 的 数 据 库 应 用 系 统 的 实 现 提 供 了 可 能 性。 

---- 以 下 是 一 些 用 于 数 据 库 及 其 设 备 管 理 的 常 用 函 数。 

---- 1 . 取 当 前 的 工 作 数 据 库 

---- 由 于 管 理 任 务 一 般 都 必 须 在master 库 中 完 成, 因 此, 在 执 行 管 理 任 务 之 前, 最 好 保 存 当 前 工 作 库, 以 便 完 成 任 务 之 后 再 切 换 回 去。 

Public Function SQLGetCurrentDatabaseName(Cn As ADODB.Connection) As String
Dim sSQL As String
Dim RS As New ADODB.Recordset
On Error GoTo errSQLGetCurrentDatabaseName
sSQL = “select CurrentDB = DB_NAME()"
RS.Open sSQL, Cn
SQLGetCurrentDatabaseName = Trim $(RS!CurrentDB)
RS.Close
Exit Function
errSQLGetCurrentDatabaseName:
SQLGetCurrentDatabaseName = “"
End Function

---- 2 . 判 断 一 个 数 据 库 设 备 是 否 存 在 

---- Public Function SQLExistDeviceName(Cn As ADODB.Connection, sDevName As String) As Boolean 

---- '--按 照 名 称 判 断 一 个 设 备 是 否 存 在, 如 果 存 在, 返 回1, 否 则 返 回0 

Dim sSQL As String
Dim RS As New ADODB.Recordset
Dim bTmp As Boolean
On Error GoTo errSQLExistDeviceName
sSQL = “select CntDev=count( *) from master.dbo.sysdevices where name = ‘“ & sDevName & ”'"
RS.Open sSQL, Cn
If RS!CntDev = 0 Then bTmp = False Else bTmp = True
RS.Close
SQLExistDeviceName = bTmp
Exit Function
errSQLExistDeviceName:
SQLExistDeviceName = False
End Function

---- 3 . 判 断 一 个 虚 拟 设 备 号 是 否 被 占 用:SQLExistDeviceNumber。 

---- 编 者 注: 函 数 源 代 码 发 表 在 本 报 的WWW 站 点 上, 地 址 是:http://www.computerworld.com.cn/98/skill/default.htm。 下 同。 欢 迎 访 问! 

---- 4 . 找 一 个 最 小 的 尚 未 被 占 用 的 虚 拟 设 备 号:SQLGetUnusedDeviceNumber。 

---- 5 . 取 得SQL Server 安 装 目 录 下 的DATA 子 目 录 路 径:SQLGetDataPath。 

---- 6 . 创 建 一 个 新 设 备:SQLCreateDevice。 

---- 7 . 创 建 一 个 新 的 数 据 库:SQLCreateDatabase65。 

---- 8 . 取 数 据 库 设 备 的 详 细 信 息:SQLGetDeviceInfo。 

---- 9 . 扩 大 数 据 库 设 备 的 尺 寸:SQLExpandDevice。 

---- 数 据 库 应 用 系 统 在 运 行 一 段 之 后, 数 据 量 的 增 大 往 往 要 求 数 据 库 增 大, 进 而 要 求 扩 大 设 备 尺 寸。 可 惜DISK RESIZE 语 句 要 求 的 尺 寸 参 数 为 扩 大 后 的 新 尺 寸, 而 非 需 要 增 加 的 尺 寸。 所 以, 必 须 事 先 查 到 设 备 的 原 有 尺 寸, 才 能 使 用DISK RESIZE 语 句。 

---- 10 . 判 断 一 个 数 据 库 是 否 存 在:SQLExistDatabase。 

---- 11 . 删 除 一 个 数 据 库:SQLDropDatabase。 

---- 12 . 删 除 一 个 数 据 库 设 备:SQLDropDevice。 

---- 13 . 取SQL Server 的 版 本 信 息:SQLGetVersionString。 

---- 在 即 将 发 行 的SQL Server 7.0 中, 不 再 有 数 据 库 设 备 的 概 念, 创 建 数 据 库 也 将 变 得 更 加 简 单。 在 创 建 特 定 的 用 户 数 据 库 时, 为 了 区 分 不 同 的 版 本 进 行 不 同 的 操 作, 取 得SQL Server 的 版 本 是 非 常 重 要 的。 

---- “ 用Visual Studio 开 发 分 布 式Web 应 用” 系 列 文 章( 之 九), 读 者 有 何 意 见 或 建 议, 请 发E mail 至:ms_visualstudio@hotmail.com。 
相关文章