從Oracle Developer/2000 調 用VB
2024-08-29 13:52:00
供稿:網友
Oracle 數 據 庫 管 理 系 統 是 優 秀 的 數 據 庫 管 理 系 統, 其 開 發 工 具Developer/2000 也 是 一 個 功 能 強 大, 方 便 靈 活 的 工 具 軟 件, 許 多Oracle 數 據 庫 開 發 人 員 都 選 擇Developer/2000 作 為 系 統 開 發 的 工 具。 但 當 今 的 數 據 庫 用 戶 再 也 不 會 僅 僅 局 限 于 枯 燥 無 味 的 數 據, 他 們 希 望 以 圖 文 并 茂 的 方 式 顯 示 查 詢 結 果。 因 此 在 設 計 項 目 時, 一 般 是 選 擇Developer/2000 來 開 發 有 關 數 據 庫 的 維 護 功 能, 而 選 擇 其 它 如VB、VC 等 優 秀 的 程 序 語 言 來 開 發 有 關 圖 形 等 方 面 的 工 作。 這 就 帶 來 一 個 問 題: 如 何 實 現Oracle 與 它 們 的 連 接。 本 文 就Oracle 與VB5.0 的 連 接 來 談 一 點 自 己 的 體 會。
---- 一 . 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 訪 問SQL Server", 此 處 不 在 贅 說。
---- 二 . 從Developer/2000 向VB 應 用 程 序 傳 遞 參 數
---- Developer/2000 調 用VB 應 用 程 序 可 以 有 兩 種 方 式, 一 是 通 過HOST 過 程 調 用 外 部 命 令(VB 應 用 程 序), 如:HOST("notepad.exe"); 二 是 通 過DDE 包 來 調 用VB 應 用 程 序, 如:
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 之 前 先 終 止 所 調 用 的 程 序, 如DDE.APP_END(AppID)
---- 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( 窗 口) 的 父 窗 口 設 成Develop 2000 的MDI 窗 口。
---- 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 開 發 的 呢 ?