Oracle應用Linux開發C

noter發表於2007-06-05
隨著Linux作業系統的不斷完善與發展,出現了大量基於 Linux平臺的應用開發,原有的基於UNIX平臺的商業軟體也不斷被移植到Linux上來。最典型的,Oracle公司宣佈,他的現有的及未來所有的數 據庫產品和商業應用都將支援Linux平臺。本文所述OCI for Linux的C語言庫,正是Linux平臺上Oracle的C語言介面。
我們知道,在一個複雜的Oracle資料庫應用中,C程式程式碼由於其語言本身的靈活性、高效性,往往被加入到其商務邏輯的核心層模組中。Oracle資料 庫對C語言的介面就是OCI(Oracle Common Interface) C-Library,該庫是一個功能十分強大的資料庫操作模組。它支援事務處理,單事務中的多連線多資料來源操作,支援資料的物件訪問、儲存過程的呼叫等一 系列高階應用,並對Oracle下的多種附加產品提供介面。但是我們發現,為了使OCI庫在多種平臺上保持統一的風格並考慮向下相容性,Oracle對大 量的C語言型別和程式碼進行了重新封裝,這使得OCI庫初看上去顯得紛繁複雜,初用者不知從何下手。由Kai Poitschke開發的Libsqlora8庫初步解決了這一問題,它使得在Linux下Oracle的非高階C語言開發變得比較方便易用。
Libsqlora8 for *nix是GNU/Linux組織開發的針對Oracle8 OCI library的易用性C語言封裝。它將大量的OCI資料型別表現為通用C語言資料型別,將OCI函式按型別重新分類封裝,大大減少了函式的呼叫步驟和程 序程式碼量。Libsqlora8還有許多引人注目的特性:
易於使用的動態SQL特性;
同一連線中具有不同變數繫結的遊標的重複開啟;
相同事務中的多資料庫連線;
Oracle資料庫應用開發中的Build-in trace功能;
正確處理資料插入操作中的陣列變數問題;
多平臺支援Oracle 8.0.4(HP-UX 9), Oracle 8.05(GNU/Linux), Oracle 8.1.6(GNU/Linux)等;
可以作為靜態或動態形式連結進入應用程式。
下面我們分步驟詳細闡述如何在Linux平臺上利用Libsqlora8函式庫開發Oracle資料庫應用。
1.安裝Linux作業系統,並對新系統進行適當的系統配置。在本例中我們選用RedHat Linux 6.2作業系統。在為系統分割槽時,我們為Oracle資料庫專門分出兩個分割槽:/u01,/u02,作為Oracle資料庫的系統軟體和資料庫檔案的安裝 點。安裝好系統後,我們為系統增添兩個新組:oinstall和dba,並建立一個新使用者Oracle,他擁有整個資料庫系統軟體。這裡就不詳細說明了。
2.下面我們應該安裝Oracle資料庫了,這次我們選用Oracle 8.1.6版本,該版資料庫對國際化有很好的支援。在安裝資料庫之前,我們要先對Oracle使用者進行一些設定。主要是在該使用者的啟動指令碼中,加入一些必要的環境變數,在本例中可以如下設定:
ORACLE_BASE=/u01/app/oracle
ORACLE_HOME=$ORACLE_BASE/product/8.1.6
ORACLE_SID=oratest
PATH=$ORACLE_HOME/bin:/usr/bin:/etc:/bin:/usr/local/bin:/usr/X11R6/bin
LD_LIBRARY_PATH=$ORACLE_HOME/lib
export ORACLE_BASE ORACLE_HOME ORACLE_SID PATH
3.Oracle 8.1.6的資料庫安裝是比較簡單的,我們選擇預設安裝,在系統的提示下逐一完成安裝過程。注意,Oracle8i對系統的要求是比較高的,特別是記憶體, 在一些特殊應用中,要修改系統的預設設定以提高資料庫效能。有關資料庫調優的討論與本文無關,在此就不再詳細介紹了。啟動資料庫,好了,現在我們可以用 sqlplus登入資料庫,可以看到,預設安裝的Oracle資料庫有一類OCITest資料庫表,就使用這些表作為我們例子中的預設表。
4.安裝Libsqlora8庫函式。該庫函式當前版本為Libsqlora8-2.1.5,可從許多Linux網站上得到,也可從http://www.china-linux.org上下載libsqlora8-2.1.5.tar.gz源程式包。按以下步驟安裝:
$>tar -xzvf libsqlora8-2.1.5.tar.gz
$>cd libsqlora8-2.1.5
$>LD_LIBRARY_PATH=$ORACLE_HOME/lib
$>export LD_LIBRARY_PATH
$>./configure
$>make
$>make install
對於要使用Oracle build-in trace功能的開發者,還要將以下環境變數設定好,SQLORA_TRACE_LEVEL,SOLORA_TRACE_FILE,SQLORA_ARRAYSIZE,當然,ORACLE_SID是一定要設好的。
5.下面,我們介紹一下Libsqlora8的主要函式。
1)int sqlo_init(int threaded_mode) 初始化程式庫介面,讀出環境變數,設定相應的全域性變數。當前,threaded_mode設為0。
2)int sqlo_connect(int * dbh, char * connect_str) 連線資料庫,dbh為資料庫連線描述符,connect_str為使用者名稱/口令字串。
3)int sqlo_finish(int dbh) 斷開資料庫連線。
4)int sqlo_open(int dbh, char * stmt, int argc, char *argv[]) 開啟由stmt確定的查詢語句所返回的遊標。Argc,argv為查詢的引數,後面我們將用更清晰的方法傳遞引數。
5)int sqlo_close(int sth) 關閉由上一個函式開啟的遊標。
6)int sqlo_fetch(int sth) 從開啟的遊標中獲取一條記錄,並將之存入一個已分配記憶體空間中。
7)const char **sqlo_values(int sth, int *numbalues, int dostrip) 從記憶體中返回上一次sqlo_fetch取得的值,是以字串形式返回的。
8)以下介紹另一種檢索方式,int sqlo_prepare(int dbh, char const *stmt),返回一個開啟的遊標sth。
9)int sqlo_bind_by_name(int sth, const char * param_name, int param_type, const void * param_addr, unsigned int param_size, short * ind_arr, int is_array) 將查詢語句的傳入引數,按照名字的形式與函式中的變數繫結。如果你使用陣列,那麼引數param_addr和ind_arr必須指向該陣列。
int sqlo_bind_by_pos(int sth, int param_pos, int param_type, const void * param_addr, unsigned int param_size, short * ind_arr, int is_array) 將查詢語句的傳出值,按照位置順序與函式中的變數繫結。
10)int sqlo_execute(int sth, int iterations) 執行查詢語句。“Iterations”可設為“1”。
11)在執行完資料庫操作後,我們可用int sqlo_commit (int dbh)提交操作,或用int sqlo_rollback(int dbh)回滾操作。
12)Libsqlora8還有其他一些操作函式,這裡就不一一列出了。
下面舉幾個例子說明這些函式如何使用。
cstr = "ocitest/ocitest"; //使用者名稱/口令
status = sqlo_init(0);
if (SQLO_SUCCESS != status)
{ printf ("sql_init failed. Exiting/n");
exit(1);
}
status = sqlo_connect(&dbh, cstr); // int dbh
以上原始碼,顯示瞭如何連線資料庫。
/* Select all and display */
char *select_stmt="SELECT cname, clength, colid FROM ocicolu";
if (0>(sd = sqlo_open(dbh, select_stmt, 0, NULL)))
{ printf("sqlo_open failed: %s/n", sqlo_geterror(dbh));
return 0;
}
while (0 == sqlo_fetch(sd,1))
{ v = sqlo_values(sd, NULL, 1);
printf("Result: %s/n",v);
}
if (0 > sqlo_close(sd))
{ printf("sqlo_open failed: %s/n", sqlo_geterror(dbh));
return 0;
}
以上例子展示了第一種查詢方法,顯然,這種方法較簡單,但不夠靈活。
char *update_stmt =
"UPDATE ocitest.upload_log SET upload_fresh = '0' where log_name = :1";
if (0 <= (sth = sqlo_prepare(dbh, update_stmt)))
{ if (SQLO_SUCCESS !=
(sqlo_bind_by_name(sth, ":1", SQLOT_STR, packet_name, 64, NULL, 0)
))
{ printf("sqlo_bind_param failed failed: %s/n", sqlo_geterror(dbh) );
return 0;
}
}
if (SQLO_SUCCESS != sqlo_execute(sth, 1))
{ printf("sqlo_execute failed: %s/n", sqlo_geterror(dbh) );
return 0;
}
上面的程式碼顯示瞭如何通過名字繫結變數,“:1”在Oracle SQL語句中表示為一個變數(名字隨意),在sqlo_bind_by_name函式中與packet_name變數繫結。在變數繫結完畢後,就可以呼叫 sqlo_execute函式來執行這個SQL語句。
好了,我們已經向大家介紹了Libsqlora8的基本使用方法,如果希望瞭解更多內容,Libsqlora8的程式包中帶有詳細的說明和例子,大家不妨自己鑽研一下。有什麼心得,歡迎和我聯絡。E-mail:nick_chen@yeah.net

【來源】

相關文章