国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項超值服

開通VIP
MFC集成數(shù)據(jù)庫訪問

本文描述了如何在MFC的文檔/視圖/框架架構(gòu)中使用ADO和ADOX來創(chuàng)建和打開數(shù)據(jù)庫。

預(yù)備閱讀

在閱讀本文之前,建議先對COM,數(shù)據(jù)庫和MFC的文檔/視圖/框架有一個基本的了解。推薦閱讀下列文章

MFC技術(shù)文章

微軟知識庫文章

Office VBA參考

步驟

  1. 在計算機(jī)上安裝MDAC2.5以上版本
  2. 打開VC。首先,我們使用MFC應(yīng)用程序向?qū)?chuàng)建一個標(biāo)準(zhǔn)的MDI程序,這里我為這個工程起名為Passport,然后在stdafx.h中導(dǎo)入ADOX
    #include <shlwapi.h>
    #import "c:\Program Files\Common Files\system\ado\Msado15.dll"  rename("EOF","adoEOF") rename("DataTypeEnum","adoDataTypeEnum")
    #import "c:\Program Files\Common Files\System\ADO\Msadox.dll"  rename("EOF", "adoXEOF") rename("DataTypeEnum","adoXDataTypeEnum")
    #import "c:\PROGRAM FILES\COMMON FILES\System\ado\MSJRO.DLL"

    根據(jù)你的計算機(jī)上ADO的安裝路徑,這里的路徑可能有所不同。
  3. 在文檔類中聲明數(shù)據(jù)庫連接 ADODB::_ConnectionPtr m_pConn;和記錄集 ADODB::_RecordsetPtr m_pSet;,并且重載文檔類的DeleteContents() 、OnNewDocument()和OnOpenDocument()函數(shù),用于斷開數(shù)據(jù)庫連接,創(chuàng)建數(shù)據(jù)庫和表,以及打開現(xiàn)有的數(shù)據(jù)庫。
    (作者的抱怨:CSDN文章中心該改改了,代碼排版這么麻煩)
    void CPassportDoc::DeleteContents()
    {
     try
     {
      if(m_pSet){
       ESRecordsetClose(m_pSet);
      }
      if(m_pConn)
       if(m_pConn->State&ADODB::adStateOpen)
        m_pConn->Close();
      m_pConn=NULL; 
     }
     catch(_com_error &e){
      ESErrPrintProviderError(m_pConn);
      ESErrPrintComError(e);
     }
     CDocument::DeleteContents();
    }BOOL CPassportDoc::OnNewDocument()
    {
     if (!CDocument::OnNewDocument())
      return FALSE;
     CFileDialog dlgFile(FALSE, _T(".mdb"), NULL, OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, _T("Access 數(shù)據(jù)庫 (*.mdb)|*.mdb|全部文件(*.*)|*.*||"));
     if (dlgFile.DoModal() != IDOK)
      return FALSE;
     CString strDBPath=dlgFile.GetPathName();
     if(!CreateDB(strDBPath))return FALSE;
     //create
     CString strConnect;
     
     strConnect.Format(_T("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s"),strDBPath);
     COleVariant Connect(strConnect); 
     // TODO: add reinitialization code here
     // (SDI documents will reuse this document)
     try{
      m_pConn.CreateInstance(_T("ADODB.Connection"));
      m_pSet.CreateInstance(_T("ADODB.Recordset"));
      m_pConn->PutCommandTimeout(30);
      m_pConn->PutConnectionTimeout(30);
      m_pConn->put_CursorLocation(ADODB::adUseClient);
      m_pConn->Open(_bstr_t(strConnect),_bstr_t(),_bstr_t(),ADODB::adConnectUnspecified);
      ::ESRecordsetOpen(_T("Passport"),m_pConn,m_pSet);
      SetPathName(strDBPath);
      return TRUE;
     }
     catch(_com_error &e){
      ESErrPrintProviderError(m_pConn);
      ESErrPrintComError(e);
     }
     catch(...){
     }
     m_pConn=NULL;
     return FALSE;
    }
    BOOL CPassportDoc::OnOpenDocument(LPCTSTR lpszPathName)
    {
     if (!CDocument::OnOpenDocument(lpszPathName))
      return FALSE;
     ADODB::_ConnectionPtr tempConnn;
     CString strConnect;
     CString strDBPath=lpszPathName;
     strConnect.Format(_T("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s"),strDBPath);
     COleVariant Connect(strConnect); 
     // TODO: add reinitialization code here
     // (SDI documents will reuse this document)
     try{
      tempConnn.CreateInstance(_T("ADODB.Connection"));
      tempConnn->PutCommandTimeout(30);
      tempConnn->PutConnectionTimeout(30);
      tempConnn->put_CursorLocation(ADODB::adUseClient);
      tempConnn->Open(_bstr_t(strConnect),_bstr_t(),_bstr_t(),ADODB::adConnectUnspecified);
      SetPathName(strDBPath);
      m_pConn=tempConnn;
      m_pSet=NULL;
      m_pSet.CreateInstance(_T("ADODB.Recordset"));
      ::ESRecordsetOpen(_T("Passport"),m_pConn,m_pSet);
      UpdateAllViews(NULL,UpdateHintRefresh);
      return TRUE;
     }
     catch(_com_error &e){
      ESErrPrintProviderError(tempConnn);
      ESErrPrintComError(e);
     }
     catch(...){
     } 
     return FALSE;
    }
  4. 編寫一個輔助函數(shù),用于創(chuàng)建數(shù)據(jù)庫、表和索引
    BOOL CPassportDoc::CreateDB(LPCTSTR lpszFile)
    {
     if(::PathFileExists(lpszFile)){
      CString strTemp;
      strTemp.Format(IDS_TARGET_EXISTS,lpszFile);
      AfxMessageBox(lpszFile);
      return FALSE;
     }
     ADODB::_ConnectionPtr tempConnn;
     ADOX::_CatalogPtr pCatalog = NULL;
     ADOX::_TablePtr  pTable = NULL;
        ADOX::_IndexPtr pIndexNew  = NULL;
        ADOX::_IndexPtr pIndex  = NULL;
     CString strConnect;
     CString strDBPath=lpszFile;
     strConnect.Format(_T("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s"),strDBPath);
     COleVariant Connect(strConnect); 
     try{
      pCatalog.CreateInstance(_T("ADOX.Catalog"));
      pCatalog->Create((LPCTSTR)strConnect);//創(chuàng)建數(shù)據(jù)庫
      tempConnn.CreateInstance(_T("ADODB.Connection"));
      tempConnn->PutCommandTimeout(30);
      tempConnn->PutConnectionTimeout(30);
      tempConnn->put_CursorLocation(ADODB::adUseClient);
      tempConnn->Open(_bstr_t(strConnect),_bstr_t(),_bstr_t(),ADODB::adConnectUnspecified);
      pCatalog->PutActiveConnection(_variant_t((IDispatch *) tempConnn));
      pTable.CreateInstance(_T("ADOX.Table"));
      pTable->ParentCatalog =pCatalog;
      pTable->Name="Passport";
      ADOX::ColumnsPtr pCols =pTable->Columns;
      pCols->Append(_T("RecordID")  ,ADOX::adInteger,0);//自動編號字段
      pCols->Append(_T("Name")   ,ADOX::adWChar,255);//文本字段
      pCols->Append(_T("DateOfBirth")  ,ADOX::adDate,0);//日期字段
      pCols->Append(_T("OtherInfo"),ADOX::adLongVarWChar,0);//備注字段
      pCatalog->Tables->Refresh();
      long lCount=pCols->Count;
      for(long i=0;i<lCount;i++){
       pCols->GetItem(i)->ParentCatalog =pCatalog;//重要!設(shè)置Catalog,參見Q201826 PRB: Error 3265 When You Access Properties Collection
       ADOX::PropertiesPtr pProperties=pCols->GetItem(i)->Properties;
       if(pProperties){//這里是用于調(diào)試的屬性顯示代碼
        long lp=pProperties->Count;
        TRACE("Properties for Col %s\r\n",(LPCTSTR)pCols->GetItem(i)->Name);
        for(long j=0;j<lp;j++){
         TRACE("\rProperty %s:%s\r\n",g_GetValueString(pProperties->GetItem(j)->Name)
          ,g_GetValueString(pProperties->GetItem(j)->Value));
        }
       }
      }
      pCols->GetItem(_T("RecordID"))->Properties->GetItem(_T("Description"))->Value=_T("記錄編號");//注釋
      pCols->GetItem(_T("RecordID"))->Properties->GetItem(_T("AutoIncrement"))->Value=true;//自動編號
      pCols->GetItem(_T("Name"))->Properties->GetItem(_T("Jet OLEDB:Compressed UniCode Strings"))->Value=true;
      pCols->GetItem(_T("Name"))->Properties->GetItem(_T("Description"))->Value=_T("姓名");
      pCols->GetItem(_T("DateOfBirth"))->Properties->GetItem(_T("Description"))->Value=_T("出生日期");
     pCols->GetItem(_T("OtherInfo"))->Properties->GetItem(_T("Jet OLEDB:Compressed UniCode Strings"))->Value=true;
      pCols->GetItem(_T("OtherInfo"))->Properties->GetItem(_T("Description"))->Value=_T("其他信息");
      pCatalog->Tables->Append(_variant_t ((IDispatch*)pTable));//添加表
      pCatalog->Tables->Refresh();//刷新
      pIndexNew.CreateInstance(_T("ADOX.Index"));
      pIndexNew->Name = "RecordID";//索引名稱
      pIndexNew->Columns->Append("RecordID",ADOX::adInteger,0);//索引字段
      pIndexNew->PutPrimaryKey(-1);//主索引
      pIndexNew->PutUnique(-1);//唯一索引
      pTable->Indexes->Append(_variant_t ((IDispatch*)pIndexNew));//創(chuàng)建索引
      pIndexNew=NULL;
      pCatalog->Tables->Refresh();//刷新
      return TRUE;
     }
     catch(_com_error &e){
      ESErrPrintProviderError(tempConnn);
      ESErrPrintComError(e);
      return FALSE;
     }
     catch(...){
     } 
     return FALSE;
    }
  5. 輔助的數(shù)據(jù)庫函數(shù)。由于這些函數(shù)是Jiangsheng以前為一個項目寫的。所以命名有些奇怪。借鑒了MFC類CDaoRecordset的部分代碼
    #define _countof(array) (sizeof(array)/sizeof(array[0]))
    BOOL ESRecordsetOpen(
       LPCTSTR lpszSQL
       ,ADODB::_ConnectionPtr pConnection
       ,ADODB::_RecordsetPtr& rst
       ,ADODB::CursorTypeEnum CursorType//=adOpenDynamic
       ,ADODB::LockTypeEnum LockType//=ado20::adLockOptimistic
       ,long lOptions//=adCmdUnspecified
       )
    {
     _bstr_t bstrQuery;
    const TCHAR _afxParameters2[] = _T("PARAMETERS ");
    const TCHAR _afxSelect2[] = _T("SELECT ");
    const TCHAR _afxTransform2[] = _T("TRANSFORM ");
    const TCHAR _afxTable2[] = _T("TABLE ");
     // construct the default query string
     if ((_tcsnicmp(lpszSQL, _afxSelect2, _countof(_afxSelect2)-1) != 0) &&
      (_tcsnicmp(lpszSQL, _afxParameters2, _countof(_afxParameters2)-1) != 0) &&
      (_tcsnicmp(lpszSQL, _afxTransform2, _countof(_afxTransform2)-1) != 0) &&
      (_tcsnicmp(lpszSQL, _afxTable2, _countof(_afxTable2)-1) != 0)){
      CString strTemp;
      strTemp.Format("SELECT * FROM (%s)",lpszSQL);
      bstrQuery=(LPCTSTR)strTemp;
     }
     else
      bstrQuery=lpszSQL;
     if(rst!=NULL){
      rst->CursorLocation=ADODB::adUseClient;
      rst->Open(bstrQuery,_variant_t(pConnection.GetInterfacePtr(),true),CursorType,LockType,lOptions);  
     }
     TRACE("Open Recordset:%s\n",lpszSQL);
     return ESRecordsetIsOpen(rst);
    }
    BOOL ESRecordsetIsOpen(const ADODB::_RecordsetPtr& rst)
    {
     if(rst!=NULL){
      return rst->State&ADODB::adStateOpen;
     }
     return FALSE;
    }
    void ESRecordsetClose(ADODB::_RecordsetPtr& rst)
    {
     if(rst!=NULL){
      if(rst->State&ADODB::adStateOpen)
       rst->Close();
     }
    }
    CString g_GetValueString(const _variant_t& val)
    {
     CString strVal;
     _variant_t varDest(val);
     if(!g_varIsValid(val)){
      return strVal;
     }
     if(val.vt==VT_BOOL){
      if(val.boolVal==VARIANT_FALSE){
       return _T("否");
      }
      else
       return _T("是");
     }
     else{
     }
     if(varDest.vt!=VT_BSTR){
      HRESULT hr=::VariantChangeType(&varDest,&varDest,VARIANT_NOUSEROVERRIDE|VARIANT_LOCALBOOL,VT_BSTR);
      if(FAILED(hr)){
       return strVal;
      }
      
     }
     strVal=(LPCTSTR)_bstr_t(varDest); 
     return strVal;
    }
  6. 錯誤處理代碼
    void ESErrPrintComError(_com_error &e)
    {
       _bstr_t bstrSource(e.Source());
       _bstr_t bstrDescription(e.Description());
     CString strTemp;
     strTemp.Format(_T("´錯誤\n\t錯誤代碼: %08lx\n\t含義: %s\n\t來自 : %s\n\t描述 : %s\n"),
      e.Error(),e.ErrorMessage(),(LPCSTR) bstrSource,(LPCSTR) bstrDescription);
        // Print COM errors.
     ::AfxMessageBox(strTemp);
    #ifdef _DEBUG
       AfxDebugBreak();
    #endif
    }
    void ESErrPrintProviderError(ADODB::_ConnectionPtr pConnection)
    {
     if(pConnection==NULL) return;
     try{
      // Print Provider Errors from Connection object.
      // pErr is a record object in the Connection's Error collection.
      ADODB::ErrorPtr    pErr  = NULL;
      ADODB::ErrorsPtr pErrors=pConnection->Errors;
      if(pErrors){
       if( (pErrors->Count) > 0){
        long nCount = pErrors->Count;
        // Collection ranges from 0 to nCount -1.
        for(long i = 0;i < nCount;i++){
         pErr = pErrors->GetItem(i);
         CString strTemp;
         strTemp.Format(_T("\t 錯誤代碼: %x\t%s"), pErr->Number, pErr->Description);
        }
       }
      }
     }
     catch(_com_error &e){
      ESErrPrintComError(e);
     }
    }

總結(jié)

在文檔/視圖/框架架構(gòu)中集成數(shù)據(jù)庫訪問總體來說還是難度不大的。微軟提供了很多示例的代碼,大部分工作只是把示例代碼從其他語言改寫到VC。主要的工作是對MFC的文檔/視圖/框架架構(gòu)的理解,在適當(dāng)?shù)臅r候調(diào)用這些代碼。

盡管我在打開數(shù)據(jù)庫的同時也打開了一個記錄集,但是我并未給出顯示記錄集內(nèi)容的代碼,這超出了本文的范圍。我可以給出的提示是使用現(xiàn)成的數(shù)據(jù)列表控件來顯示,微軟知識庫文章Q229029 SAMPLE: AdoDataGrid.exe Demonstrates How to Use ADO with DataGrid Control Using Visual C++可以作為參考。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
VC++ ADODB 打開操作ACCESS數(shù)據(jù)庫代碼
VC 數(shù)據(jù)庫 listctrl
VC中使用ADO連接SQL 2005的一種方法 - [VC++]
C++通過ADO訪問SQLSERVER/ORACLE數(shù)據(jù)庫
關(guān)閉ADOX.Catalog創(chuàng)建Access的鏈接,避免ldb鎖定
燕山大學(xué)數(shù)據(jù)庫三級項目——界面系統(tǒng)設(shè)計
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服