c++呼叫ado連結mssql資料庫詳解
最近程式中用到讀寫資料庫,看了些例子,查了番MSDN,下面把詳細步驟寫出來,以備忘,或與同行共勉。
讀寫資料庫的技術很多,現在多用ADO。ADO以COM方式提供,所以它的很多行為遵循COM規範。首先,要引入ADO的COM檔案,它的位置一般在"C:/Program Files/Common Files/System/ado/msado15.dll"。
1. 引入ADO
開啟預編譯標頭檔案StdAfx.h,寫上引入宣告:
#import "C:/Program Files/Common Files/System/ado/msado15.dll" no_namespace rename("EOF","adoEOF")
解釋一下上句:no_namespace是指忽略名稱空間,rename則是把ADO中的EOF重新命名為adoEOF。命成什麼名字無所謂,但注意宣告中的名字要和程式碼中的名字一致。
2. 初始化
用ADO寫程式碼前,要將COM初始化。常用手段是在程式碼前後加上CoInitialize(NULL)和CoUninitialize()。也可以用AfxOleInit()來初始化COM庫。
3. 三個核心物件
ADO的3個核心物件是連線物件(_Connection)、命令物件(_Command)和記錄集物件(_RecordSet)。其中連線物件是任何操作必須的。很多操作3個核心物件都可以完成。要例項化它們並使用它們提供的方法,不得不說到它們是一種智慧指標
4. 例項化
_ConnectionPtr pConn(__uuidof(Connection));
_RecordsetPtr pRec(__uuidof(Recordset));
_CommandPtr pCmd(__uuidof(Command));
如果上面不加引數,則需加上:
pConn.CreateInstance("ADODB.Connection");
pRec.CreateInstance("ADODB.Recordset");
pCmd.CreateInstance("ADODB.Command");
5. 連線資料庫
連線資料庫一般採取字串連線。這個字串的獲取方法用了“不能說的祕密”,即任意新建一個txt檔案,重新命名為.x.udl。然後雙擊此檔案,將出現“資料庫連線屬性”視窗。第一個標籤頁“提供程式”列出了所有資料庫引擎,Access, SQL Server, Oracle等,選擇後點下一步跳至第二個標籤頁“連線”,選擇伺服器名稱欄可以填上伺服器的IP地址,本機則可不填或填點號;填上資料庫使用者名稱和密碼後就可以選擇資料庫了。點“測試連線”按鈕,成功。確定。用記事本開啟x.udl。將會看到它生成的連線字串。如下:
"Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Password=123;Initial Catalog=cfdata"
此連線串中,Persist Security Info屬性為True時表示在建立連線後仍然儲存密碼,一般取False即可。ID和Password屬性只有在上述資料庫屬性對話方塊中勾選“允許儲存密碼”時才會有。自己可以手工新增。Cfdata是我的資料庫名。
C++中連線程式碼如下:
pConn->ConnectionString="Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Password=123;Initial Catalog=cfdata";
6. 示例
有些資料庫操作_Connection一個就能完全搞定。如update語句。因為它不需要返回的結果。如下:
pConn->ConnectionString="Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Password=123;Initial Catalog=cfdata";
pConn->Open("","","",adConnectUnspecified); //開啟連線。此處引數均已在上述字串宣告,故可為空
CString strSQL="update table1 set name=’Richard’ where id=1";
_pConn->Execute(_bstr_t(strSQL),NULL,adCmdText);
這裡涉及強制型別轉換。COM中的資料型別和常規(如MFC)型別一般都有對應,但需要轉換。如上面的_bstr_t和CString。至於應該轉換成什麼型別,看VC環境中的提示即可(這裡推薦大家加裝Visual Assitant,使提示功能更完善)。
也有些操作需要返回記錄集,如select語句。這裡就至少需要_Connection和_Recordset兩種核心物件,也可以用_Command執行之。下面展示同一操作用3種物件分別實現的程式碼。
(1)連線物件
CString strSQL="select * from table1"; //方法1
pRec=pConn->Execute(_bstr_t(strSQL),NULL,adCmdText);
(2)記錄集物件
CString strSQL="select * from table1"; //方法2
pRec->Open(_variant_t(strSQL),(_variant_t)( (IDispatch*)pConn),adOpenDynamic,adLockOptimistic,adCmdText);
其中第二個引數(_variant_t)( (IDispatch*)pConn)指明活動連線,資料型別轉換比較複雜,_variant_t是引數要求的型別,IDispath*則是_variant_t可強制轉換型別型別。也可用下句:
pConnGetInterfacePtr();
(3) 命令物件
CString strSQL="select * from table1"; //方法3
pCmd->put_ActiveConnection((_variant_t)((IDispatch*)pConn));
pCmd->CommandText=_bstr_t(strSQL);
pRec=pCmd->Execute(NULL,NULL,adCmdText);
7. 資料使用
取得記錄集後,將其中資料取出。用一個ListBox讀取其中name欄位資料。程式碼如下:
while(!pRec->adoEOF)
{
//_bstr_t型別可以視作COM型別字串和MFC型別字串之間的橋樑
CString str=LPSTR(_bstr_t(pRec->GetCollect("name")));
((CListBox*)GetDlgItem(IDC_LIST1))->AddString(str);
pRec->MoveNext();
}
上述程式碼中用到了adoEOF,要注意直接拷貝第三方程式碼時可能會被重新命名為rsEOF等,此時則需作相應更改。另外,while迴圈中的MoveNext()也不要忘了,否則它就成了死迴圈了。欄位值的獲取及轉換也可用下面方法:
_variant_t var=pRec->GetCollect("name");
var.ChangeType(VT_BSTR);
CString str=var.bstrVal;
8. 關閉與釋放
用完相應物件後,需要關閉並釋放之,程式碼如下:
pRec->Close();
pConn->Close();
pRec.Release();
pCmd.Release();
pConn.Release();
9. 錯誤捕獲
資料庫操作難免出現錯誤,連線串錯誤,SQL語句錯誤,或返回NULL你卻硬要向表裡塞(此錯誤可以在取出後用var.vt!=VT_NULL判斷),所以我們需要把它們放到try…catch段中。ADO在捕獲到錯誤後會丟擲_com_error型別異常,我們可以這樣做:
try
{
pConn->ConnectionString="Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Password=123;Initial Catalog=cfdata";
pConn->Open("","","",adConnectUnspecified);
………… //程式碼省略
}
catch(_com_error& e)
{
AfxMessageBox(e.ErrorMessage());
AfxMessageBox(e.Description());
}
這裡有個疑惑,在捕獲錯誤後,e.ErrorMessage()和e.Description()中放著不同資訊,有時前者說得清晰,有的後者說的清晰,搞不清楚,索性就都加上吧。最後,可以再加個catch(…),畢竟ADO之外的地方也可能發生錯誤。
這裡,我還犯過一個錯誤,被它整了N久。我把_com_error& e寫成了_com_error* e後面也對應改成->操作符,而且編譯通過,結果一執行程式就崩潰,而且它不告訴我在哪出錯,因為這時的錯誤是_com_error這時卻對著_com_error*來捕獲當然捕不到。這裡&只是一個引用,寫不寫無所謂,*是萬萬不可地。(網上書上很多大師級程式碼都是用了*,誤導啊)。
10. 其他介面
ADO中除了3個核心物件外,我們還應瞭解FieldsPtr、FieldPtr、StreamPtr等介面。例如上述示例中,我們可以用FieldsPtr的GetCount()方法獲取其欄位個數,用FieldPtr來接收具體欄位等。二進位制資料如影象檔案等則會用到StreamPtr。就寫到這裡。歡迎加入我們的VC群713035,和眾多C++程式設計師共同進步。(全文完)
----------
轉自:http://blog.csdn.net/asanscape/article/details/6084600
實測有時候在WIN7 X64雙擊執行udl檔案時,視窗一閃而過...
可以用下面的方式開啟
C:\Windows\syswow64\rundll32.exe "C:\Program Files (x86)\Common Files\System\Ole DB\oledb32.dll",OpenDSLFile C:\aaa.udl
其中最後面的 C:\aaa.udl 為udl檔案的路徑檔名
相關推薦
c++呼叫ado連結mssql資料庫詳解
最近程式中用到讀寫資料庫,看了些例子,查了番MSDN,下面把詳細步驟寫出來,以備忘,或與同行共勉。 讀寫資料庫的技術很多,現在多用ADO。ADO以COM方式提供,所以它的很多行為遵循COM規範。首先,要引入ADO的COM檔案,它的位置一般在"C:/Program Fi
VC使用ADO連線Oracle資料庫詳解(含原始碼下載)
ADO 主要物件介紹 ADO物件包括:連線物件(Connection Object)、命令物件 (Command Object) 、記錄集對象(RecordSet Object)、欄位物件(Field Object) 、記錄物件(Record Object)
C++編譯和連結過程的詳解
1.基本概念 1.編譯:編譯器對原始檔進行編譯,就是把原始檔中的文字形式存在的原始碼翻譯成機器語言形式的目標檔案的過程,在這個過程中,編譯器會進行一系列的語法檢查。如果編譯通過,就會把對應的CPP轉換成OBJ檔案。 2.編譯單元:根據C++標準,每一個CPP檔
C#呼叫C/C++動態連結庫(.dll)詳解
第一篇編譯C的動態連線庫 在實際工作中,我們經常會將C語言中的.lib和.h檔案(靜態庫)編譯成動態連線庫.dll檔案(這裡只提供這兩種檔案,沒有完整的工程),以提供給其他語言平臺呼叫。 1,必須有.lib檔案,只有.h檔案是無法編譯動態連線庫的。 2,我使用的是V
c++中呼叫Com元件的方法詳解
轉載自:http://www.cppblog.com/woaidongmao/archive/2011/01/10/138250.html需求: 1.建立myCom.dll,該COM只有一個元件,兩個介面: IGetRes--方法Hello(), IGetResEx--方法HelloEx() 2
C#連線sqlServer資料庫詳解
C# 是如何跟SQL Server進行連線的? 在C#/.NET程式設計中,離不開ADO.NET。ADO.NET是.NET連線資料庫的重要元件。使用其可以很方便地訪問資料庫,ADO.NET還可以訪問Oracle資料庫、Access資料庫、SQL Ser
C/C++ 程式編譯與連結的過程詳解(靜態連結)
我們知道一個程式的執行需要經過編譯和連結兩個階段,其過程究竟是怎樣的呢? 程式的編譯階段分為以下幾個步驟,分別是預編譯、編譯、彙編、生成二進位制可重定向檔案(.o)。 預編譯: 首先是原始碼檔案xxx.c和相關的標頭檔案被預編譯器編譯成一個.i檔案。
C++中呼叫ActiveX元件的方法詳解
本文以 "msscript.ocx" 作為參考 第一步: 獲取標頭檔案 #import "msscript.ocx" 得到兩個檔案 "msscript.tlh" 和 "msscript.tli" 整合下的到個頭檔案"msscript.h"如下: +
C# 定時器傳值問題詳解
ati bll main 實例 詳解 use object handle source //傳參數定時器 private static System.Timers.Timer aTimer; Main(ApprovalID); public static void
C#中的IDisposable模式用法詳解
數據庫 nor 是否 entry block 記錄日誌 自定義 技術分享 ssa 本文實例講述了C#中IDisposable模式的用法,針對垃圾資源的回收進行了較為詳細的講解。分享給大家供大家參考之用。具體方法如下: 首先,對於垃圾回收而言,在C#中,托管資源的垃圾回收是
C# List<T>用法詳解
知新樹 寧金峰 所屬命名空間:System.Collections.Generic public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnu
C#中的Linq to Xml詳解
image 查詢 學習 ebo ret 遞增 xdoc 裏的 事件 前言 我相信很多從事.NET開發的,在.NET 3.5之前操作XML會比較麻煩,但是在此之後出現了Linq to Xml,而今天的主人公就是Linq to Xml,廢話不多說,直接進入主題。 一、生
[Js-C++].h文件與#include詳解
diff dep poi nta obj ssi always *** function ******************************************************* 4) The "right way" to include ******
C++11Mutex(互斥鎖)詳解
AR c++ 條件 oid 簡單 但是 資源 void AD 多個線程訪問同一資源時,為了保證數據的一致性,最簡單的方式就是使用 mutex(互斥鎖)。 (1).直接操作 mutex,即直接調用 mutex 的 lock / unlock 函數。此例順帶使用了 boost:
C#基礎之流程控制語句詳解
集合 必須 清晰 循環 remove 很難 使用 fault code C#程序的執行都是一行接一行、自上而下地進行,不遺漏任何代碼。為了讓程序能按照開發者所設計的流程進行執行,必然需要進行條件判斷、循環和跳轉等過程,這就需要實現流程控制。C#中的流程控制包含了條件語句、循
C 二維指針難點詳解。
spa 難點 一個 數組a 例子 維數 指向 二維 數據類型 關於 指向二維數組的指針。 int a[2][3]; int *p; int (*p_1)[3]; 可以用p_1 = a ,但是不能用p = a ; 因為此時數組a的數據類型是 int (* x)[3],
C# winform控件之PictureBox詳解
建立 默認 rgs 控件 review 選擇圖片 zh-cn sage 詳解 PictureBox表示用於顯示圖像的 Windows 圖片框控件https://msdn.microsoft.com/zh-cn/library/system.windows.forms
NoSQL資料庫詳解
NoSQL(NoSQL = Not Only SQL ),意即"不僅僅是SQL"。 在現代的計算系統上每天網路上都會產生龐大的資料量。 這些資料有很大一部分是由關係資料庫管理系統(RDBMS)來處理。 1970年 E.F.Codd's提出的關係模型的論文 "A relational mode
SELECT is not allowed in cluster (Redis叢集JedisCluster資料庫詳解)
(1)redis在單機模式下redis.conf配置檔案中預設的資料庫數量是16個, # Set the number of databases. The default database is DB 0, you can select# a different one on
pg資料庫詳解(1)--Mac安裝postgreSQL詳解
Mac安裝postgreSQL詳解 --------------------- 作者:文動天下 來源:CSDN 連結:https://blog.csdn.net/li_yi_kun?t=1 版權宣告:本文為博主原創文章,轉載請附上博文連結! 建議用