學會使用ODBC API

2022-08-12 04:27:16 字數 3971 閱讀 7538

雖說以前也接觸過一些資料庫的應用,但是由於當時只是抱著非常淺顯的資料庫知識,做了一些sql語句上的操作,安裝-配置-連線這一系列的流程全是自己照著例子實現的,大概記住的也就是odbc、ado之類,也簡單的理解了一下,當共享使用資料庫時最好使用odbc的方式,而本地的資料庫就可以使用ado。

具體區別這些連線方式倒是就可以好好學習一下了:

簡單的來說,odbc和ado都是微軟提供的資料庫訪問方式,ado是乙個com元件,而odbc則是一種標準的訪問方式,結束了資料庫訪問和資料庫相關的局面,只不過兩者實現的不同,所以在不同應用的表象上不同罷了(不對的話請指出,只看了wiki上的一點介紹,沒有系統學習)。

通過分析考慮到將來可能會採用共享資料庫的方式,此外對於com自己也不是很熟悉,所以還是使用odbc的方式比較好,使用odbc的方式就很多了,但是由於我並不是程式開發人員,現在負責維護,不大敢做大手術,所以就選擇了odbc api,這就相當於使用windos api和mfc一樣,雖然api複雜,但是相對自由很多。

首先要在程式中新增幾個依賴項

#include #include 

#include

#pragma comment(lib,"odbc32.lib")

#pragma comment(lib,"odbccp32.lib")

前兩個標頭檔案分別代表基本的odbc api和高階的odbc api,最後乙個好像是包含了更高階的api(暫時這麼理解吧),一般用到前兩個即可,odbc32.lib對應sql.h和sqlext.h,odbccp32.lib對應odbcinst.h。

所有使用資料庫的過程無非是這樣乙個流程:

1. 想辦法建立資料庫的連線

2. 想辦法執行sql語句,並使用結果

3. 不用時關閉連線,以免下次訪問報錯

對於像我這樣不常用資料庫的菜鳥來說,這樣的方式足夠完成我所面臨的問題了,諸如互斥訪問、分布式之類的問題還是暫時留給高手們考慮吧。

在我們要連線資料庫的類中,或者全域性變數下建立相關的變數

sqlhenv m_henviroment;//資料庫環境控制代碼,屬於老大級別的

sqlhdbc m_hdatabaseconnection;//資料庫連線控制代碼,老大以後就是他了,有了他資料庫就連線上了

sqlhstmt m_hstatement;//執行語句控制代碼,最終執行sql於句的控制代碼

使用odbc api建立資料庫連線分為3部分:申請環境控制代碼,使用環境控制代碼申請連線控制代碼、使用連線控制代碼連線資料庫。

/* 申請環境變數 */

sqlreturn l_uireturn = sqlallochandle(sql_handle_env,null,&m_henviroment);

//申請各種控制代碼都靠這個函式,引數1是要申請控制代碼的型別,引數2為申請該控制代碼依靠的控制代碼(老大沒依靠,所以是null),申請結果在引數3中儲存

//返回值代表著執行的意義,如下面判斷,success_with_info相當於是警告,雖然成功了,但是可能有問題

if (l_uireturn != sql_success && l_uireturn !=sql_success_with_info)

sqlsetenvattr(m_henviroment,sql_attr_odbc_version,(sqlpointer)sql_ov_odbc3,sql_is_integer);

l_uireturn = sqlallochandle(sql_handle_dbc,m_henviroment,&m_hdatabaseconnection);

if (l_uireturn != sql_success && l_uireturn !=sql_success_with_info)

sqlwchar * l_swcadsnname = _t("

");//資料來源名稱

sqlwchar * l_swcausername = _t("

");//使用者名稱

sqlwchar * l_swcapassword = _t("

");//密碼

l_uireturn =sqlconnect(m_hdatabaseconnection,l_swcadsnname,sql_nts

,l_swcausername,sql_nts

,l_swcapassword,sql_nts);

if (l_uireturn != sql_success && l_uireturn !=sql_success_with_info)

/*

申請於句句柄

*/sqlreturn l_uireturn = sqlallochandle(sql_handle_stmt,m_hdatabaseconnection,&m_hstatement);

if (l_uireturn != sql_success && l_uireturn !=sql_success_with_info)

/*構造sql語句

*/cstring l_cstrsql;

l_cstrsql.format(_t(

"select * from 資料表

"));

/*執行sql語句

*/l_uireturn =sqlexecdirect(m_hstatement,l_cstrsql.getbuffer(),sql_nts);

if (l_uireturn != sql_success && l_uireturn !=sql_success_with_info)

/*獲得返回結果的行數

*/sqlinteger l_siidcount = 0

; l_uireturn = sqlrowcount(m_hstatement,&l_siidcount);

/*開始讀取結果

*///

讀取第一行時要呼叫,以後依次呼叫就可以下移行數,直到不返回sql_success

l_uireturn =sqlfetch(m_hstatement);

if (l_uireturn != sql_success && l_uireturn !=sql_success_with_info)

sqlinteger l_siid;

sqlinteger l_siidlength = 0

;

/*獲得資料

*/sqlgetdata(m_hstatement,

1,sql_c_ulong,&l_siid,0,&l_siidlength);

//引數1為執行語句的控制代碼,引數2為所要得到的資料位於的列數(sql語句中),引數3為資料型別,這個比較多,需要看一下msdn

//引數4為儲存的位置(位址),引數5為引數4可用的位置,既然引數3已設定為長整型,所以這裡可使用0

//引數6為實際返回的長度

/*釋放語句控制代碼

*/sqlfreehandle(sql_handle_stmt,m_hstatement);

sqlfreehandle(sql_handle_stmt,m_hstatement);

sqlfreehandle(sql_handle_dbc,m_hdatabaseconnection);

sqlfreehandle(sql_handle_env,m_henviroment);

客戶來了新的需求-交換:當時的原型為,他們那裡有一套嵌入式的系統負責從感測器上獲得資料,他們也有一套相應的管理程式,但是但是那套管理程式缺乏顯示效果,所以需要利用我們所做的系統進行顯示。

根據這個需求,我們(其實只有我乙個人)進行了分析,當時客戶提出的最好使用socket變成來實現,按說這也是乙個不錯的主意,自由且不是很複雜,但是帶來的後果就可能是以後如果各種互動多了以後,極難維護。所以覺得使用乙個共同的資料庫比較好,他們負責生成資料,我們負責讀取並顯示,這種好處是可以最大的運用程式的效率,不用總是考慮socket能不能及時的接收到,而且責任分明,也方便維護,但是現在考慮這種方式的缺點就是,我們的**有一定的重複,他們的客戶端就有一些根據資料條件進行「分類」的意思,我們這邊則要根據資料進行不同的顯示效果。

學會使用SafeArray

學會使用safearray也是很重要的,因為在ado程式設計中經常要用。它的主要目的是用於automation中的陣列型引數的傳遞。因為在網路環境中,陣列是不能直接傳遞的,而必須將其包裝成safearray。實質上safearray就是將通常的陣列增加乙個描述符,說明其維數 長度 邊界 元素型別等資...

學會使用Git

作為一名人民的好幹部,如果希望被惦記,可以學我們的鄭書記,將自己和藹可親的光輝形象搬上檯曆 作為一名有夢想有追求而又不知道如何出名的人,你可以參考對岸的 超想被包養 社團。而作為乙個核心愛好者,要想成為一名核心開發者,為核心貢獻自己的 我們必須要能夠與其他眾多的核心開發者協同工作,這就意味著應該能夠...

學會使用SafeArray

學會使用safearray也是很重要的,因為在ado程式設計中經常要用。它的主要目的是用於automation中的陣列型引數的傳遞。因為在網路環境中,陣列是不能直接傳遞的,而必須將其包裝成safearray。實質上safearray就是將通常的陣列增加乙個描述符,說明其維數 長度 邊界 元素型別等資...