ADO 操作access資料庫

來源:互聯網
上載者:User

 

資料庫一直沒有接觸過,由於工作需要,就進行了一些瞭解。從一開始找資料,到學會基本的編程,大概花了一個半月。其中找資料花的時間最多。這裡我對這一個半月的學習進行總結,希望對新手有協助,也作為資料留檔供以後使用。

 

vc對資料的操作方式有ODBC DAO OLE/OB和ado等,一開始我都大概看了下,最後選擇了ADO,這個是由於網上介紹,ADO比較有市場。這裡大家可以查看<VC 資料庫編程三部教學(基礎、實踐與進階) >這本書,SCDN上下得到,源碼也有。可以做一個大概瞭解。個人感覺這本書不是很好,上面關於ADO的編程源碼 我沒有看,就看了ADO的介紹。在給大家介紹ADO編程很好的文章寫的很詳細《VC++中使用ADO方式操作ACCESS資料庫》,這篇文章網上隨便可以查到,寫的很詳細,代碼也很全。對於ADO的介紹,網上很多也很詳細。我這裡不再介紹了,我主要對我自己寫的程式進行解讀。

 

程式中包括了串連資料庫,儲存,查詢,修改等基本的功能。高手就沒必看了,新人個人認為還是有參考價值的。我在CSDN上浪費了很多積分,下載下來的程式,基本都沒用的。最多的是串連資料庫的,但其他動作的比較少。

#import "C://Program Files//Common Files//System//ado//msado15.dll"/<br /> no_namespace /<br /> rename( "EOF", "adoEOF" )

ADO編程

第一步:匯入支援庫檔案

在stdafx.h檔案中

 

注意粗線的地方msado15.dll是需要的檔案,一般在ado檔案夾下面,最後要注意將eof重新命名,命名可以自己設定。

 

第二步:初始化智能

CoInitialize (NULL);

這個接觸過COM的肯定知道。在程式結束的地方需要載入

CoUninitialize();

來關閉智能指標。這個只有記的就成,如果要瞭解,看看COM技術方面的資料,有詳細介紹的。

 

第三步:串連資料庫

try<br />{<br />HRESULT hr = m_connect.CreateInstance(__uuidof(Connection));</p><p>if (FAILED (hr))<br />{<br />m_connect == NULL;<br />AfxMessageBox ("Can't create an instance of Connection");<br />return TRUE;<br />}<br />_bstr_t strconnect =_bstr_t("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=裝置管理.mdb");<br />m_connect->Open(strconnect,_bstr_t (""),_bstr_t (""),adModeUnknown);<br />}<br />catch( _com_error &e )<br />{<br />_bstr_t bstrSource(e.Source());<br />_bstr_t bstrDescription(e.Description());<br />TRACE( "Exception thrown for classes generated by #import" );<br />TRACE( "/tCode = %08lx/n", e.Error());<br />TRACE( "/tCode meaning = %s/n", e.ErrorMessage());<br />TRACE( "/tSource = %s/n", (LPCTSTR) bstrSource);<br />TRACE( "/tDescription = %s/n", (LPCTSTR) bstrDescription);<br />}<br />catch (...)<br />{<br />TRACE ( "*** Unhandled Exception ***" );<br />}

這個try和catch的用法 不是很瞭解,不過貌似很有用的東西,以後要試著多使用使用。catch中的代碼,我是抄一個老外的,也有比較簡單的寫法。

程式中主要的是

HRESULT hr = m_connect.CreateInstance(__uuidof(Connection)); 建立串連指標,其中m_connect為_ConnectionPtr類型。

_bstr_t strconnect =_bstr_t("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=裝置管理.mdb");注意這個必須為_bstr_t 的類型。

m_connect->Open(strconnect,_bstr_t (""),_bstr_t (""),adModeUnknown);串連資料庫。

open函數的參數為 第一個參數:可以為SQL語句,表名,或者命令對象:連接字串由一系列被分隔字元號的parameter = value來組成,如上述程式為例子。ADO可以串連很多資料來源,如mysql等這邊有個j牛逼的人物做個總結,串連為:http://www.codeproject.com/KB/database/connectionstrings.aspx

 

第二個參數:為useID 第三個參數為PAssWORD 我寫的程式的資料沒有許可權所以沒有這些。

最後一個為 Option:

  adModeUnknown:為預設值  (現在我都用這個,具體的要以後多用了才有體會。)

  adModeRead:唯讀

  adModeWrite:唯寫

  adModeReadWrite:讀寫

  adModeShareRead:阻止其他Connection對象以讀許可權開啟串連

  adModeShareWrite:阻止其他Connection對象以寫入權限開啟串連

  adModeShareNone:阻止其他Connection對象以任何許可權開啟串連

  adModeShareShareExclusive:阻止其他Connection對象以讀寫權限開啟串連

  adConnectUnspecifed:(預設值)同步開啟串連

  adAsyncConnect:非同步開啟串連

上述我都是網上找的,就用到一個缺損的。

上述代碼中沒有問題的話,那你就串連資料庫成功了。下面就是其他動作了。

 

第一 讀資料:

       讀寫查詢等都有2種方法,一種是ADO內建的函數,一種是執行SQL;程式中使用的是SQL的方法。這種個人感覺靈活一些,不過好學習SQL語言。

       SQL語言執行方法的總體都是一樣的

1) 串連資料來源。也就是上面代碼實現的功能。

2) 定義並建立

   定義   _CommandPtr pCommand;//指向Command的指標
            _RecordsetPtr pRecordset;//指向Recordset的指標

   建立   HRESULT hr = pCommand.CreateInstance(__uuidof(Command));

                           hr = pRecordset.CreateInstance(__uuidof(Recordset));

3) 將Command的指標和資料來源關聯起來

       pCommand->ActiveConnection = m_connect;

4) 添加SQL語句

       pCommand->CommandText = (_bstr_t)sql;//你所有的操作差別都在SQL語句用;並注意一定是_bstr_t型的。

5) 執行SQL語句並返回記錄集

       pRecordset=pCommand->Execute(NULL,NULL,adCmdText);

      注意有些SQL操作是沒有記錄集返回的 如 UPDATA; DELETE等

SQL讀取記錄集的語句

      sql = “SELECT * FROM [表名] WHERE 條件”

注意的是如果段名或者表名是中文或者含有 / 空格 等符號的需要用[]括起來

段名 表名 可以用別名的方式 如 sql="SELECT [段名] as name FROM date";

多個表名用“,”分開 如 sql = "SELECT [段名1] as name1, [段名2] as name2 FROM date";

還可以顯示固定的條數   sql = "SELECT TOP 20 * FROM [表名]":表中的前20條記錄

                                 sql = "SELECT TOP 20 PERCENT * FROM [表名]":表中的前20%條記錄

程式中讀取表的前一百條記錄的代碼
 //更新view列表<br />//更新view列表<br />CListView* lpview;<br />POSITION pos = GetFirstViewPosition();<br />lpview = (CListView*)GetNextView(pos); //擷取listview的控制代碼<br />CRect rect;<br />CListCtrl& listctrl=(CListCtrl&)lpview->GetListCtrl();<br /> //取得listview中的CListCtrl控制項的控制代碼</p><p>listctrl.GetWindowRect(&rect);<br />listctrl.DeleteAllItems();<br />while(listctrl.DeleteColumn(0));<br />::UpdateWindow(lpview->m_hWnd);<br />//清空view上的內容<br />//資料庫查看檔案<br />m_report = 1;<br /> //2)定義並建立<br />_CommandPtr pCommand;<br />_RecordsetPtr pRecordset;<br />try<br />{<br />HRESULT hr = pCommand.CreateInstance(__uuidof(Command));<br />if (FAILED(hr))<br />{<br />hr=NULL;<br />AfxMessageBox("can't create an instance of Command");<br />return;<br />}<br />//3)關聯資料來源設定SQL語句<br />pCommand->ActiveConnection = m_connect;<br />pCommand->CommandText = "SELECT TOP 100 * FROM [裝置]";<br />hr = pRecordset.CreateInstance(__uuidof(Recordset));<br />if (FAILED(hr))<br />{<br />pRecordset = NULL;<br />AfxMessageBox("can't create an instance of Recordset");<br />return;<br />}<br />//4)執行SQL語句<br />pRecordset=pCommand->Execute(NULL,NULL,adCmdText);<br />int cols = pRecordset->GetFields()->Count;//擷取列數<br />if (data_name!=NULL)<br />{<br />delete []data_name;<br />}<br />data_name = new CString[cols];<br />_variant_t get_name;//這裡需要注意返回的都是_variant_t型的<br />//讀取欄位名<br />for (int i=0;i<cols;i++)<br />{<br />get_name = pRecordset->GetFields()->GetItem(_variant_t(short(i)))->GetName();<br />if (get_name.vt==VT_NULL)//這裡是防止段名為空白直接跳出報錯<br />{<br />data_name[i].Empty();<br />}<br />else<br />data_name[i] = (LPCTSTR)(_bstr_t)get_name;<br />int nWidth = listctrl.GetStringWidth(data_name[i]) + 50;<br />listctrl.InsertColumn(i, data_name[i], LVCFMT_LEFT, nWidth);<br />}<br />int nCount =0;<br />//擷取資料<br />CString lptext;<br />CString k("0");<br />while (!pRecordset->GetadoEOF ())//遍曆記錄集<br />{<br />listctrl.InsertItem(nCount,k);<br />for (i=0;i<cols;i++)<br />{</p><p>get_name = pRecordset->GetFields()->GetItem(_variant_t(short(i)))->GetValue();<br />if (get_name.vt==VT_NULL)//防止記錄集為空白直接跳出報錯<br />{<br />lptext.Empty();<br />}<br />else<br />lptext = (LPCTSTR)(_bstr_t)get_name;<br /> //注意返回的資料類型<br />listctrl.SetItemText(nCount,i,lptext);<br /> //顯示到VIEW中<br />}<br />pRecordset->MoveNext();<br />nCount++;<br />}<br />pRecordset->Close();<br />//delete []lpview;<br />}<br />catch ( _com_error &e )<br />{<br />_bstr_t bstrSource(e.Source());<br />_bstr_t bstrDescription(e.Description());<br />TRACE( "Exception thrown for classes generated by #import" );<br />TRACE( "/tCode = %08lx/n", e.Error());<br />TRACE( "/tCode meaning = %s/n", e.ErrorMessage());<br />TRACE( "/tSource = %s/n", (LPCTSTR) bstrSource);<br />TRACE( "/tDescription = %s/n", (LPCTSTR) bstrDescription);<br />}<br />catch (...)<br />{<br />TRACE ( "*** Unhandled Exception ***" );<br />}

上述代碼中註解的地方 需要注意一下;這些基本是我剛開始寫出現過問題的地方。我上網查詢,也有不少人出現過這樣的錯誤。

 

第二 查詢

       基本步驟和讀取是一樣的SQL的語句為

       sql="SELECT * FROM [表名] WHERE 條件";查詢主要是設定 條件子語句

有條件符  >,<,>=,=<=,<>(取反),!>,!<等

 

範圍運算子(判斷運算式是否在指定範圍)

       BETWEEN ... AND ...            ;NOT BETWEEN ... AND ... 

列表運算子(判斷運算式是否在指定項中)

      IN(項1,項2 ...);NOT IN(項1,項2 ...);

模型匹配(判斷是否與指定的字元通配格式符合)LINK , NOT LINK:(這個很有用,我程式中的查詢都是用到他)

空值判斷符(判斷運算式是否為空白):IS NULL,NOT IS NULL

 

模式比對的萬用字元  %:表示任意類型和長度

               底線   _ :匹配單個任一字元

                方括弧  []:指定一個字元,字串或範圍,要求匹配對象為定值中的一個

                           [^]: 要求匹配對象為指定字元外的任意一個

如 LINK '%菜鳥%':就是讀取所有含菜鳥字元的資料

 

(上述說明是在一個BOLG中看到的忘了 BLOG是哪位大N的 這裡表示感謝。查網路學東西,比只啃書要快好多啊。)

 

程式碼

_CommandPtr pCommand;<br />_RecordsetPtr pRecordset;<br />try<br />{<br />HRESULT hr = pCommand.CreateInstance(__uuidof(Command));<br />if (FAILED(hr))<br />{<br />hr=NULL;<br />AfxMessageBox("can't create an instance of Command");<br />return;<br />}<br />pCommand->ActiveConnection = m_connect;<br />pCommand->CommandText = (_bstr_t)sql;<br />hr = pRecordset.CreateInstance(__uuidof(Recordset));<br />if (FAILED(hr))<br />{<br />pRecordset = NULL;<br />AfxMessageBox("can't create an instance of Recordset");<br />return;<br />}<br />pRecordset=pCommand->Execute(NULL,NULL,adCmdText);<br />int cols = pRecordset->GetFields()->Count;//擷取列數<br />if (data_name!=NULL)<br />{<br />delete []data_name;<br />}<br />data_name = new CString[cols];<br />_variant_t get_name;<br />//讀取欄位名<br />for (int i=0;i<cols;i++)<br />{<br />get_name = pRecordset->GetFields()->GetItem(_variant_t(short(i)))->GetName();<br />if (get_name.vt==VT_NULL)<br />{<br />data_name[i].Empty();<br />}<br />else<br />data_name[i] = (LPCTSTR)(_bstr_t)get_name;<br />int nWidth = listctrl.GetStringWidth(data_name[i]) + 60;<br />listctrl.InsertColumn(i, data_name[i], LVCFMT_LEFT, nWidth);<br />}<br />int nCount =0;<br />//擷取資料<br />CString lptext;<br />bool f =false;<br />CString k("0");<br />while (!pRecordset->GetadoEOF ())<br />{<br />listctrl.InsertItem(nCount,k);<br />for (int j=0;j<cols;j++)<br />{<br />get_name = pRecordset->GetFields()->GetItem(_variant_t(short(j)))->GetValue();<br />if (get_name.vt==VT_NULL)<br />{<br />lptext.Empty();<br />}<br />else<br />lptext = (LPCTSTR)(_bstr_t)get_name;</p><p>listctrl.SetItemText(nCount,j,lptext);<br />}<br />pRecordset->MoveNext();<br />nCount++;<br />}</p><p>pRecordset->Close();<br />if (nCount==0)<br />{<br />AfxMessageBox("為查到相關資訊,請放寬條件。或確定是否存在記錄");<br />}

上面可以看出用sql執行方式,查詢,讀取基本都差不多,差別在於執行的sql語句;所有對於sql的學習才是以後學習的重點。

 

第三 添加

       sql=sql="INSERT INTO [表名] ([段名1],[段名2]...) VALUES ('值1','值二'...)";後面可以加條件

程式碼

_CommandPtr pCommand;<br />_RecordsetPtr pRecordset;<br />try<br />{<br />HRESULT hr = pCommand.CreateInstance(__uuidof(Command));<br />if (FAILED(hr))<br />{<br />hr=NULL;<br />AfxMessageBox("can't create an instance of Command");<br />return;<br />}<br />pCommand->ActiveConnection = m_connect;<br />pCommand->CommandText = (_bstr_t)sql;<br />hr = pRecordset.CreateInstance(__uuidof(Recordset));<br />if (FAILED(hr))<br />{<br />pRecordset = NULL;<br />AfxMessageBox("can't create an instance of Recordset");<br />return;<br />}<br />pRecordset=pCommand->Execute(NULL,NULL,adCmdText);</p><p>OnDevenceInfo();<br />}

注意的是 添加好像沒有返回集的,反正我試者關閉返回集就報錯。

 

第四 刪除

        sql = "DELETE FROM [表名] WHERE [ID]= '值'";

需要注意的是如果 不限制條件,那麼你整張表的所有資料都會被刪除,這點和後面要說的修改是一樣的;還有如何access自動產生的ID被刪除後是不會再出現的,也就是說1~9中的8被刪除,那麼即使你添加 也是1~7 9~10這樣的。一開始我在刪除的時候,直接和listctrl擷取的行數對於,就會出現錯誤的解決。後面改用擷取ID值做為限制條件,解決問題。(這樣的低價錯誤估計也就我這樣的菜鳥才會犯)。

程式碼

_CommandPtr pCommand;<br />_RecordsetPtr pRecordset;<br />try<br />{<br />HRESULT hr = pCommand.CreateInstance(__uuidof(Command));<br />if (FAILED(hr))<br />{<br />hr=NULL;<br />AfxMessageBox("can't create an instance of Command");<br />return;<br />}<br />pCommand->ActiveConnection = m_connect;<br />pCommand->CommandText = (_bstr_t)sql;<br />hr = pRecordset.CreateInstance(__uuidof(Recordset));<br />if (FAILED(hr))<br />{<br />pRecordset = NULL;<br />AfxMessageBox("can't create an instance of Recordset");<br />return;<br />}<br />pRecordset=pCommand->Execute(NULL,NULL,adCmdText);<br />}

 

第五 修改

        sql="UPDATE [裝置] SET [段名]='值',[段名1]='值1' WHERE 條件"

需注意的是一定要加限制條件,不然你的整張表都將被同一值修改。

程式碼

_CommandPtr pCommand;<br />_RecordsetPtr pRecordset;<br />try<br />{<br />HRESULT hr = pCommand.CreateInstance(__uuidof(Command));<br />if (FAILED(hr))<br />{<br />hr=NULL;<br />AfxMessageBox("can't create an instance of Command");<br />return;<br />}<br />pCommand->ActiveConnection = m_connect;<br />pCommand->CommandText = (_bstr_t)sql;<br />hr = pRecordset.CreateInstance(__uuidof(Recordset));<br />if (FAILED(hr))<br />{<br />pRecordset = NULL;<br />AfxMessageBox("can't create an instance of Recordset");<br />return;<br />}<br />pRecordset=pCommand->Execute(NULL,NULL,adCmdText);<br />}

 

上面可以看出 對於簡單的資料庫操作,ADO還是比較簡單的,主要的都是一樣的,唯獨差別的是SQL語句。所以我個人感覺對於SQL本身的學習才是將來的重點。

當然ADO的一些其他動作,還要進一步學習才能瞭解。

上述代碼的來源程式在

http://download.csdn.net/source/2791099

希望各位大俠,指出錯誤。如果程式中有問題請提出指正。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.