查看單個文章
舊 2006-07-07, 11:54 PM   #5 (permalink)
psac
榮譽會員
 
psac 的頭像
榮譽勳章
UID - 3662
在線等級: 級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時
註冊日期: 2002-12-07
住址: 木柵市立動物園
文章: 17381
現金: 5253 金幣
資產: 33853 金幣
預設

Linux之ODBC安裝、配置和編程

Linux之ODBC安裝、配置和編程

本文主要內容是介紹ODBC的簡單原理,以及如何在Linux/Unix下進行ODBC的安裝、配置與編程。

一、 ODBC原理

ODBC 是Open Database Connect 即開放資料庫互連的簡稱,它是由Microsoft 公司於1991 年提出的一個用於訪問資料庫的統一界面標準,是應用程式和資料庫系統之間的中間件。它通過使用相應應用平台上和所需資料庫對應的驅動程式與應用程式的交互來實現對資料庫的操作,避免了在應用程式中直接呼叫與資料庫相關的操作,從而提供了資料庫的獨立性。

ODBC 主要由驅動程式和驅動程式管理器組成。驅動程式是一個用以支持ODBC 函數呼叫的模塊,每個驅動程式對應於相應的資料庫,當應用程式從基於一個資料庫系統移植到另一個時,只需更改應用程式中由ODBC 管理程式設定的與相應資料庫系統對應的別名即可。驅動程式管理器可鏈接到所有ODBC 應用程式中,它負責管理應用程式中ODBC 函數與DLL 中函數的綁定。

ODBC 使用層次的方法來管理資料庫,在資料庫通信結構的每一層,對可能出現依賴資料庫產品自身特性的地方,ODBC 都引入一個公共接頭以解決潛在的不一致性,從而很好地解決了基於資料庫系統應用程式的相對獨立性,這也是ODBC 一經推出就獲得巨大成功的重要原因之一。

從結構上分,ODBC 分為單束式和多束式兩類。

1. 單束式驅動程式
單束式驅動程式介於應用程式和資料庫之間,像中介驅動程式一樣資料提供一個統一的資料訪問方式。
當用戶進行資料庫操作時,應用程式傳遞一個ODBC 函數呼叫給ODBC 驅動程式管理器,由ODBC API 判斷該呼叫是由它直接處理並將結果返回還是送交驅動程式執行並將結果返回。
由上可見,單束式驅動程式本身是一個資料庫引擎,由它直接可完成對資料庫的操作,儘管該資料庫可能位於網路的任何地方。
2. 多束式驅動程式
多束式驅動程式負責在資料庫引擎和客戶應用程式之間傳送命令和資料,它本身並不執行資料處理操作而用於遠端操作的網路通信協議的一個界面。
前端應用程式提出對資料庫處理的請求,該請求轉給ODBC 驅動程式管理器,驅動程式管理器依據請求的情況,就地完成或傳給多束驅動程式,多束式驅動程式將請求翻譯為特定廠家的資料庫通信接頭(如Oracle 的SQLNet)所能理解的形式並交於接頭去處理,接頭把請求經網路傳送給服務器上的資料引擎,服務器處理完後把結果發回給資料庫通信接頭,資料庫接頭將結果傳給多束式ODBC 驅動程式,再由驅動程式將結果傳給應用程式。

很多程式員已經體會到了在Windows平台下的ODBC的益處,而在Linux/Unix下進行資料庫編程的時候卻不得不根據不同的資料庫來選擇特有的API進行編程,一旦資料庫發生了改變,所有與這些API相關的程式都必須進行修改。其實在Linux/Unix下現在也有了自己的ODBC,可以使我們的資料庫編程就像在Windows平台下一樣簡單。

下面我們開始介紹Linux/Unix下的ODBC:

二、 Linux/Unix下ODBC的安裝:

方法一:
先下載最新的unixODBC源碼包(http://www.unixodbc.org/unixODBC-2.2...述命令:

tar zxvf unixODBC-2.2.1.tar.gz
cd unixODBC-2.2.1
./configure --prefix=/usr/local/unixODBC-2.2.1 --includedir=/usr/include --libdir=/usr/lib -bindir=/usr/bin --sysconfdir=/etc
make
make install

安裝成功後,unixODBC所需的頭文件都被安裝到了/usr/inlucde下,編譯好的庫文件安裝到了/usr/lib下,與unixODBC相關的可執行文件安裝到了/usr/bin下,配置文件放到了/etc下。

方法二:
下載rpm包進行安裝,我們這裡以Red Hat 7.3為例:
unixODBC-2.2.0-5 RPM for i386(安裝包及源碼包)
ftp://speakeasy.rpmfind.net/linu ... BC-2.2.0-5.i386.rpm、ftp://ftp.rpmfind.net/linux/redh ... DBC-2.2.0-5.src.rpm)
unixODBC-devel-2.2.0-5 RPM for i386
ftp://speakeasy.rpmfind.net/linu ... el-2.2.0-5.i386.rpm)
直接將unixODBC-2.2.0-5.i386.rpm和unixODBC-devel-2.2.0-5.i386.rpm裝入系統就可以了,命令如下:

rpm -ivh unixODBC-2.2.0-5.i386.rpm
rpm -ivh unixODBC-devel-2.2.0-5.i386.rpm

安裝好以後,所需的各個部分與上面所列的位置相同。

三、 Linux/Unix下ODBC的配置:

執行ODBCConfig程式(在/usr/bin下)

和Windows下的ODBC設置視窗是不是很像?我想大家都能看懂吧。

第一步:安裝資料庫的ODBC驅動程式
Drivers這一欄中用來設置資料庫的驅動程式,點擊Add按鈕


Name一欄填入資料庫驅動的名稱,Description是資料庫驅動的描述,Driver是用來選擇資料庫驅動程式的,Setup是用來選擇資料庫驅動安裝程式的,如果你是按照上述安裝方法安裝的,這些程式都放在/usr/lib下,下面是資料庫驅動程式的列表:
資料庫 資料庫驅動程式 資料庫驅動安裝程式
TXT libodbctxt.so libodbctxtS.so
NNTP libnn.so libodbcnnS.so
MiniSQL libodbcmini.so libodbcminiS.so
PostgreSQL libodbcpsql.so libodbcpsqlS.so
MySQL (註釋) libodbcmyS.so
Sybase/MS SQL (註釋) libtdsS.so
Oracle (註釋) liboraodbcS.so

註釋:
MySQL、Sybase/MS SQL和Oracle的資料庫驅動可以在下列網址找到:
MySQL          http://www.unixodbc.org/myodbc.html
Sybase/MS SQL      http://www.freetds.org
Oracle           http://www.easysoft.org

MySQL的驅動程式MyODBC-2.50.39-4 RPM for i386以及源碼包:
ftp://speakeasy.rpmfind.net/linu ... -2.50.39-4.i386.rpm
ftp://ftp.redhat.com/pub/redhat/ ... C-2.50.39-4.src.rpm

選擇好驅動程式之後,點擊"√"儲存退出。

第二步:設置DSN
DSN分為User DSN、System DSN和File DSN三種,我們以System DSN為例。選中System DSN一欄以後,點擊Add…

列表中會列出你已經安裝好的資料庫驅動程式,我這裡只裝了MySQL和PostgreSQL,然後選擇你所要使用的驅動程式,然後點擊OK

我這裡使用的是MySQL的資料庫驅動,不同的資料庫,這個視窗的內容會有所不同。Name是資料源的名稱,Description是描述,Server可以選擇服務器,如果本機啟動了MySQL就可以選擇localhost,如果Port和Socket有特殊要求,再根據實際情況進行修改,Database是用來選擇資料庫的,下拉表菜單不一定包含所有的資料庫,你可以把自己已經創建好的資料庫名稱填寫在這裡。都配置好之後,點擊"√"儲存退出。

這樣Linux/Unix下的ODBC資料源就已經設置好了,大家還可以在ODBCConfig程式的Status欄中檢視ODBC的使用情況,在Advanced欄中設置是否做日誌或者啟動連接池,在About欄中,有一個Linux/Unix ODBC的示意圖,在Credits按鈕中可以看到所有開發者的名字的列表。 ODBCConfig程式中所有有關資料庫驅動程式的訊息被放在odbcinst.ini(在/etc下)文件中,有關DSN的訊息被放在odbc.ini(在/etc下)文件中,大家有興趣的話,可以自己去觀察一下。

第三步:使用DataManager程式瀏覽資料庫
執行DataManager程式之後就可以檢視Drivers、System DSN和User DSN這幾項內容,,在瀏覽資料庫的時候,可以在右面的SQL欄中輸入SQL語句,然後點擊人形按鈕就可以執行SQL語句,執行結果會在Results一欄中顯示出來

第四步:使用isql程式檢視資料庫
unixODBC還提供了命令台下檢視資料庫的程式,這就是isql,用法如下:

isql DSN [UID [PWD]] [options]

DSN 資料源名稱
UID 用戶ID
PWD 用戶密碼

Options:
-b 批處理,沒有提示字元的模式
-dx 設置列之間的分隔符為x
-w 將查詢結果輸出為HTML格式
-c 第一行輸出列名
--version 輸出isql的版本號

四、 Linux/Unix下ODBC的編程:

1、使用unixODBC提供的ODBC API進行編程:
在進行編程之前,我們來看一下ODBC API中的常用資料類型與我們在C語言中使用的資料類型的對應關係:
類型標識符 ODBC資料類型 C資料類型
SQL_C_CHAR SQLCHAR * unsigned char *
SQL_C_SSHORT SQLSMALLINT short int
SQL_C_USHORT SQLUSMALLINT unsigned short int
SQL_C_SLONG SQLINTEGER long int
SQL_C_FLOAT SQLREAL float
SQL_C_DOUBLE SQLDOUBLE, SQLFLOAT double
SQL_C_BINARY SQLCHAR * unsigned char *
SQL_C_TYPE_DATE SQL_DATE_STRUCT struct tagDATE_STRUCT {SQLSMALLINT year; SQLUSMALLINT month; SQLUSMALLINT day; } DATE_STRUCT;
SQL_C_TYPE_TIME SQL_TIME_STRUCT struct tagTIME_STRUCT {SQLUSMALLINT hour; SQLUSMALLINT minute; SQLUSMALLINT second; } TIME_STRUCT;

我們這裡使用的資料庫名稱為test(DSN),這個DSN使用的用戶名是root,密碼為空,表的名稱是web,字段情況如下:
>
字段名 資料類型
id integer
name char(40)
size integer

第一:設定ODBC環境控制碼並設置參數
首先我們需要聲明一個ODBC環境控制碼(SQLHENV),它可以用來獲得有關的ODBC環境訊息,我們需要呼叫SQLAllocHandle ( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &V_OD_Env )來獲得這個控制碼,V_OD_Env就是要分配的SQLHENV類型的環境控制碼。
分配好控制碼之後,你給它需要設定所使用的ODBC版本,你可以呼叫SQLSetEnvAttr ( V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0 ),SQL_ATTR_ODBC_VERSION是存放你定義的ODBC版本號的變數,SQL_OV_ODBC3則說明你的程式使用的是ODBC 3.0。

第二:設定連接控制碼並設置超時參數
我們需要聲明一個連接控制碼(SQLHDBC),用來存放資料庫連接訊息的,呼叫SQLAllocHandle ( SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc )獲得連接控制碼,V_OD_hdbc就是要分配的SQLHDBC類型的連接控制碼。
分配好之後,我們可以呼叫SQLSetConnectAttr ( V_OD_hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER *)5, 0 )來設定連接超時參數。

第三:連接資料庫
呼叫SQLConnect ( V_OD_hdbc, (SQLCHAR*) "Test", SQL_NTS, (SQLCHAR*) "root", SQL_NTS, (SQLCHAR*) "", SQL_NTS )連接我前面提到的資料庫,需要設定三個參數,就是資料庫名稱、用戶名和密碼(因為我的資料庫密碼為空,所以這裡的密碼也為空),後面的SQL_NTS的位置應該寫入這些參數的長度,如果寫的是SQL_NTS就是讓SQLConnect來決定參數的長度。

第四:分配SQL語句的控制碼並進行查詢:
需要聲明一個SQL語句的控制碼(SQLHSTMT),用來存放SQL語句訊息的,呼叫SQLAllocHandle ( SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt )來獲得這個控制碼,V_OD_hstmt就是我們要分配的SQLHSTMT類型的SQL語句控制碼。

我們的查詢語句是:

SELECT name, id FROM web ORDER BY id

執行這條查詢語句之後,查詢結果可能有很多行,但每行只有兩列,分別對應name和id,它們的資料類型為integer和char*,在ODBC中的資料類型標識符為SQL_C_ULONG和SQL_C_CHAR。我們需要先聲明這樣的兩個變數來存貯查詢結果:

SQLINTEGER V_OD_id;
char V_OD_buffer[200];

然後我們需要使用SQLBindCol函數把查詢結果和我們定義的變數進行綁定:

SQLBindCol(V_OD_hstmt,1,SQL_C_CHAR, &V_OD_buffer,150,&V_OD_err);
SQLBindCol(V_OD_hstmt,2,SQL_C_ULONG,&V_OD_id,150,&V_OD_err);

這裡的V_OD_err是用來存放錯誤訊息編號的變數,類型也是SQLINTEGER。
接下來,我們呼叫SQLExecDirect來進行查詢:

SQLExecDirect ( V_OD_hstmt, "SELECT dtname,iduser FROM web order by iduser", SQL_NTS );

我們可以用SQLNumResultCols ( V_OD_hstmt, &V_OD_colanz )來獲得結果的列數,也可以用SQLRowCount( V_OD_hstmt, &V_OD_rowanz )來獲得結果的條數,V_OD_colanz和V_OD_rowanz分別存儲相應的結果,類型分別為SQLSMALLINT和SQLINTEGER。
在讀取結果之前,我們需要呼叫SQLFetch ( V_OD_hstmt )語句,這個語句可以用來獲得第一條結果也可以用來都下一條,有點像next的感覺。然後我們就可以在V_OD_id和V_OD_buffer裡面獲得每條記錄的結果了。

第五:關於關閉連接和釋放控制碼
關閉資料庫的連接,呼叫SQLDisconnect ( V_OD_hdbc )就可以了,但在關閉資料庫之前需要先釋放SQL語句的控制碼,而且在關閉資料庫之後應該釋放連接控制碼和ODBC環境控制碼,語句如下(按正常的順序):

SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
SQLDisconnect(V_OD_hdbc);
SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);

第六:關於上述情況中的錯誤訊息處理
我們需要定義兩個變數:

long V_OD_erg;
SQLINTEGER V_OD_err;

SQLAllocHandle、SQLSetEnvAttr、SQLSetConnectAttr、SQLConnect、SQLExecDirect、SQLNumResultCols和SQLRowCount的呼叫結果都可以用V_OD_erg來存儲,V_OD_err可以獲得SQLBindCol中的錯誤訊息。

第七:獲得本機的DSN訊息
我們可以在聲明SQLHENV控制碼之後,使用SQLDataSources函數來獲得本機的DSN訊息。程式如下:

void OD_ListDSN(void)
{
char l_dsn[100],l_desc[100];
short int l_len1,l_len2,l_next;

l_next=SQL_FETCH_FIRST;
while( SQLDataSources(V_OD_Env,l_next,l_dsn, sizeof(l_dsn),
&l_len1, l_desc, sizeof(l_desc), &l_len2) == SQL_SUCCESS)
{
printf("Server=(%s) Beschreibung=(%s)
",l_dsn,l_desc);
l_next=SQL_FETCH_NEXT;
}
}

l_next變數是用來指定我們所要獲得的DSN的類別:
SQL_FETCH_FIRST 設定SQLDataSources()函數找到第一個可用的資料源(可以是User DSN,也可以是Systerm DSN)
SQL_FETCH_FIRST_USER 設定SQLDataSources()函數找到第一個User DSN
SQL_FETCH_FIRST_SYSTEM 設定SQLDataSources()函數找到第一個System DSN
SQL_FETCH_NEXT 找到下一個資料源,至於資料源類型則要根據前面的定義

到這裡,我們在Unix的C語言下面進行ODBC編程已經講完,上述ODBC API需要引用以下幾個頭文件(這些文件已經安裝到/usr/include下了):

#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>

另外如果大家使用GTK進行編程,由於到目前為止GTK還沒有加入專門處理資料庫的部件,所以大家可以在GTK中呼叫上述的ODBC API即可。

這裡附上例程供大家參考學習:

/* odbc.c
testing unixODBC
*/
#include <stdlib.h>
#include <stdio.h>
#include <odbc/sql.h>
#include <odbc/sqlext.h>
#include <odbc/sqltypes.h>

SQLHENV V_OD_Env; // Handle ODBC environment
long V_OD_erg; // result of functions
SQLHDBC V_OD_hdbc; // Handle connection

char V_OD_stat[10]; // Status SQL
SQLINTEGER V_OD_err,V_OD_rowanz,V_OD_id;
SQLSMALLINT V_OD_mlen,V_OD_colanz;
char V_OD_msg[200],V_OD_buffer[200];


int main(int argc,char *argv[])
{
// 1. allocate Environment handle and register version
V_OD_erg=SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Error AllocHandle
");
exit(0);
}
V_OD_erg=SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Error SetEnv
");
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
exit(0);
}
// 2. allocate connection handle, set timeout
V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Error AllocHDB %d
",V_OD_erg);
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
exit(0);
}
SQLSetConnectAttr(V_OD_hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER *)5, 0);
// 3. Connect to the datasource "web"
V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "Test", SQL_NTS,
(SQLCHAR*) "root", SQL_NTS,
(SQLCHAR*) "", SQL_NTS);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Error SQLConnect %d
",V_OD_erg);
SQLGetDiagRec(SQL_HANDLE_DBC, V_OD_hdbc,1,
V_OD_stat, &V_OD_err,V_OD_msg,100,&V_OD_mlen);
printf("%s (%d)
",V_OD_msg,V_OD_err);
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
exit(0);
}
printf("Connected !
");
V_OD_erg=SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Fehler im AllocStatement %d
",V_OD_erg);
SQLGetDiagRec(SQL_HANDLE_DBC, V_OD_hdbc,1, V_OD_stat,&V_OD_err,V_OD_msg,100,&V_OD_mlen);
printf("%s (%d)
",V_OD_msg,V_OD_err);
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
exit(0);
}
SQLBindCol(V_OD_hstmt,1,SQL_C_CHAR, &V_OD_buffer,150,&V_OD_err);
SQLBindCol(V_OD_hstmt,2,SQL_C_ULONG,&V_OD_id,150,&V_OD_err);

V_OD_erg=SQLExecDirect(V_OD_hstmt,"SELECT dtname,iduser FROM web order by iduser",SQL_NTS);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Error in Select %d
",V_OD_erg);
SQLGetDiagRec(SQL_HANDLE_DBC, V_OD_hdbc,1, V_OD_stat,&V_OD_err,V_OD_msg,100,&V_OD_mlen);
printf("%s (%d)
",V_OD_msg,V_OD_err);
SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
exit(0);
}
V_OD_erg=SQLNumResultCols(V_OD_hstmt,&V_OD_colanz);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
SQLDisconnect(V_OD_hdbc);
SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
exit(0);
}
printf("Number of Columns %d
",V_OD_colanz);
V_OD_erg=SQLRowCount(V_OD_hstmt,&V_OD_rowanz);
if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
{
printf("Number of RowCount %d
",V_OD_erg);
SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
SQLDisconnect(V_OD_hdbc);
SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
exit(0);
}
printf("Number of Rows %d
",V_OD_rowanz);
V_OD_erg=SQLFetch(V_OD_hstmt);
while(V_OD_erg != SQL_NO_DATA)
{
printf("Result: %d %s
",V_OD_id,V_OD_buffer);
V_OD_erg=SQLFetch(V_OD_hstmt);
} ;
SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
SQLDisconnect(V_OD_hdbc);
SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
return(0);
}

2.QT下進行ODBC編程
QT 3.0提供了Data Table、Data Browser和Data View三個與資料庫相關的控件。你可以在QT的Project設置你要連接的資料庫,Driver一欄中選擇QODBC3即可,其它選項你一看就明白了。上述的三個資料庫控件的使用方法可以參見QT中相應文檔,也很好使用的。

參考資料:

1. 微軟的ODBC主頁:http://www.microsoft.com/data/odbc/;
2. UnixODBC的主頁:http://www.unixodbc.org;
3. FreeODBC的主頁:http://www.jepstone.net/FreeODBC/;
4. EasySoft的主頁:http://www.easysoft.com;
5. TrollTech的QT 3.0文檔主頁:http://doc.trolltech.com/3.0/
__________________
http://bbsimg.qianlong.com/upload/01/08/29/68/1082968_1136014649812.gif
psac 目前離線  
送花文章: 3, 收花文章: 1631 篇, 收花: 3205 次