程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Visual C++中的ODBC編程實例教程

Visual C++中的ODBC編程實例教程

編輯:關於C語言
 

ODBC是一種使用SQL的程序設計接口,使用ODBC使數據庫應用程序 的編寫者避免了與數據源相連接的復雜性。這項技術目前已經得到了 大多數DBMS廠商的廣泛支持。
  Microsoft Developer Studio為大多數標准的數據庫格式提供了 32位ODBC驅動器。這些標准數據格式包括有:SQL Server、Access、P aradox、dBase、FoxPro、Excel、Or acle以及Microsoft Text。如 果用戶希望使用其他數據格式,則需要安裝相應的ODBC驅動器及DBMS 。
  用戶使用自己的DBMS數據庫管理功能生成新的數據庫模式後,就 可以使用ODBC來登錄數據源。對用戶的應用程序來說,只要安裝有驅 動程序,就能注冊很多不同的數據庫。登錄數據庫的具體操作參見有 關ODBC的聯機幫助。
  MFC提供的ODBC數據庫類
  Visual C++的MFC基類庫定義了幾個數據庫類。在利用ODBC編程 時,經常要使用到 CDatabase(數據庫類)、CRecordSet(記錄集類)和 CRecordView(可視記錄集類)。
  CDatabase類對象提供了對數據源的連接,通過它可以對數據源進 行操作。
  CRecordSet類對象提供了從數據源中提取出的記錄集。CRecordS et對象通常用於兩種形式:動態行集(dynasets)和快照集(snapshots) 。動態行集能與其他用戶所做的更改保持同步,快照集則是數據的一 個靜態視圖。每種形式在記錄集被打開時都提供一組記錄,所不同的 是,當在一個動態行集裡滾動到一條記錄時,由其他用戶或應用程序中 的其他記錄集對該記錄所做的更改會相應地顯示出來。
  CRecordView類對象能以控件的形式顯示數據庫記錄,這個視圖是 直接連到一個CRec ordSet對象的表視圖。
  應用ODBC編程
  應用Visual C++的AppWizard可以自動生成一個ODBC應用程序框 架,步驟是:打開Fil e菜單的New選項,選取Projects,填入工程名,選 擇MFC AppWizard (exe),然後按AppWiza rd的提示進行操作。
  當AppWizard詢問是否包含數據庫支持時,如果想讀寫數據庫,那 麼選定Database vi ew with file support;如果想訪問數據庫的信 息而不想回寫所做的改變,那麼選定Data base view without file s upport。
  選擇了數據庫支持之後,Database Source 按鈕會被激活,選中它 去調用Data Optio ns對話框。在Database Options對話框中會顯示 出已向ODBC注冊的數據庫資源,選定所要操作的數據庫,如:Super_ES, 單擊OK後出現Select Database Tables對話框,其中列舉了選中的數 據庫包含的全部表;選擇要操作的表後,單擊OK。在選定了數據庫和數 據表之後,就可以按照慣例繼續進行AppWizard操作。
  特別需要指出的是:在生成的應用程序框架View類(如:CSuper_ES View)中,包含一個指向CSuper_ESSet對象的指針m_pSet,該指針由App Wizard建立,目的是在視表單和記錄集之間建立聯系,使得記錄集中的 查詢結果能夠很容易地在視表單上顯示出來。
  要使程序與數據源建立聯系,需用CDatebase::OpenEx()或CDatab ase::Open()函數來進行初始化。數據庫對象必須在使用它構造記錄 集對象之前初始化。
  下面舉例說明在Visual C++環境中ODBC的編程應用。
  1.查詢記錄
  查詢記錄使用CRecordSet::Open()和CRecordSet::Requery()成 員函數。在使用CRe cordSet類對象之前,必須使用CRecordSet::Open ()函數來獲得有效的記錄集。一旦已經使用過CRecordSet::Open()函 數,再次查詢時就可以應用CRecordSet::Requery()函數。
  在調用CRecordSet::Open()函數時,如果將一個已經打開的CData base對象指針傳給CRecordSet類對象的m_pDatabase成員變量,則使用 該數據庫對象建立ODBC連接;否則如果m_pDatabase為空指針,就新建 一個CDatabase類對象,並使其與缺省的數據源相連,然後進行CRecord Set類對象的初始化。缺省數據源由GetDefaultConnect()函數獲得。 也可以提供所需要的SQL語句,並以它來調用CRecordSet::Open()函數 ,例如:Super_ESSet.Open(A FX_DATABASE_USE_DEFAULT,strSQL);
  如果沒有指定參數,程序則使用缺省的SQL語句,即對在GetDefaul tSQL()函數中指定的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_s trSort為排序字符串,存放著 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以外,還可以使用參數化。利用參數 化可以更直觀、更方便地完成條件查詢任務。使用參數化的步驟如下 :
  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()、Mov ePrev()、MoveFirst()和MoveLast()來移動光標 。
  2.增加記錄
  增加記錄使用AddNew()函數,要求數據庫必須是以允許增加的方 式打開:
  m_pSet->AddNew(); //在表的末尾增加新記錄
  m_pSet->SetFieldNull(&(m_pSet->m_type), FALSE);
  m_pSet->m_type="電動機";
  ……
   //輸入新的字段值
  m_pSet->Update();
   //將新記錄存入數據庫
  m_pSet->Requery();
  //重建記錄集
  3.刪除記錄
  可以直接使用Delete()函數來刪除記錄,並且在調用Delete()函 數之後不需調用Upd ate()函數:
  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(); //將修改結果存入數據庫
  m_pSet->Requery();
  5.撤消操作
  如果用戶選擇了增加或者修改記錄後希望放棄當前操作,可以在 調用Update()函數之前調用:
  CRecordSet::Move(AFX_MOVE_REFRESH);來撤消增加或修改模式, 並恢復在增加或修改模式之前的當前記錄。其中,參數AFX_MOVE_REFR ESH的值為零。
  6.數據庫連接的復用
  在CRecordSet類中定義了一個成員變量m_pDatabase:
  CDatabase* m_pDatabase;
  它是指向對象數據庫類的指針。如果在CRecordSet類對象調用Op en()函數之前,將一個已經打開的CDatabase類對象指針傳給m_pDatab ase,就能共享相同的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類完成大多數的查詢操作,而且在C RecordSet::Open( )函數中也可以提供SQL語句,但是有時候我們還是 希望進行一些其他操作,例如建立新表、刪除表、建立新的字段等,這 時就需要使用CDatabase類直接執行SQL語句的機制。通過調用CDatab ase::ExecuteSQL()函數來完成SQL語句的直接執行:
  BOOL CDB::ExecuteSQLAndReportFailure(const CString& strS QL)
  {
  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無關性,因此在應用中應當慎用 此類操作。  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved