乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

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

       Frank_Chia 2009-07-27

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

      預(yù)備閱讀

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

      MFC技術(shù)文章

      微軟知識(shí)庫文章

      Office VBA參考

      步驟

      1. 在計(jì)算機(jī)上安裝MDAC2.5以上版本
      2. 打開VC。首先,我們使用MFC應(yīng)用程序向?qū)?chuàng)建一個(gè)標(biāo)準(zhǔn)的MDI程序,這里我為這個(gè)工程起名為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ì)算機(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. 編寫一個(gè)輔助函數(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);//自動(dòng)編號(hào)字段
          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("記錄編號(hào)");//注釋
          pCols->GetItem(_T("RecordID"))->Properties->GetItem(_T("AutoIncrement"))->Value=true;//自動(dòng)編號(hào)
          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以前為一個(gè)項(xiàng)目寫的。所以命名有些奇怪。借鑒了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. 錯(cuò)誤處理代碼
        void ESErrPrintComError(_com_error &e)
        {
           _bstr_t bstrSource(e.Source());
           _bstr_t bstrDescription(e.Description());
         CString strTemp;
         strTemp.Format(_T("´錯(cuò)誤\n\t錯(cuò)誤代碼: %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 錯(cuò)誤代碼: %x\t%s"), pErr->Number, pErr->Description);
            }
           }
          }
         }
         catch(_com_error &e){
          ESErrPrintComError(e);
         }
        }

      總結(jié)

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

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

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多