设为首页
加入收藏夹

从Oracle Developer/2000 调 用VB5.0
浏览选项:

  作者:国 家 基 础 地 理 信 息 中 心 王 小 平
  ---- Oracle 数 据 库 管 理 系 统 是 优 秀 的 数 据 库 管 理 系 统, 其 开 发
工 具Developer/2000 也 是 一 个 功 能 强 大, 方 便 灵 活 的 工 具 软 件, 许 多
Oracle 数 据 库 开 发 人 员 都 选 择Developer/2000 作 为 系 统 开 发 的 工 具。
但 当 今 的 数 据 库 用 户 再 也 不 会 仅 仅 局 限 于 枯 燥 无 味 的 数 据, 他
们 希 望 以 图 文 并 茂 的 方 式 显 示 查 询 结 果。 因 此 在 设 计 项 目 时, 一
般 是 选 择Developer/2000 来 开 发 有 关 数 据 库 的 维 护 功 能, 而 选 择 其 它
如VB、VC 等 优 秀 的 程 序 语 言 来 开 发 有 关 图 形 等 方 面 的 工 作。 这 就
带 来 一 个 问 题: 如 何 实 现Oracle 与 它 们 的 连 接。 本 文 就Oracle 与
  ---- 一 . VB5.0 与Oracle 数 据 库 的 连 接
  ---- VB5.0 可 以 与 多 种 外 部 数 据 库 的 连 接。VB5.0 可 以 从Microsoft
Access、dBASE、Microsoft Excel、FoxPro、Lotus、Paradox 等 数 据 库 中 读 取 数 据
; 通 过ODBC,VB5.0 可 以 与SQL SERVER 和ORACLE 相 连。 通 过ODBC 连 接 数 据 库
时, 首 先 要 正 确 配 置ODBC 的DSN(Data Name Source, 即 数 据 源), 然 后 在
VB5.0 中 可 以 通 过Data 控 件 或RDO 对 象 连 接 数 据 库。
  ---- 1. 配 置ODBC
  ---- 在WINDOWS 95 的 控 制 面 板 中 用 属 标 双 击32bit ODBC 就 启 动 了ODBC
数 据 源 管 理 器(ODBC Data Source Administrator), 在"UserDSN" 方 式 下 按
"Add" 按 钮, 出 现"Create New Data Source" 对 话 框, 从 中 选 择"Microsoft ODBC
Driver for Oracle"( 安 装VB 时 自 动 安 装 该 驱 动; 或 安 装VB 时 选 择
"Custom" 方 式, 在Data Access 选 项 中 选 择"Oracle ODBC Driver") 并 按 下
"Finish" 按 钮, 出 现"Microsoft ODBC Driver for Oracle Setup" 对 话 框, 在"Data
Source Name" 中 给 定 一 名 称( 如my_dsn), 在"User Name" 中 写 上 你 在ORACLE
数 据 库 中 的 用 户 名( 如scott), 在"Connect String" 中 写 上 想 要 连 接 的
Oracle 数 据 库 别 名( 该 别 名 登 记 在tnsnames.ora 文 件 中, 可 以 通 过 手 工
编 辑 该 文 件 或 通 过Developer/2000 中 的 工 具"SQL Net Easy Configuration" 来
  ---- 2. 设 置Data 控 件
  ---- Data 控 件 非 常 简 单 易 用, 可 以 用 来 执 行 大 部 分 数 据 访 问 操
作, 而 根 本 不 用 编 写 代 码。 一 个Data 控 件 可 以 对 应 一 个 基 表 或 视
图( 可 以 是 数 据 库 中 所 固 有 的 视 图 对 象, 也 可 以 是 在RecordSource 属
性 中 的SQL SELECT 语 句 所 选 出 的 数 据 集 合)。
  ---- 启 动VB, 在Form 上 添 加Data 控 件( 如Data1), 并 设 置 其Connect 属
性。Connect 属 性 中 记 载 着 连 接 字 符 串, 它 可 以 由 多 个 参 数 组 成:
  DSN:用名称注册 ODBC数据源
  UID:数据库的一个可识别的用户名。
  PWD:与用户名相关的密码
  ---- 例 如 将Connect 属 性 置 为"ODBC;DSN=my_dsn;UID=scott;PWD=tiger", 然 后
从RecordSource 属 性 的 列 表 框 中 选 择 某 一 基 表 或 视 图。
  ---- Data 控 件 可 以 与DBList、DBCombo、DBGrid 和 MSFlexGrid 字 段 结 合 使
用, 只 要 将 它 们 的DataSource 属 性 设 置 为 某 一 控 件( 如Data1), 详 见VB
  ---- 关 于VB 与 远 程 数 据 库 的 连 接, 请 参 阅《 计 算 机 世 界》1998 年
4 月20 日 的"VB5.0 中 远 程 数 据 库 的 访 问" 及1998 年5 月25 日 的" 用VB 和RDO
  ---- 二 . 从Developer/2000 向VB 应 用 程 序 传 递 参 数
  ---- Developer/2000 调 用VB 应 用 程 序 可 以 有 两 种 方 式, 一 是 通 过
HOST 过 程 调 用 外 部 命 令(VB 应 用 程 序), 如:HOST("notepad.exe"); 二 是
  DECLARE
  AppID PLS_INTEGER;
  BEGIN
  AppID := DDE.APP_BEGIN('notepad.exe');
  END;
  ---- 下 面 主 要 介 绍 一 下Developer/2000 中 向VB 应 用 程 序 的 参 数 传 递
  ---- 1. 命 令 行 参 数
  ---- 我 们 知 道,C 语 言 中 是 通 过int main( int argc[ , char *argv[ ] [,
char *envp[ ] ] ] ) 来 接 收 命 令 行 参 数 的, 但 在VB 中 没 有 对 应 的 语 法
。 好 在VB 提 供 了COMMAND() 函 数 来 返 回 命 令 行 参 数, 以 下 函 数 可 以
分 解 命 令 行 参 数 并 返 回 参 数 数 组:
  Function GetCommandLine(Optional MaxArgs)

  Dim C, CmdLine, CmdLnLen, InArg, I, NumArgs

  '检查是否提供了 MaxArgs参数。
  If IsMissing(MaxArgs) Then MaxArgs = 10
  ReDim ArgArray(MaxArgs) As String
  NumArgs = 0: InArg = False
  CmdLine = Command()
  CmdLnLen = Len(CmdLine)
  '以一次一个字符的方式取出命令行参数。
  For I = 1 To CmdLnLen
  C = Mid(CmdLine, I, 1)   If (C < > " " And C < > vbTab) Then
  If Not InArg Then
  If NumArgs = MaxArgs Then Exit For
  NumArgs = NumArgs + 1
  InArg = True
  End If
  '将字符加到当前参数中。
  ArgArray(NumArgs) = ArgArray(NumArgs) + C
  Else
  InArg = False
  End If
  Next I
  ReDim Preserve ArgArray(NumArgs)
  GetCommandLine = ArgArray()
  End Function
  调用方式如下:
  Dim cmdarray As Variant
  Rem cmdarray = GetCommandLine()
  ---- 这 样, 从Developer/2000 中 调 用 用VB 编 写 的 应 用 程 序 时 就 可 以
  AppID := DDE.APP_BEGIN('notepad.exe myfile');

  注 意: 别 忘 了 在 退 出Developer/2000 之 前 先 终 止 所 调 用 的 程 序, 如
  ---- 2. 用 基 表 或 视 图 来 传 递 参 数
  ---- 当 要 传 递 大 量 的 数 据 时, 上 述 方 法 就 行 不 通 了。 例 如, 将
在Developer/2000 中 从 数 据 库 某 个 基 表 中 查 询 出 的 记 录 集 合 传 给VB
以 进 行 图 形 显 示。 解 决 这 一 问 题 的 通 常 方 法 是 将 数 据 全 部 写 入
文 件(Oracle Developer/2000 提 供 了 内 建 软 件 包TEXT_IO 来 进 行 文 件 操 作)
, 然 后 以 文 件 名 为 参 数 调 用VB 应 用 程 序, 但 采 用 这 种 方 法 时VB 应
用 程 序 对 数 据 进 行 检 索 和 排 序 比 较 困 难, 而 且 文 件 操 作 本 身 也 比
较 烦 琐, 数 据 量 大 时, 速 度 问 题 比 较 突 出。
  ---- 一 种 好 的 解 决 方 法 是 用 数 据 库 作 为 传 递 参 数 的 中 介, 利 用
基 表 或 视 图 来 保 存 检 索 出 的 数 据, 然 后 只 要 向VB 应 用 程 序 传 递 基
表 或 视 图 名 即 可, 而VB 的 强 大 的 数 据 库 功 能 能 够 使 你 得 心 应 手
地 操 纵 数 据。 但 是Oracle 的PL /SQL 只 支 持DML(Data Manipulation Language,
即 数 据 操 作 语 言) 而 不 支 持DDL(Data Definition Language, 即 数 据 描 述
语 言), 因 此 在PL /SQL 中 不 能 动 态 产 生 基 表 或 视 图, 好 在Oracle 数 据
库 中 提 供 了DBMS_SQL 包, 该 包 可 以 让 你 执 行 任 何DDL 或DML, 包 括 创 建
  ---- 下 例 是 在Developer/2000 FORMS 中 根 据 当 前 块 的 默 认 选 择 条 件 创
  DECLARE
  cursor_name INTEGER;
  rows_processed INTEGER;
  table_name VARCHAR2(20):= get_block_property

  ( :system.cursor_block, base_table);
  wh_string VARCHAR2(500) := Rtrim(get_block_property
  (:system.cursor_block,default_where));
  sql_string VARCHAR2(400);
  BEGIN
  :globe.view_name := 'v_'|| table_name;
  sql_string := 'create view '|| :globe.view_name ||'
   as select * from '|| table_name;
  If wh_string Is Not Null Then
  sql_string := sql_string || ' where '|| wh_string;
  End If;
  cursor_name := dbms_sql.open_cursor;
  dbms_sql.parse(cursor_name, sql_string, dbms_sql.v7);
  rows_processed := dbms_sql.execute(cursor_name);

  dbms_sql.close_cursor(cursor_name);
  END;
  ---- 上 例 中,open_cursor 获 得 一 个 新 的 光 标(cursor) 号, parse 对 所
要 执 行 的 语 句 进 行 语 法 分 析, execute 执 行 给 定 的 光 标,close_cursor
关 闭 光 标、 释 放 内 存。 DBMS_SQL 包 还 有 其 它 许 多 功 能( 如 将 值 绑 定
给SQL 语 句 中 的 变 量、 读 取 查 询 结 果 等), 有 兴 趣 的 读 者 可 以 查 阅
ORACLE 手 册Oracle Server Application Developer's Guide。
  ---- 三 . Developer/2000 与VB 应 用 程 序 的 统 一
  ---- 用Developer/2000 开 发 的 应 用 程 序 在 执 行 时 会 出 现 一 个MDI 窗
口, 应 用 程 序 中 的 所 有 窗 口 都 在 此MDI 窗 口 之 内, 而 用VB 开 发 的 应
用 程 序 拥 有 自 己 独 立 的 窗 口, 这 样 开 发 出 的 应 用 软 件 会 给 用 户
以 两 个 平 台、 两 套 系 统 之 嫌。 如 果 能 够 解 决 这 个 问 题, 就 会 使 应
用 软 件 系 统 增 色 不 少。 我 们 很 自 然 地 想 到 将VB 的Form( 窗 口) 的 父 窗
  ---- 1. 获 得Developer/2000 的MDI 窗 口 句 柄
  ---- Developer/2000 FORMS 用FORMS_MDI_WINDOW 标 记FORMS 的MDI 窗 口, 用
get_window_property 获 得 其 窗 口 句 柄 后 就 可 以 将 它 作 为 参 数 传 给VB
  DECLARE
  w_hdl BINARY_INTEGER;
  BEGIN
  w_hdl := TO_NUMBER(get_window_property
  (FORMS_MDI_WINDOW, WINDOW_HANDLE));
  AppID := DDE.APP_BEGIN('My_app.exe '|| :globe.view_name ||
   ' ' || TO_CHAR(w_hdl));
  END;
  ---- 2. 将VB 的 窗 口(Form) 放 入Developer/2000 的MDI 窗 口
  ---- Visual Basic 调 用WINDOWS API 非 常 简 单, 只 要 在 调 用 之 前 对 所 调
函 数 进 行 说 明 即 可。 格 式 说 明 可 以 使 用Visual Basic 的 工 具API Text
Viewer。 运 行API Text Viewer, 装 载Win32api.MDB, 从 中 选 出 所 需 的API 函 数
, 增 加 到"Selected Items" 框 内, 再 拷 贝 到 剪 贴 板, 然 后 粘 贴 到VB 的 说
  Private Declare Function SetParent Lib "user32"

   (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
  Private Sub Form_Load()
  Dim cmdarray As Variant
  cmdarray = GetCommandLine()
  rc = SetParent(Me.hWnd, cmdarray(2))
  Data1.Connect = "ODBC;DSN=my_dsn;UID=scott;PWD=tiger"
  Data1.RecordSource = " scott." + cmdarray(1)

  End Sub
  ---- 将 该VB 应 用 程 序 编 译 成 可 执 行 程 序(EXE), 以 便
Developer/2000 调 用。 至 此,VB 的 窗 口 已 经 纳 入Developer/2000 的MDI 窗 口 内
. 你 可 以 将VB Form 的ShowInTaskbar 属 性 设 置 成False 使VB 应 用 程 序 不 出 现
在 任 务 栏 内, 同 时 给 该Form 的Icon 属 性 赋 一 个 与Developer/2000 窗 口 图
标 的 相 似 的 图 标, 这 样 谁 还 能 分 得 出 你 的 软 件 哪 一 部 分 是 用
Developer/2000 开 发 的, 哪 一 部 分 是 用Visual Basic 开 发 的 呢 ?



Copyright © 2004 wanxu.com All Rights Reserved