____Oracle公司于1997年推出的Oracle 8數據庫以其支持大數據庫、多用戶的高性能事務處理、支持業界各項工業標准、完整的安全和完整性控制、支持分布式數據庫和分布處理,具有可移植性、可兼容性和可連接性等突出優點倍受用戶喜愛。
而在客戶端的開發工具方面,Visual C++也因其強大的功能和高度的靈活性等特點深受廣大程序員的喜愛。本文旨在介紹使用Visual C++開發基于Oracle數據庫應用程序的兩種方法。
____使用PRO*C開發數據庫應用
____1.PRO*C工作原理
____PRO系列是Oracle公司提供的在第三代高級程序設計語言中嵌入SQL語句來訪問數據庫的一套預編譯程序,包括PRO*Ada、PRO*C、PRO*COBOL、PRO*Fortran、PRO*Pascal和P RO*PL/I六種。程序員用相應的高級語言編寫嵌入SQL語句的PRO源程序(若用C語言則稱爲 PRO*C源程序),然後運行相應的預編譯程序,把嵌入的SQL語句轉換爲標准的Oracle調用並生成目標源程序,即純高級語言格式的源程序,最後將這些源程序加入用戶的程序中調用 (其處理過程如下圖)。
圖1
____Oracle預編譯程序提供如下功能:
____能用六種通用的高級程序設計語言中的任何一種編寫應用程序。
____遵循ANSI標准,在高級語言中嵌入SQL語句。
____可采用動態SQL方法,讓程序在運行時接受或構造一個有效的SQL語句。
____實現Oracle內部數據類型和高級語言數據類型之間的自動轉換。
____可通過在應用程序中嵌入PL/SQL事物處理塊來改進性能。
____能在程序行和命令行上指定所需要的預編譯可選項,並可在預編譯的過程中改變它們的值。
____能全面檢查嵌入的SQL數據操縱語句和PL/SQL塊的文法和語義。
____可用SQL*Net並行存取多個地點的Oracle數據庫。
____可把數組作爲輸入和輸出程序變量使用。
____能對應用程序中的代碼段進行條件預編譯。
____提供了較強的異常處理功能。
____由此可見,通過預編譯程序與其它高級語言的結合,既可以利用SQL強有力的功能和靈活性爲數據庫應用系統的開發提供強有力的手段,又可以充分利用高級語言自身在系統開發方面的優勢,從而提供一個完備的基于Oracle數據庫應用程序的開發解決方案。
____2.在VC中使用PRO*C
____每個PRO*C源文件一般由程序頭和程序體兩部分組成。程序頭包含宿主變量(SQL語句中所包含的變量)說明、通訊區定義和C外部表示符的說明等。程序體一般是由若幹函數組成,這些函數內含有SQL語句(以EXEC SQL起頭的語句)。
____PRO*C支持的數據類型包括:VARCHAR2(變長字符串)、NUMBER(二進制數)、INTGER(有符號整數)、FLOAT(浮點數)、STRING(以NULL結尾的字符串)、VARNUM(變長二進制數)、 LONG(變長字符串)、VARCHAR(變長字符串)、ROWID(二進制值)、DATE(定長日期/時間值 )、VARRAW(變長二進制數據)、RAW(定長二進制數據) 、LONGRAW(變長二進制數據)、UN SIGNED(無符號整數)、LONGVARCHAR(變長字符串)、LONGVARRAW(變長二進制數據)、CHA R(定長字符串)、CHARZ(C中定長以NULL結尾的字符串)、MLSLABEL(變長二進制數據)。
____在PRO*C中不能使用『l』或『u』作詞尾或『0x』作詞頭修飾常量;在SQL語句中使用單引號來定義字符串,用雙引號來定義非凡的或小寫字符的標識符(如表名等);SQL語句中不答應使用C中的尋址、間接、位邏輯、複合賦值、?=、--、++、%、操作符,並且用NOT、AND、OR、=來分別代替!、&&、、==。
____下面的程序是一個連接數據庫的PRO*C源程序例子。
____#include //聲明SQL通訊區
____#include
____#include
____EXEC SQL BEGIN DECLARE SECTION;
____VARCHAR username[20]; //聲明宿主變量
____VARCHAR passWord[20];
____VARCHAR dbname[20];
____EXEC SQL END DECLARE SECTION;
____void db_connect()
____{
____strcpy((char *)username.arr,"SCOTT");
____username.len = strlen((char *)username.arr);
____strcpy((char *)password.arr,"TIGER");
____password.len = strlen((char *)password.arr);
____strcpy((char *)dbname.arr,"SUNDB");
____dbname.len = strlen((char *)dbname.arr);
____EXEC SQL WHENEVER SQLERROR STOP;
____//隱式異常處理
____EXEC SQL CONNECT :usernameIDENTIFIED BY :password USING :dbname;
____/*if (sqlca.sqlcode != 0) //顯式異常處理
____{
____AfxMessageBox("\n與 Oracle 數據庫連接失敗!");
____return;
____}*/
____}
____在VC中使用PRO*C時,先用PRO*C編寫所需的操作數據庫的子程序,再運行PRO*C預編譯程序把PRO*C源程序轉成相應的.CPP源程序,將該程序插入到用戶工程文件中,並在需要對插入函數進行調用的模塊中說明函數,然後就可以在此模塊中調用所需的函數。
____使用ODBC中間件訪問數據庫
____1.ODBC工作原理
____ODBC是Open Database Connect(開放數據庫互連)的簡稱,它是由Microsoft公司于1 991年提出的一個用于訪問數據庫的統一界面標准,是應用程序和數據庫系統之間的中間件。它通過使用相應應用平台上和所需數據庫對應的驅動程序與應用程序的交互來實現對數據庫的操作,避免了在應用程序中直接調用與數據庫相關的操作,從而提供了數據庫的獨立性。
____ODBC主要由驅動程序和驅動程序治理器組成。驅動程序是一個用以支持ODBC函數調用的模塊(在WIN95下通常是一個DLL),每個驅動程序對應于相應的數據庫,當應用程序從基于一個數據庫系統移植到另一個時,只需更改應用程序中由ODBC治理程序設定的與相應數據庫系統對應的別名即可。驅動程序治理器(包含在ODBC32.DLL中)可鏈接到所有ODBC 應用程序中,它負責治理應用程序中ODBC函數與DLL中函數的綁定。
____ODBC使用層次的方法來治理數據庫,在數據庫通信結構的每一層,對可能出現依靠數據庫産品自身特性的地方,ODBC都引入一個公共接口以解決潛在的不一致性,從而很好地解決了基于數據庫系統應用程序的相對獨立性,這也是ODBC一經推出就獲得巨大成功的重要原因之一。
____從結構上分,ODBC分爲單束式和多束式兩類。
____單束式驅動程序
圖2
____單束式驅動程序介于應用程序和數據庫之間,像中介驅動程序一樣數據提供一個統一的數據訪問方式。
____當用戶進行數據庫操作時,應用程序傳遞一個ODBC函數調用給ODBC驅動程序治理器, 由ODBC API判定該調用是由它直接處理還是送交驅動程序執行。
____可見,單束式驅動程序本身是一個數據庫引擎,由它直接可完成對數據庫的操作,盡管該數據庫可能位于網絡的任何地方。
____多束式驅動程序
圖3
____多束式驅動程序負責在數據庫引擎和客戶應用程序之間傳送命令和數據,它本身並不執行數據處理操作,而用于遠程操作的網絡通信協議的一個界面。
____前端應用程序提出對數據庫處理的請求,該請求轉給ODBC驅動程序治理器,驅動程序治理器依據請求的情況,就地完成或傳給多束驅動程序。多束式驅動程序將請求翻譯爲特定廠家的數據庫通信接口(如Oracle的SQLNet)所能理解的形式並交于接口去處理,接口把請求經網絡傳送給服務器上的數據引擎。服務器處理完後把結果發回給數據庫通信接口 ,數據庫接口將結果傳給多束式ODBC驅動程序,再由驅動程序將結果傳給應用程序。
____2.在VC中使用ODBC
____Visual C++中提供了CDatabase、CRecordset、CRecordView、CDBException和CFie ldExchange五個類,這些類封裝了ODBC SDK函數,從而使用戶可以無需了解SDK函數就可以很方便地操作支持ODBC的數據庫。
____CDatabase類封裝了與數據庫建立連接、控制事務的提交和回滾及執行SQL語句的方法。
____CRecordset類封裝了大部分操縱數據庫的方法,包括浏覽、修改記錄、控制遊標移動、排序等操作。
____CRecordView類提供了與Recordset對象相連接的視圖,可以建立視中的控件與數據庫數據的對應,同時支持移動遊標、修改記錄等操作。
____CDBException類提供了對數據庫操作的異常處理,可以獲得操作異常的相關返回代碼。
____CFieldExchange類提供了用戶變量與數據庫字段之間的數據交換,假如不需要使用自定義類型,將不用直接調用該類的函數,MFC Wizard將自動爲程序員建立鏈接。
____兩種方法的比較
____綜上所述,使用這兩種方法在Visual C++中都可以很方便地開發出基于Oracle數據庫的應用程序,同時,這兩種方法又各有其優缺點。ODBC由于有MFC強大的類庫支持而使得編程實現非常方便,同時可移植性也很強,在異構數據庫之間移植也只需更改很少一部分程序。但是,由ODBC的實現機制我們可以看到,與PRO*C相比,應用程序需要經過ODBC驅動程序治理器和ODBC驅動程序兩層,才能和數據庫通信接口建立聯系,而PRO*C是直接與通信接口聯系,因此建立在ODBC上應用程序的執行效率會相對低一些。PRO*C具有執