VC之ADO數據流存取

相信大家在開發項目時一般都會用到數據庫,以前開發web時,大部份的時間就是用代碼來處理數據,現在搞協同CAD系統的開發也要處理數據庫中的數據,(我的web和CAD是一個系統,協同嘛!)不同的是以前用C#,而現在要用c++,沒辦法,項目的第一步都是搞什麽密碼啊,權限管理之類的好,還有就是要存入文件什麽的!因為文件的數據量比較大,存取比其他類型的數據類型麻煩多了!

目標:用MFC(DLL)對Pro/E進行二次開發,對做好的模型(.prt文件)可以在服務器的數據庫中存取,我用的數據庫是SQL Server 2000

好先掛上我運行成功后的代碼:

 

 

View Code
  1 void CPartToDBDlg::OnOK() 
  2 {
  3     // TODO: Add extra validation here
  4     ::CoInitialize(NULL);
  5     //定义变量
  6     _RecordsetPtr pRs=NULL;                             
  7     _ConnectionPtr pConnection=NULL;   
  8     _variant_t varChunk;   
  9     HRESULT hr;         
 10     HLOCAL hMem;
 11     BYTE* pbyte;
 12     CString strHint;//提示信息
 13     CFile strFileR;//定义读文件对象
 14 
 15     LPTSTR pstrBack = _tcsrchr(m_sourcePath, '\\');//取得文件名称,只含文件名和最后一个'\'
 16     strFileR.Open(m_sourcePath,CFile::modeRead);    
 17     long nLength=strFileR.GetLength();
 18     hMem=LocalAlloc(LHND, nLength+1);//分配内存,将读出的数据放入其中
 19     if (hMem == NULL)
 20     {
 21         return;    //分配内存失败
 22     }
 23     pbyte=(BYTE*)LocalLock(hMem);// 锁定内存
 24     memset(pbyte, (BYTE)0, strFileR.GetLength()+1);//初始化新分配的内存,设定初始值为0
 25     strHint.Format("开始读取文件%s",m_sourcePath);//提示信息
 26     AfxMessageBox(strHint);//读取文件到内存,注意这里是ReadHuge而非Read
 27     strFileR.ReadHuge(pbyte,nLength); 
 28 
 29     BYTE* pBufEx;   
 30     pBufEx=pbyte; 
 31     
 32     SAFEARRAY* psa;   
 33     SAFEARRAYBOUND rgsabound[1];   
 34     rgsabound[0].lLbound=0;   
 35     rgsabound[0].cElements=nLength;   
 36     psa=SafeArrayCreate(VT_UI1,1,rgsabound);  
 37     for(long i=0;i<nLength;i++)
 38     {
 39         SafeArrayPutElement(psa,&i,pBufEx++);//Stores the data element at a given location in the array.
 40     }                
 41     VARIANT varBLOB;   
 42     varBLOB.vt = VT_ARRAY | VT_UI1;   
 43     varBLOB.parray = psa;  
 44     
 45     _bstr_t strCnn("Provider=SQLOLEDB; Server=SEUHH\\SQLEXPRESS;Database=ProTkDB; uid=sa; pwd=;");         
 46     try   
 47     {     
 48                   pConnection.CreateInstance(__uuidof(Connection));      //Open   a   connection   
 49                   hr = pConnection->Open(strCnn,"","",NULL);       //Connect   a   DataBase   
 50                   pRs.CreateInstance(__uuidof(Recordset));   
 51                   pRs->Open("select * from PartsClass where id=1",_variant_t((IDispatch*)pConnection,true),adOpenKeyset,adLockOptimistic,adCmdText);     //Open   a   Table    
 52                   pRs->Fields->GetItem("Image")->AppendChunk(varBLOB);                          
 53                   pRs->Update(); 
 54                   //給出提示信息顯示成功
 55                   CString sMsg;
 56                   sMsg.Format("數據字段長度為:%d",pRs->Fields->GetItem("Image")->ActualSize);
 57                   pRs->Close();   
 58                   pConnection->Close(); 
 59                   AfxMessageBox(sMsg);
 60     }   
 61     catch(_com_error   &e)   
 62     {   
 63                   //   Notify   the   user   of   errors   if   any.   
 64                   _bstr_t   bstrSource(e.Source());   
 65                   _bstr_t   bstrDescription(e.Description());   
 66                   CString   sError;   
 67                   sError.Format("Source   :   %s   \n   Description   :   %s\n",(LPCSTR)bstrSource,(LPCSTR)bstrDescription);   
 68                   AfxMessageBox(sError);           
 69     }
 70     //释放内存
 71     LocalUnlock(pbyte);
 72     LocalFree(hMem);
 73     //关闭文件
 74     strFileR.Close();
 75 }
 76 
 77 void CPartToDBDlg::OnCancel() 
 78 {
 79     // TODO: Add extra cleanup here
 80     // 2.   VC把数据库中IMAGE字段取出存为文件   
 81     ::CoInitialize(NULL);
 82      _RecordsetPtr   pRs   =   NULL;   
 83      _ConnectionPtr   pConnection   =   NULL;   
 84      HRESULT   hr;    
 85      _bstr_t strCnn("Provider=SQLOLEDB; Server=SEUHH\\SQLEXPRESS;Database=ProTkDB; uid=sa; pwd=;"); 
 86      try   
 87      {                    
 88                     pConnection.CreateInstance(__uuidof(Connection)); //Open   a   connection   
 89                     hr = pConnection->Open(strCnn,"","",NULL);       //Connect   a   DataBase 
 90                     pRs.CreateInstance(__uuidof(Recordset));   
 91                     pRs->Open("select * from PartsClass where id=1",_variant_t((IDispatch*)pConnection,true),adOpenKeyset,adLockOptimistic,adCmdText);   
 92                       long lDataSize = pRs->GetFields()->GetItem("Image")->ActualSize;
 93                     char *m_pBuffer;  //定义缓冲变量
 94                      if(lDataSize > 0)
 95                     {
 96                         
 97                         _variant_t varBLOB;//从image字段中读取数据到varBLOB中
 98                            varBLOB = pRs->GetFields()->GetItem("Image")->GetChunk(lDataSize);
 99                            if(varBLOB.vt == (VT_ARRAY | VT_UI1))
100                         {
101                              if(m_pBuffer = new char[lDataSize+1])    //分配必要的存储空间
102                             {    
103                                 char *pBuf = NULL;
104                                 SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
105                                  memcpy(m_pBuffer,pBuf,lDataSize); ///复制数据到缓冲区m_pBuffer
106                                 SafeArrayUnaccessData (varBLOB.parray);
107                             }
108                         }
109                     }
110                     CFile file("d:\\user\\sweep_blend_5.prt",CFile::modeCreate|CFile::modeWrite);
111                     file.Write(m_pBuffer,lDataSize);
112                     file.Flush();
113                     file.Close();
114                     //給出提示信息顯示成功
115                     CString sMsg;
116                     sMsg.Format("數據字段長度為:%d",lDataSize);
117                     pRs->Close();   
118                     pConnection->Close(); 
119                     AfxMessageBox(sMsg);   
120                 
121     }   
122     catch(_com_error   &e)   
123      {   
124                   //   Notify   the   user   of   errors   if   any.   
125                   _bstr_t   bstrSource(e.Source());   
126                   _bstr_t   bstrDescription(e.Description());   
127                   CString   sError;   
128                   sError.Format("Source   :   %s   \n   Description   :   %s\n",(LPCSTR)bstrSource,(LPCSTR)bstrDescription);   
129                   AfxMessageBox(sError);           
130     }
131 
132     CDialog::OnCancel();
133 }
134 
135 void CPartToDBDlg::OnButton1() 
136 {
137     // TODO: Add your control notification handler code here
138     CString strFilter;
139     strFilter="All Files(*.*)|*.*||";
140     CFileDialog dlg(TRUE, NULL, NULL, OFN_EXPLORER|OFN_HIDEREADONLY|
141         OFN_ENABLESIZING|OFN_FILEMUSTEXIST,strFilter);
142     
143     dlg.m_ofn.lStructSize = sizeof(OPENFILENAME);
144     if(dlg.DoModal() == IDOK )
145     {
146         m_sourcePath=dlg.GetPathName();//Edit控件
147     }
148     UpdateData(FALSE);
149 }
說明:
當然了,在工程中要先導入msado15.dll是必須的,其他的就看上面的代碼吧!在數據庫中對應的數據類型可以是image,text,ntext三種,我只對image的做了,
其他兩個沒做!還有就是這段程序是可以存取任何類型的文件數據的!
總結:
要注意做事的方法!我開始在網上找了很久都沒有找到,我想原因主要是因為我現在對VC,MFC還處於入門階段,很多函數都不認識,
上網看了很多,但就是達不到我的目的,畢竟代碼都是要完成個人所需的功能的,很是浪費時間,所以啊,還是應該從最簡單的功能做起,確定自己想要的東西,
多利用圖書館的資源,學校就是圖書館好,資源相當豐富,這個我是要肯定的…
posted @ 2010-05-15 21:07  samyangvs05  阅读(309)  评论(0编辑  收藏  举报