用ADO管理SQL Server数据库及其设备
---- 微 软 公 司 的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。