欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Visual C++ 中的ODBC編程的介紹

  發(fā)布時(shí)間:2012-05-14 09:27:12   作者:佚名   我要評(píng)論
ODBC 是一種使用SQL 的程序設(shè)計(jì)接口。使用ODBC 讓應(yīng)用程序的編寫者避免了與數(shù)據(jù)源相聯(lián)的復(fù)雜性
        一.概述
  ODBC 是一種使用SQL 的程序設(shè)計(jì)接口。使用ODBC 讓應(yīng)用程序的編寫者避免了與數(shù)據(jù)源相聯(lián)的復(fù)雜性。這項(xiàng)技術(shù)目前已經(jīng)得到了大多數(shù)DBMS 廠商們的廣泛支持。
  Microsoft Developer Studio 為大多數(shù)標(biāo)準(zhǔn)的數(shù)據(jù)庫格式提供了32 位ODBC 驅(qū)動(dòng)器。這些標(biāo)準(zhǔn)數(shù)據(jù)格式包括有:SQL Server、Access、Paradox、dBase、FoxPro、Excel、Oracle 以及Microsoft Text。如果用戶希望使用其他數(shù)據(jù)格式,用戶需要相應(yīng)的ODBC 驅(qū)動(dòng)器及DBMS。
  用戶使用自己的DBMS 數(shù)據(jù)庫管理功能生成新的數(shù)據(jù)庫模式后,就可以使用ODBC 來登錄數(shù)據(jù)源。對(duì)用戶的應(yīng)用程序來說,只要安裝有驅(qū)動(dòng)程序,就能注冊(cè)很多不同的數(shù)據(jù)庫。登錄數(shù)據(jù)庫的具體操作參見有關(guān)ODBC 的聯(lián)機(jī)幫助。
  二.MFC 提供的ODBC 數(shù)據(jù)庫類
  Visual C++ 的MFC 基類庫定義了幾個(gè)數(shù)據(jù)庫類。在利用ODBC 編程時(shí),經(jīng)常要使用到CDatabase( 數(shù)據(jù)庫類),CRecordSet( 記錄集類) 和CRecordView( 可視記錄集類)。其中:
  CDatabase 類對(duì)象提供了對(duì)數(shù)據(jù)源的連接,通過它你可以對(duì)數(shù)據(jù)源進(jìn)行操作。
  CRecordSet 類對(duì)象提供了從數(shù)據(jù)源中提取出的記錄集。CRecordSet 對(duì)象通常用于兩種形式:動(dòng)態(tài)行集(dynasets)和快照集(snapshots)。動(dòng)態(tài)行集能保持與其他用戶所做的更改保持同步??煺占瘎t是數(shù)據(jù)的一個(gè)靜態(tài)視圖。每一種形式在記錄集被打開時(shí)都提供一組記錄,所不同的是,當(dāng)你在一個(gè)動(dòng)態(tài)行集里滾動(dòng)到一條記錄時(shí),由其他用戶或是你應(yīng)用程序中的其他記錄集對(duì)該記錄所做的更改會(huì)相應(yīng)地顯示出來。
  CRecordView 類對(duì)象能以控制的形式顯示數(shù)據(jù)庫記錄。這個(gè)視圖是直接連到一個(gè)CRecordSet 對(duì)象的表視圖。
  三.應(yīng)用ODBC 編程
  應(yīng)用Visual C++ 的AppWizard 可以自動(dòng)生成一個(gè)ODBC 應(yīng)用程序框架。方法是:打開File 菜單的New 選項(xiàng),選取Projects,填入工程名,選擇MFC AppWizard (exe),然后按AppWizard 的提示進(jìn)行操作。當(dāng)AppWizard 詢問是否包含數(shù)據(jù)庫支持時(shí),如果你想讀寫數(shù)據(jù)庫,那么選定Database view with file support;而 ?閬敕夢(mèng)適?菘獾男畔⒍?幌牖匭此?齙母謀洌?敲囪《―atabase view without file support 選項(xiàng)就比較合適了。選擇了數(shù)據(jù)庫支持之后Database Source 按鈕會(huì)激活,選中它去調(diào)用Data Options 對(duì)話框。在Database Options 對(duì)話框中會(huì)顯示已向ODBC 注冊(cè)的數(shù)據(jù)庫資源,選定你所要操作的數(shù)據(jù)庫,如:Super_ES,單擊OK 后會(huì)出現(xiàn)Select Database Tables 對(duì)話框,其中列舉了你所選中的數(shù)據(jù)庫中包含的全部表,選擇你希望操作的表后,單擊OK。在選定了數(shù)據(jù)庫和數(shù)據(jù)表之后,你可以按照慣例繼續(xù)進(jìn)行AppWizard 操作。
  特別需要指出的是:在生成的應(yīng)用程序框架View 類(如:CSuper_ESView)中包含一個(gè)指向CSuper_ESSet 對(duì)象的指針m_pSet,該指針由AppWizard 建立,目的是在視表單和記錄集之間建立聯(lián)系,使得記錄集中的查詢結(jié)果能夠很容易地在視表單上顯示出來。有關(guān)m_pSet 的詳細(xì)用法可以參見Visual C++ Online Book。
  程序與數(shù)據(jù)語言建立聯(lián)系,使用CDatebase::OpenEx() 或CDatabase::Open() 函數(shù)來進(jìn)行初始化。數(shù)據(jù)庫對(duì)象必須在你使用它構(gòu)造一個(gè)記錄集對(duì)象之前被初始化。
  下面舉例說明在Visual C++ 環(huán)境中ODBC 的編程技巧:
  1 .查詢記錄
  查詢記錄使用CRecordSet::Open() 和CRecordSet::Requery() 成員函數(shù)。在使用CRecordSet 類對(duì)象之前,必須使用CRecordSet::Open() 函數(shù)來獲得有效的記錄集。一旦已經(jīng)使用過CRecordSet::Open() 函數(shù),再次查詢時(shí)就可以應(yīng)用CRecordSet::Requery() 函數(shù)。在調(diào)用CRecordSet::Open() 函數(shù)時(shí),如果已經(jīng)將一個(gè)已經(jīng)打開的CDatabase 對(duì)象指針傳給CRecordSet 類對(duì)象的m_pDatabase 成員變量,則使用該數(shù)據(jù)庫對(duì)象建立ODBC 連接;否則如果m_pDatabase 為空指針,就新建一個(gè)CDatabase 類對(duì)象并使其與缺省的數(shù)據(jù)源相連,然后進(jìn)行CRecordSet 類對(duì)象的初始化。缺省數(shù)據(jù)源由GetDefaultConnect() 函數(shù)獲得。你也可以提供你所需要的SQL 語句,并以它來調(diào)用CRecordSet::Open() 函數(shù),例如:
  Super_ESSet.Open(AFX_DATABASE_USE_DEFAULT,strSQL);
  如果沒有指定參數(shù),程序則使用缺省的SQL 語句,即對(duì)在GetDefaultSQL() 函數(shù)中指定的SQL 語句進(jìn)行操作:
  CString CSuper_ESSet::GetDefaultSQL()
  {return _T("[BasicData],[MainSize]");}
  對(duì)于GetDefaultSQL() 函數(shù)返回的表名,對(duì)應(yīng)的缺省操作是SELECT 語句,即:
  SELECT * FROM BasicData,MainSize
  查詢過程中也可以利用CRecordSet 的成員變量m_strFilter 和m_strSort 來執(zhí)行條件查詢和結(jié)果排序。m_strFilter 為過濾字符串,存放著SQL 語句中WHERE 后的條件串;m_strSort 為排序字符串,存放著SQL 語句中ORDER BY 后的字符串。如:
  Super_ESSet.m_strFilter="TYPE=電動(dòng)機(jī)";
  Super_ESSet.m_strSort="VOLTAGE";
  Super_ESSet.Requery();
  對(duì)應(yīng)的SQL語句為:
  SELECT * FROM BasicData,MainSize
  WHERE TYPE=電動(dòng)機(jī)
  ORDER BY VOLTAGE
  除了直接賦值給m_strFilter 以外,還可以使用參數(shù)化。利用參數(shù)化可以更直觀,更方便地完成條件查詢?nèi)蝿?wù)。使用參數(shù)化的步驟如下:
  (1) .聲明參變量:
  CString p1;
  float p2;
  (2) .在構(gòu)造函數(shù)中初始化參變量
  p1=_T("");
  p2=0.0f;
  m_nParams=2;
  (3) .將參變量與對(duì)應(yīng)列綁定
  pFX- >SetFieldType(CFieldExchange::param)
  RFX_Text(pFX,_T("P1"),p1);
  RFX_Single(pFX,_T("P2"),p2);
  完成以上步驟之后就可以利用參變量進(jìn)行條件查詢了:
  m_pSet- >m_strFilter="TYPE=? AND VOLTAGE=?";
  m_pSet- >p1=" 電動(dòng)機(jī)";
  m_pSet- >p2=60.0;
  m_pSet- >Requery();
  參變量的值按綁定的順序替換查詢字串中的"?" 適配符。
  如果查詢的結(jié)果是多條記錄的話,可以用CRecordSet 類的函數(shù)Move(),MoveNext(),MovePrev(),MoveFirst() 和MoveLast() 來移動(dòng)光標(biāo)。
  2 .增加記錄
  增加記錄使用AddNew() 函數(shù),要求數(shù)據(jù)庫必須是以允許增加的方式打開:
  m_pSet- >AddNew(); //在表的末尾增加新記錄
  m_pSet- >SetFieldNull(&(m_pSet- >m_type), FALSE);
  m_pSet- >m_type=" 電動(dòng)機(jī)";
  ... //輸入新的字段值
  m_pSet- > Update(); //將新記錄存入數(shù)據(jù)庫
  m_pSet- >Requery(); //重建記錄集
  3 .刪除記錄
  直接使用Delete() 函數(shù),并且在調(diào)用Delete() 函數(shù)之后不需調(diào)用Update() 函數(shù):
  m_pSet- >Delete();
  if (!m_pSet- >IsEOF())
  m_pSet- >MoveNext();
  else
  m_pSet- >MoveLast();
  4 .修改記錄
  修改記錄使用Edit() 函數(shù):
  m_pSet- >Edit(); //修改當(dāng)前記錄
  m_pSet- >m_type="發(fā)電機(jī)";
  //修改當(dāng)前記錄字段值
  ...
  m_pSet- >Update(); //將修改結(jié)果存入數(shù)據(jù)庫
  m_pSet- >Requery();
  5 .撤消操作
  如果用戶選擇了增加或者修改記錄后希望放棄當(dāng)前操作,可以在調(diào)用Update() 函數(shù)之前調(diào)用:
  CRecordSet::Move(AFX_MOVE_REFRESH);
  來撤消增加或修改模式,并恢復(fù)在增加或修改模式之前的當(dāng)前記錄。其中的參數(shù)AFX_MOVE_REFRESH 的值為零。
  6 .?dāng)?shù)據(jù)庫連接的復(fù)用
  在CRecordSet 類中定義了一個(gè)成員變量m_pDatabase:
  CDatabase* m_pDatabase;
  它是指向?qū)ο髷?shù)據(jù)庫類的指針。如果在CRecordSet 類對(duì)象調(diào)用Open() 函數(shù)之前,將一個(gè)已經(jīng)打開的CDatabase 類對(duì)象指針傳給m_pDatabase,就能共享相同的CDatabase 類對(duì)象。如:
  CDatabase m_db;
  CRecordSet m_set1,m_set2;
  m_db.Open(_T("Super_ES"));//建立ODBC連接
  m_set1.m_pDatabase=&m_db;
  //m_set1復(fù)用m_db對(duì)象
  m_set2.m_pDatabse=&m_db;
  // m_set2復(fù)用m_db對(duì)象
  7 .SQL 語句的直接執(zhí)行
  雖然通過CRecordSet 類,我們可以完成大多數(shù)的查詢操作,而且在CRecordSet::Open() 函數(shù)中也可以提供SQL 語句,但是有的時(shí)候我們還想進(jìn)行一些其他操作,例如建立新表,刪除表,建立新的字段等等,這時(shí)就需要使用到CDatabase 類的直接執(zhí)行SQL 語句的機(jī)制。通過調(diào)用CDatabase::ExecuteSQL() 函數(shù)來完成SQL 語句的直接執(zhí)行:
  BOOL CDB::ExecuteSQLAndReportFailure(const CString& strSQL)
  {
  TRY
  {
  m_pdb- >ExecuteSQL(strSQL);//直接執(zhí)行SQL語句
  }
  CATCH (CDBException,e)
  {
  CString strMsg;
  strMsg.LoadString(IDS_EXECUTE_SQL_FAILED);
  strMsg+=strSQL;
  return FALSE;
  }
  END_CATCH
  return TRUE;
  }
  應(yīng)當(dāng)指出的是,由于不同DBMS 提供的數(shù)據(jù)操作語句不盡相同,直接執(zhí)行SQL 語句可能會(huì)破壞軟件的DBMS 無關(guān)性,因此在應(yīng)用中應(yīng)當(dāng)慎用此類操作。
  8 .動(dòng)態(tài)連接表
  表的動(dòng)態(tài)連接可以利用在調(diào)用CRecordSet::Open() 函數(shù)時(shí)指定SQL 語句來實(shí)現(xiàn)。同一個(gè)記錄集對(duì)象只能訪問具有相同結(jié)構(gòu)的表,否則查詢結(jié)果將無法與變量相對(duì)應(yīng)。
  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 .動(dòng)態(tài)連接數(shù)據(jù)庫
  由于與數(shù)據(jù)庫的連接是通過CDatabase 類對(duì)象來實(shí)現(xiàn)的,所以我們可以通過賦與CRecordSet 類對(duì)象參數(shù)m_pDatabase 以連接不同數(shù)據(jù)庫的CDatabase 對(duì)象指針,就可以動(dòng)態(tài)連接數(shù)據(jù)庫。
  void CDB::ChangeConnect()
  {
  CDatabase* pdb=m_pSet- >m_pDatabase;
  pdb- >Close();
  switch (m_id)
  {
  case 0:
  if (!pdb- >Open(_T("Super_ES")))
  //連接數(shù)據(jù)源Super_ES
  {
  AfxMessageBox("數(shù)據(jù)源Super_ES打開失敗,"
  "請(qǐng)檢查相應(yīng)的ODBC連接", MB_OK|MB_ICONWARNING);
  exit(0);
  }
  m_id=1;
  break;
  case 1:
  if (!pdb- >Open(_T("Motor")))
  //連接數(shù)據(jù)源Motor
  {
  AfxMessageBox("數(shù)據(jù)源Motor打開失敗,"
  "請(qǐng)檢查相應(yīng)的ODBC連接", MB_OK|MB_ICONWARNING);
  exit(0);
  }
  m_id=0;
  break;
  }
  }
  四.總結(jié)
  Visual C++ 中的ODBC 類庫可以幫助程序員完成絕大多數(shù)的數(shù)據(jù)庫操作。利用ODBC 技術(shù)使得程序員從具體的DBMS 中解脫出來,從而極大的減少了軟件開發(fā)的工作量,縮短開發(fā)周期,提高了效率和軟件的可靠性。本文總結(jié)的筆者從事軟件開發(fā)的一些經(jīng)驗(yàn)心得希望對(duì)從事ODBC 開發(fā)的工作者有所幫助。

相關(guān)文章

最新評(píng)論