舉例介紹VC++中的ODBC編程
ODBC(怒放式數據庫Databnse連接)是一種應用SQL的程式設計接口,應用ODBC使數據庫Databnse實際運用程式的編寫者避免了與數據源相連接的復雜性。利用ODBC技能使得程式員從具體的DBMS中解脫出來,從而能夠遞減熱門軟件開發的務工量,縮短開發周期,并升高效率和熱門軟件的可靠性。這項技能目前已經得到了大多數DBMS廠商的廣泛支持。
Microsoft Developer Studio為大多數達標的數據庫Databnse各式幫助了32位ODBC驅動器。這一部份達標數據各式包括有:SQL Server、Access、Paradox、dBase、FoxPro、Excel、Oracle數據庫以及Microsoft Text。假如用戶期望應用更多有聯系數據各式,則需求安裝相應的ODBC驅動器及DBMS。
用戶應用自個的DBMS數據庫Databnse管制功能生成新的數據庫Databnse模式后,就能夠應用ODBC來登錄數據源。對用戶的實際運用程式來說,只要安裝有驅動程式,就能注冊很多不相同的數據庫Databnse。登錄數據庫Databnse的具體操作參見有關ODBC的聯機幫助。
一、MFC幫助的ODBC數據庫Databnse類
Visual C++的MFC基類庫定義了幾個數據庫Databnse類。在利用ODBC編程時,經常要應用到 CDatabase(數據庫Databnse類)、CRecordSet(記錄集類)和CRecordView(可視記錄集類)。
CDatabase類對象幫助了對數據源的連接,經過它能夠對數據源停止操作。
CRecordSet類對象幫助了從數據源中提取出的記錄集。CRecordSet對象通日常于兩種形式:動態行集(dynasets)和快照集(snapshots)。動態行集能與更多有聯系用戶所做的更改保持同步,快照集則是數據的唯一靜態視圖。每種形式在記錄集被打開時都幫助一組記錄,所不相同的是,當在唯一動態行集里滾動到一條記錄時,由更多有聯系用戶或實際運用程式中的更多有聯系記錄集對該記錄所做的更改會相應地呈現出來。
CRecordView類對象能以控件的形式呈現數據庫Databnse記錄,那個視圖是直接連到唯一CRecordSet對象的表視圖。
二、實際運用ODBC編程
實際運用Visual C++的AppWizard能夠自動生成唯一ODBC實際運用程式框架,步驟是:打開File菜單的New選項,選取Projects,填入工程名,選取MFC AppWizard (exe),然后按AppWizard的提示停止操作。
當AppWizard詢問也許包含數據庫Databnse支持時,假如想讀寫數據庫Databnse,那么選定Database view with file support;假如想來訪數據庫Databnse的消息而不想寫回所做的改變,那么選定Database view without file support。
選好數據庫Databnse支持之后,Database Source 按鈕會被激活,選中它去調用Data Options對話框。在Database Options對話框中會呈現出已向ODBC注冊的數據庫Databnse資源,選定所要操作的數據庫Databnse,如:Super_ES,單擊OK后呈現Select Database Tables對話框,其中列舉了選中的數據庫Databnse包含的全部表;選取要操作的表后,單擊OK。在選定了數據庫Databnse和數據表之后,就能夠按照慣例繼續停止AppWizard操作。
特別需求指出的是:在生成的實際運用程式框架View類(如:CSuper_ESView)中,包含唯一指向CSuper_ESSet對象的指針m_pSet,該指針由AppWizard建立,目的是在視表單和記錄集之間建立聯系,使得記錄集中的查詢結果能夠很簡易地在視表單上呈現出來。
要使程式與數據源建立聯系,需用CDateBase::OpenEx()或CDatabase::Open()參數來停止初始化。數據庫Databnse對象必需在應用它構造記錄集對象之前初始化。
#p#
三、舉例
1.查詢記錄
查詢記錄應用CRecordSet::Open()和CRecordSet::Requery()成員參數。在應用CRecordSet類對象之前,必需應用CRecordSet::Open()參數來獲得有效的記錄集。一旦已經應用過CRecordSet::Open()參數,再次查詢時就能夠實際運用CRecordSet::Requery()參數。
在調用CRecordSet::Open()參數時,假如將唯一已經打開的CDatabase對象指針傳給CRecordSet類對象的m_pDatabase成員變量,則應用該數據庫Databnse對象建立ODBC連接;否則假如m_pDatabase為空指針,就新建唯一CDatabase類對象,并使其與缺省的數據源相連,然后停止CRecordSet類對象的初始化。缺省數據源由GetDefaultConnect()參數獲得。也能夠幫助所需求的SQL語句,并以它來調用CRecordSet::Open()參數,
例如:
- Super_ESSet.Open(AFX_DATABASE_USE_DEFAULT,strSQL);
假如沒有指定參數parameter,程式則應用缺省的SQL語句,即對在GetDefaultSQL()參數中指定的SQL語句停止操作:
- CString CSuper_ESSet::GetDefaultSQL()
- {return _T(″[BsicData],[MinSize]″);}
對于GetDefaultSQL()參數返回的表名,對應的缺省操作是SELECT語句,即:
- SELECT * FROM BasicData,MainSize
在查詢過程中,也能夠利用CRecordSet的成員變量m_strFilter和m_strSort來執行要求查詢和結果排序。m_strFilter為濾掉字符串,存放著SQL語句中WHERE后的要求串;m_strSort為排序字符串,存放著SQL語句中ORDER BY后的字符串。如:
- Super_ESSet.m_strFilter=″TYPE=‘電動機’″;
- Super_ESSet.m_strSort=″VOLTAGE″;
- Super_ESSet.Requery();
對應的SQL語句為:
- SELECT * FROM BasicData,MainSize
- WHERE TYPE=‘電動機’
- ORDER BY VOLTAGE
除了直接賦值給m_strFilter以外,還能夠應用參數parameter化。利用參數parameter化能夠更直觀、更方便地完成要求查詢任務。應用參數parameter化的步驟如下:
S聲明參變量:
- CString p1;
- float p2;
S在構造參數中初始化參變量:
- p1=_T(″″);
- p2=0.0f;
- m_nParams=2;
S將參變量與對應列綁定:
- pFX->SetFieldType(CFieldExchange::param)
- RFX_Text(pFX,_T(″P1″),p1);
- RFX_Single(pFX,_T(″P2″),p2);
完成以上步驟后就能夠利用參變量停止要求查詢:
- m_pSet->m_strFilter=″TYPE=? AND VOLTAGE=?″;m_pSet->p1=″電動機″;
- m_pSet->p2=60.0;
- m_pSet->Requery();
參變量的值按綁定的順序替換查詢字串中的“?”通配符。
假如查詢的結果是多條記錄,能夠用CRecordSet類的參數Move()、MoveNext()、MovePrev()、MoveFirst()和MoveLast()來移動光標。
2.漸增記錄
漸增記錄應用AddNew()參數,要求數據庫Databnse必需是以允許漸增的方法打開:
- m_pSet->AddNew(); //在表的末尾漸增新記錄
- m_pSet->SetFieldNull(&(m_pSet->m_type), FALSE);
- m_pSet->m_type=″電動機″;
- ……
- //輸入新的字段值
- m_pSet->Update();
- //將新記錄存入數據庫Databnse
- m_pSet->Requery();
- //重建記錄集
3.刪除記錄
能夠直接應用Delete()參數來刪除記錄,并且在調用Delete()參數之后不需調用Update()參數:
- m_pSet->Delete();
- if (!m_pSet->IsEOF())
- m_pSet->MoveNext();
- else
- m_pSet->MoveLast();
4.改正記錄
改正記錄應用Edit()參數:
- m_pSet->Edit();
- //改正當前記錄
- m_pSet->m_type=″發電機″;
- //改正當前記錄字段值
- ……
- m_pSet->Update(); //將改正結果存入數據庫Databnse
- m_pSet->Requery();
5.撤消操作
假如用戶選取了漸增或者改正記錄后期望放棄當前操作,能夠在調用Update()參數之前調用:
CRecordSet::Move(AFX_MOVE_REFRESH)來撤消漸增或改正模式,并恢復在漸增或改正模式之前的當前記錄。其中,參數parameterAFX_MOVE_REFRESH的值為零。
6.數據庫Databnse連接的復用
在CRecordSet類中定義了唯一成員變量m_pDatabase:
- CDatabase* m_pDatabase;
它是指向對象數據庫Databnse類的指針。假如在CRecordSet類對象調用Open()參數之前,將唯一已經打開的CDatabase類對象指針傳給m_pDatabase,就能共享相同的CDatabase類對象。如:
- CDatabase m_db;
- CRecordSet m_set1,m_set2;
- m_db.Open(_T(″Super_ES″)); //建立ODBC連接
- m_set1.m_pDatabase=&m_db;
- //m_set1復用m_db對象
- m_set2.m_pDatabse=&m_db;
- // m_set2復用m_db對象
7.SQL語句的直接執行
雖然咱們能夠經過CRecordSet類完成大多數的查詢操作,而且在CRecordSet::Open()參數中也能夠幫助SQL語句,但是有時候咱們還那樣期望停止一部份更多有聯系操作,例如建立新表、刪除表、建立新的字段等,這時就需求應用CDatabase類直接執行SQL語句的機制。經過調用CDatabase::ExecuteSQL()參數來完成SQL語句的直接執行:
- BOOL CDB::ExecuteSQLAndReportFailure(const CString& strSQL)
- {TRY
- {m_pdb->ExecuteSQL(strSQL);
- //直接執行SQL語句}
- CATCH (CDBException,e)
- {CString strMsg;
- strMsg.LoadString(IDS_EXECUTE_SQL_FAILED);
- strMsg+=strSQL;
- return FALSE;}
- END_CATCH
- return TRUE;}
應當指出的是,由于不相同的DBMS幫助的數據操作語句不盡相同,直接執行SQL語句估計會破壞熱門軟件的DBMS無關性,因此在實際運用中應當慎用此類操作。
8.動態連接表
表的動態連接能夠利用在調用CRecordSet::Open()參數時指定SQL語句來呈現。同唯一記錄集對象只能來訪具有相同框架的表,否則查詢結果將無法與變量相對應。
- void CDB::ChangeTable()
- {
- if (m_pSet->IsOpen()) m_pSet->Close();
- switch (m_id)
- {
- case 0:
- m_pSet->Open(AFX_DB_USE_DEFAULT_TYPE,
- ″SELECT * FROM SLOT0″);
- //連接表SLOT0
- m_id=1;
- break;
- case 1:
- m_pSet->Open(AFX_DB_USE_DEFAULT_TYPE,
- ″SELECT * FROM SLOT1″); //連接表SLOT1
- m_id=0;
- break; }}
9.動態連接數據庫Databnse
能夠經過賦與CRecordSet類對象參數parameterm_pDatabase來連接不相同數據庫Databnse的CDatabase對象指針,從而呈現動態連接數據庫Databnse。
- void CDB::ChangeConnect()
- {CDatabase* pdb=m_pSet->m_pDatabase;
- pdb->Close();
- switch (m_id)
- {
- case 0:
- if (!pdb->Open(_T(″Super_ES″)))
- //連接數據源Super_ES
- {
- AfxMessageBox(″數據源Super_ES打開失敗″,″請檢查相應的ODBC連接″, MB_OK|MB_ICONWARNING);
- exit(0);
- }
- m_id=1;
- break;
- case 1:
- if (!pdb->Open(_T(″Motor″)))
- //連接數據源Motor
- {
- AfxMessageBox(″數據源Motor打開失敗″,″請檢查相應的ODBC連接″, MB_OK|MB_ICONWARNING);
- exit(0);
- }
- m_id=0;
- break; }}
總結:Visual C++中的ODBC類庫能夠幫助程式員完成絕大多數的數據庫Databnse操作。利用ODBC技能使得程式員從具體的DBMS中解脫出來,從而能夠遞減熱門軟件開發的務工量,縮短開發周期,并升高效率和熱門軟件的可靠性。希望本文能對你有幫助。