雖說以前也接觸過一些資料庫的應用,但是由於當時只是抱著非常淺顯的資料庫知識,做了一些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就是將通常的陣列增加乙個描述符,說明其維數 長度 邊界 元素型別等資...