熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

在Visual C++中用ADO進行數據庫

2013-11-13 09:48:36  來源: .NET編程 

   生成應用程序框架並初始化OLE/COM庫環境
  
  創建一個標准的MFC AppWizard(exe)應用程序然後在使用ADO數據庫的InitInstance函數中初始化OLE/COM庫(因為ADO庫是一個COM DLL庫)
  本例為
  BOOL CAdotestDlg::OnInitDialog()
  {
  ::CoInitialize(NULL); //初始化OLE/COM庫環境
  }
  
  程序最後要調用 ::CoUninitialize()//釋放程序占用的COM 資源
  另外
  m_pRecordset>Close(); 注意!!!不要多次關閉!!!!!!!!!!!!
  m_pConnection>Close();
  m_pRecordset = NULL;
  m_pConnection = NULL;
  
   引入ADO庫文件
  
  使用ADO前必須在工程的stdafxh文件最後用直接引入符號#import引入ADO庫文件以使編譯器能正確編譯代碼如下
  #import C:\Program Files\common files\system\ado\msadodll no_namespace rename(EOFadoEOF)
  ADO類的定義是作為一種資源存儲在ADO DLL(msadodll)中在其內部稱為類型庫類型庫描述了自治接口以及C++使用的COM vtable接口當使用#import指令時在運行時Visual C++需要從ADO DLL中讀取這個類型庫並以此創建一組C++頭文件這些頭文件具有tli 和tlh擴展名讀者可以在項目的目錄下找到這兩個文件在C++程序代碼中調用的ADO類要在這些文件中定義
  程序的第三行指示ADO對象不使用名稱空間在有些應用程序中由於應用程序中的對象與ADO中的對象之間可能會出現命名沖突所以有必要使用名稱空間如果要使用名稱空間則可把第三行程序修改為 rename_namespace(AdoNS)第四行代碼將ADO中的EOF(文件結束)更名為adoEOF以避免與定義了自己的EOF的其他庫沖突
  
  .利用智能指針進行數據庫操作
  
  在CaboutDlg頭文件中定義兩個ADO智能指針類實例並在對話框中加入一個ListCtrl
  
  class CAdotestDlg : public CDialog
  {
  _ConnectionPtr m_pConnection;
  _RecordsetPtr m_pRecordset;
  ClistCtrl m_List;
  
  }
  
  ADO庫包含三個智能指針:_ConnectionPtr_CommandPtr和_RecordsetPtr
  
  _ConnectionPtr通常被用來創建一個數據連接或執行一條不返回任何結果的SQL語句如一個存儲過程
  _CommandPtr返回一個記錄集它提供了一種簡單的方法來執行返回記錄集的存儲過程和SQL語句在使用_CommandPtr接口時可以利用全局_ConnectionPtr接口也可以在_CommandPtr接口裡直接使用連接串_RecordsetPtr是一個記錄集對象與以上兩種對象相比它對記錄集提供了更多的控制功能如記錄鎖定游標控制等
  
  在使用ADO程序的事件響應中OnButton加入以下代碼:
  
  void CAdotestDlg::OnButton()
  {
  m_ListResetContent();
  m_pConnectionCreateInstance(_uuidof(Connection)); //初始化Connection指針
  m_pRecordsetCreateInstance(_uuidof(Recordset));//初始化Recordset指針
  
  try
  {
  m_pConnection>Open(DSN=ADOTest); //連接叫作ADOTest的ODBC數據源
  //注意這是連接不需要用戶ID或密碼的open 函數
  // 否則形式為 >Open(DSN=test;uid=sa;pwd=;);
  
  // 執行SQL語句得到一個記錄集把其指針賦值給m_pRecordset
  CString strSql=select * from middle;
  BSTR bstrSQL = strSqlAllocSysString();
  m_pRecordset>Open(bstrSQL(IDispatch*)m_pConnectionadOpenDynamicadLockOptimisticadCmdText);
  //adOpenDynamic動態 adLockOptimistic樂觀封鎖法 adCmdText文本查詢語句
  
  while(!m_pRecordset>adoEOF)//遍歷所有記錄
  {
  //取紀錄字段值方式之一
  _variant_t TheValue; //VARIANT數據類型
  TheValue = m_pRecordset>GetCollect(BIG_NAME);//得到字段BIG_NAME的值
  if(TheValuevt!=VT_NULL)
  m_ListAddString((char*)_bstr_t(TheValue));
  //將該值加入到列表控件中
  
  //取紀錄字段值方式之二
  // _bstr_t TheValue=m_pRecordset>Fields>GetItem(BIG_NAME)>Value;
  // CString temp=py();
  // m_ListAddString(temp);
  
  //數據類型轉換
  _variant_t vUsernamevBirthdayvIDvOld;
  TRACE(id:%d姓名:%s年齡:%d生日:%s\r\n
  vIDlVal(LPCTSTR)(_bstr_t)vUsernamevOldlVal(LPCTSTR)(_bstr_t)vBirthday);
  
  m_pRecordset>MoveNext();//轉到下一條紀錄
  }
  m_pRecordset>Close();
  m_pConnection>Close();
  }
  catch (_com_error e)//異常處理
  {
  AfxMessageBox(eErrorMessage());
  }
  m_pRecordset>Close(); //注意!!!不要多次關閉!!!!否則會出錯
  m_pConnection>Close();
  m_pRecordset = NULL;
  m_pConnection = NULL;
  }
  
  程序中通過_variant_t和_bstr_t轉換COM對象和C++類型的數據 _variant_t類封裝了OLE自治VARIANT數據類型在C++中使用_variant_t類要比直接使用VARIANT數據類型容易得多
  
  好編譯後該程序就能運行了但記住運行前要創建一個叫ADOTest的ODBC數據源該程序將把表middle中的BIG_NAME字段值顯示在列表控件中
  
  .執行SQL命令並取得結果記錄集
  
  為了取得結果記錄集我們定義一個指向Recordset對象的指針:_RecordsetPtr m_pRecordset;
  並為其創建Recordset對象的實例: m_pRecordsetCreateInstance(ADODBRecordset);
  SQL命令的執行可以采用多種形式下面我們一進行闡述
  
  ()利用Connection對象的Execute方法執行SQL命令
  Execute方法的原型如下所示:
  _RecordsetPtr Connection::Execute ( _bstr_t CommandText VARIANT * RecordsAffected long Options )
  其中CommandText是命令字串通常是SQL命令
  
  參數RecordsAffected是操作完成後所影響的行數
  
  參數Options表示CommandText中內容的類型Options可以取如下值之一
  adCmdText:表明CommandText是文本命令
  adCmdTable:表明CommandText是一個表名
  adCmdProc:表明CommandText是一個存儲過程
  adCmdUnknown:未知
  
  Execute執行完後返回一個指向記錄集的指針下面我們給出具體代碼並作說明
  _variant_t RecordsAffected;
  ///執行SQL命令CREATE TABLE創建表格usersusers包含四個字段:整形ID字符串username整形old日期型birthday
  m_pConnection>Execute(CREATE TABLE users(ID INTEGERusername TEXTold INTEGERbirthday DATETIME)
  &RecordsAffected
  adCmdText);
  ///往表格裡面添加記錄
  m_pConnection>Execute(INSERT INTO users(IDusernameoldbirthday) VALUES ( Washington//)&RecordsAffectedadCmdText);
  ///將所有記錄old字段的值加一
  m_pConnection>Execute(UPDATE users SET old = old+&RecordsAffectedadCmdText);
  ///執行SQL統計命令得到包含記錄條數的記錄集
  m_pRecordset = m_pConnection>Execute(SELECT COUNT(*) FROM users&RecordsAffectedadCmdText);
  _variant_t vIndex = (long);
  _variant_t vCount = m_pRecordset>GetCollect(vIndex);///取得第一個字段的值放入vCount變量
  上兩句可以寫成— _variant_t vCount = m_pRecordset>GetCollect((_variant_t)((long)));
  m_pRecordset>Close();///關閉記錄集
  CString message;
  messageFormat(共有%d條記錄vCountlVal);
  AfxMessageBox(message);///顯示當前記錄條數
  
  ()利用Command對象來執行SQL命令
  _CommandPtr m_pCommand;
  m_pCommandCreateInstance(ADODBCommand);
  _variant_t vNULL;
  vNULLvt = VT_ERROR;
  vNULLscode = DISP_E_PARAMNOTFOUND;///定義為無參數
  m_pCommand>ActiveConnection = m_pConnection;///非常關鍵的一句將建立的連接賦值給它
  m_pCommand>CommandText = SELECT * FROM users;///命令字串
  m_pRecordset = m_pCommand>Execute(&vNULL&vNULLadCmdText);///執行命令取得記錄集
  
  在這段代碼中我們只是用Command對象來執行了SELECT查詢語句Command對象在進行存儲過程的調用中能真正體現它的作用下次我們將詳細介紹
  
  ()直接用Recordset對象進行查詢取得記錄集
  實例——
  void CGmsaDlg::OnDBSelect()
  {
  // TODO: Add your control notification handler code here
  _RecordsetPtr Rs; //定義Recordset對象
  _bstr_t Connect(DSN=GMS;UID=sa;PWD=;);//定義連接字符串
  _bstr_t Source (SELECT count(*) FROM buaamdb); //要執行的SQL語句
  ::CoInitialize(NULL);  //初始化Rs對象
  HRESUL hr = RsCreateInstance( __uuidof( Recordset ) );
  //省略對返回值hr的判斷
  Rs>Open( Source
  Connect
  adOpenForwardOnly
  adLockReadOnly
   );
From:http://tw.wingwit.com/Article/program/net/201311/11640.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.