ActiveX Data Objects

微軟公司的ADO（ActiveX Data Objects）是一個用於訪問數據源的COM組件，作為高層的編程界面層。ADO是在OLE DB之上，包含了很多層次化的COM對象與集合（Collections，也是一類對象，在其裡面包含了其他層級對象）。允許開發人員編寫訪問數據的代碼而不用關心數據源是如何實現與訪問驅動的，而只用關心到資料庫的連接。訪問資料庫的時候，關於SQL的知識不是必要的，但是特定資料庫支持的SQL命令仍可以通過ADO中的命令對象（Command）來執行。

## 版本

ADO被設計來替代微軟早期的數據訪問對象層（包括RDO（Remote Data Objects）和DAO（Data Access Objects））。ADO在1996年8月與OLE DB一起被發布。

ADO文件通常保存在C:\Program Files (x86)\Common Files\System\ado\目錄下。

- Microsoft Office 2000中發布了ActiveX Data Objects 2.1 Library（MSADO21.TLB）。
- Microsoft Office 2002中發布了ActiveX Data Objects 2.5 Library（MSADO25.TLB）。引入了Record對象、Stream對象、 URL綁定；並支持識別URL模式的OLE DB provider。
- Microsoft ADO Extensions 2.5 for DDL and Security Library（MSADOX.DLL）包含了下述object與collection：Catalog、Column、Group、Index、Key、Procedure、Property、Table、User object and Users collection、View。
- Microsoft Jet and Replication Objects 2.5 Library（MSJRO.DLL）包括了Filter object與collection，JetEngine object，Replica object。
- ActiveX Data Objects 2.6 Library（MSADO26.TLB）引入了CubDef.GetSchemaObject方法、Command流、Dialect屬性、Command.Execute方法、Field statusvalues、NamedParameters屬性、Resultsets in streams、Single row resultset。
- ActiveX Data Objects 2.7 Library（MSADO27.TLB）支持64位CPU
- ActiveX Data Objects 2.8 Library（MSADO28.TLB）於2003年8月隨Windows Server 2003作業系統發布，作為Microsoft Data Access Components (MDAC) 2.8的組成部分。未引進任何新特性，但做了很多安全方面的補丁。
- ADO 6.0(MSADO60.TLB) 包含在 Windows Vista中，作為Windows Data Access Components (Windows DAC) 6.0的組成部分。功能上ADO 6.0等價於ADO 2.8.
- ADO 6.1(MSADO15.dll)：2011年10月發布。文件名使用了15這個老號。因為Windows 7 SP1的ADO GUID改變了，導致在此作業系統編譯的使用了ADO的軟體可以在Windows 7 SP1上運行，但卻無法在Windows 7 Release版或Windows Vista或Windows XP上運行。

2003年後在新的編程框架.NET Framework中，微軟提供了一個面向Internet的版本的ADO，稱為ADO.NET，其對象模型和ADO差別很大，基本上需要重新徹底學習。

版本｜發布日期｜包括｜特性｜安全問題

1.0｜1996年8月｜、ADC – IIS 3.0、OLE DB 1.1 SDK (OLE DB 1.1 and ADO 1.0)—Visual Studio、Visual Interdev 1.0 and with Active Server Pages (隨IIS 3.0發布)｜、ODBC 3.0、OLE DB 1.1、ADO 1.0、ADC 1.0、ODBC drivers for Access/Jet, SQL Server，Oracle databases｜No bulletin發布

1.5｜1997年9月｜、Microsoft Internet Explorer 4.0、Internet Client SDK 4.0｜、ODBC 3.5、OLE DB 1.5、ADO 1.5、RDS 1.5 (取代ADC 1.0)｜99

2.0｜1998年7月1日｜、Visual Studio 98、Data Access 2.0 SDK｜、ODBC 3.5 SDK、OLE DB 1.5 SDK、OLE DB for OLAP Specification｜98

2.1｜1998年7月11日｜、SQL Server 7.0、SQL Server 6.5 SP5｜、ADO 2.1、RDS 2.1、OLE DB 2.1、OLE DB Provider for ODBC, SQL Server and Oracle、JRO 2.1、ODBC driver、Jet driver、RDO｜02

2.5｜2000年2月17日｜、Windows 2000｜、ADO 2.5、ADO MD 2.5、ADOX 2.5、RDS 2.5、OLE DB 2.5、OLE DB Provider for the ODBC driver for: SQL Server Site Server Search Internet Publishing Jet 4.0 (Access 2000) Oracle Indexing Services (Index Server) Microsoft Data Shaping Services OLAP Services DTS Packages Microsoft Directory Services Server DTS Flat File OLE DB Simple Provider、JRO 2.5、ODBC 3.51、an ODBC driver for Microsoft Access SQL Server Microsoft Excel Text Visual FoxPro FoxPro VFP dBase dBase VFP Paradox Oracle、Jet drivers for: Excel Microsoft Exchange Access text files Lotus 1-2-3 Paradox xBase｜02

2.6｜2000年9月｜、SQL Server 2000｜Not included (manually installed):、Microsoft Jet、Microsoft Jet OLE DB Provider、ODBC Desktop Database Drivers｜02

2.7｜2001年10月｜、Windows XP｜、支持64位系統｜、02、02、03、04

2.8｜2003年8月｜、Windows Server 2003｜bug修復｜、03、04

2.8 SP1｜2005年5月｜、SQL Server 2000 SP4、Windows XP SP2｜bug修復

2.8 SP2｜2005年3月｜、Windows Server 2003 SP1、兼容支持MSJRO

9.0｜從未發布｜、Visual Studio 2005 Beta 1、SQL Server 2005 Beta 1

Windows DAC 6.0｜2006年11月｜、Windows Vista｜、僅改變了版本號、難以兼容MSJRO

ADO 6.1｜2011年10月｜、Windows 7 SP1｜、適用於此後版本作業系統

Microsoft.Jet.OLEDB.X.0和Microsoft.ACE.OLEDB.1Y.0的區別：

- Jet引擎可以訪問office 97-2003，但是無法訪問office 2007。ACE引擎是與Office 2007一起發布的資料庫連接組件，可以訪問Office 2007或Office 97-2003。
- ACE引擎可以訪問正在打開的Excel文件，Jet引擎不能。

## 架構

ADO包含12個對象：

- 連接（Connection），代表到數據存儲的一個通過OLE DB的連接。該對象的open方法以一個連接字串作為參數，建立一個數據連接。連接字串例子：`"Provider='SQLOLEDB';Data Source='TheSqlServerName'; Initial Catalog='Northwind';Integrated Security='SSPI';"`
- 命令（Command），一個SQL語句可以直接發給OLE DB provider，通過CommandText屬性。發送參數化查詢或者存儲過程通過Parameter對象或者Parameters集合。執行一個查詢並返回結果作為數據集對象通過Execute方法。
- 記錄集（Recordset），代表數據記錄的結果。包含了Fields與Properties兩個集合。修改了其中的數據後，調用Update或UpdateBatch方法把改變後的數據提交給數據源。通過AddNew與Update、UpdateBatch方法，可以向數據源增加一條新的記錄。通過Delete與Update方法，可以刪除數據源的一條記錄。CancelUpdate方法用於在Update失敗時（如資料庫的約束不能滿足）顯式強制地取消Update操作。修改數據源時有三種方法：
- Immediate立即：調用Update方法會把數據立即修改到數據源中。記錄集需要採用樂觀鎖（adLockOptimistic）或者悲觀鎖（adLockPessimistic）預先鎖定。前者是在修改數據源時對記錄加鎖並檢查是否保持了數據完整性；後者是在打開記錄集時即把這部分數據上鎖。
- Batch批方式：使用批量樂觀鎖adLockBatchOptimistic，每次調用Update方法時僅在臨時緩衝區中修改數據。最終調用UpdateBatch把修改數據寫入數據源。在此之前，可以用UpdateCancel放棄在臨時緩衝區中的修改。
- Transaction事務：如果OLE DB provider支持事務操作，可以通過BeginTrans與CommitTrans方法來開始與提交事務。RollbackTrans用於取消事務，把資料庫卷回到事務開始狀態。
- 記錄（Record），代表資料庫的一條記錄。包含了Field集合。
- 流（Stream），代表數據的順序集合。主要用於RecordSet對象，用於讀寫字節流。常用於把recordset保存為XML格式，向OLE DB provider發送命令文本（替代CommandText對象）或者包含二進位或文本內容。
- 錯誤（Error），代表資料庫訪問中OLE DB提供的錯誤
- 欄位（Field），代表一個資料庫欄位
- 參數（Parameter），代表一個參數，用於SQL或存儲過程。
- 屬性（Property），保存對象的資訊
- ImmediateThe recordset is locked using the adLockOptimistic or adLockPessimistic lock.
- Batch：recordset使用adLockBatchOptimistic上鎖。每次Update操作在一個臨時buffer中修改數據。當UpdateBatch調用時數據才真正修改回資料庫。調用UpdateCancel放棄臨時buffer中數據。
- Transaction：如果OLE DB允許事務操作，則BeginTrans、CommitTrans、RollbackTrans可調用

ADO包含4個collection：

- Fields：包含了Field對象。
- Properties：包含了Property對象。
- Parameters：包含了Parameter對象。
- Errors：被包含在一個Connection對象中。當ADO操作產生一個錯誤，Errors被清空，然後provider產生的錯誤作為Error對象保存到這個Errors集合中。

## 使用

ADO組件的使用需要利用支持COM的高級語言，例如ASP中的VBScript或者Visual Basic，甚至微軟的競爭對手Borland的產品Delphi，現在也支持使用ADO來訪問資料庫。

使用ADO存取資料的一些基本步驟：

- 創建連接物件去連結資料庫（Create a connection object to connect to the database.）
- 創建記錄集物件來取得資料（Create a recordset object in order to receive data in.）
- 打開連接（Open the connection）
- 在記錄集中完成SQL語法的描述（Populate the recordset by opening it and passing the desired table name or SQL statement as a parameter to open function.）
- 對獲取的數據進行搜索／處理操作。
- 確定改變資料（Commit the changes you made to the data (if any) by using Update or UpdateBatch methods.）
- 關閉記錄集（Close the recordset）
- 關閉連接（Close the connection）

## ASP範例

下列的ASP範例使用ADO於"Phonebook"表中選取"Name"欄位，其中"PhoneNumber"等於"555-5555"。

```asp
dim myconnection, myrecordset, name
set myconnection = server.createobject("ADODB.Connection")
set myrecordset = server.createobject("ADODB.Recordset")

myconnection.open mydatasource
myrecordset.open "Phonebook", myconnection
myrecordset.find "PhoneNumber = '555-5555'"
name = myrecordset.fields.item("Name")
myrecordset.close

set myrecordset = nothing
set myconnection = nothing
```

這相當於下列的ASP code，以plain SQL取代Recordset object：

```asp
dim myconnection, myrecordset, name
set myconnection = server.createobject("ADODB.connection")
myconnection.open mydatasource
set myrecordset = myconnection.execute("SELECT Name FROM Phonebook WHERE PhoneNumber = '555-5555'")
name = myrecordset(0)
```

## C語言例子

```cpp
  AfxOleInit();//COM库的初始化 
#import   "c:\program files\common files\system\ado\msado15.dll "   no_namespace   rename( "EOF ", "adoEOF ") //系统生成msado15.tlh,ado15.tli两个头文件来定义ADO库
  _ConnectionPtr   m_pConnection; //指向Connection对象的指针
  HRESULT   hr; 
  hr   =   m_pConnection.CreateInstance( "ADODB.Connection ");///创建Connection对象 
  if(SUCCEEDED(hr))   
  {   //连接数据库：
      hr   =   m_pConnection-> Open( "Provider=Microsoft.Jet.OLEDB.4.0;Data   Source=test.mdb ", " ", " ",adModeUnknown); //未设置第二个参数UserID、第三个参数Password         
  } 
      //上面一句中连接字串中的Provider是针对ACCESS2000环境的，对于ACCESS97,需要改为:Provider=Microsoft.Jet.OLEDB.3.51; 
       /*第四个参数Options可以取值为: 
       adModeUnknown:缺省。当前的许可权未设置 
        adModeRead:只读 
        adModeWrite:只写 
        adModeReadWrite:可以读写 
        adModeShareDenyRead:阻止其它Connection对象以读权限打开连接 
        adModeShareDenyWrite:阻止其它Connection对象以写权限打开连接 
        adModeShareExclusive:阻止其它Connection对象打开连接 
        adModeShareDenyNone:允许其它程序或对象以任何权限建立连接 */ 
```

## ADOX

ADO包含的對象能夠創建、維護、刪除給定數據源的記錄。但是，創建與管理資料庫及其所包含的對象，ADO就力有不逮了。為此，ADOX，即Microsoft ADO Ext. for DDL and Security，提供了這方面的功能，主要包括Data Definition Language(DDL)對象及安全管理。此外，Jet資料庫引擎的許多功能都是ADO與ADOX不具備的；JRO，即Microsoft Jet and Replication Objects 2.5 Library提供了這方面的補充功能。

功能｜DAO｜ADO｜ADOX｜JRO(MDB's Only)

Create Recordsets｜✔｜✔

Edit Startup properties｜✔｜✔

Support ANSI92 SQL｜✔｜✔

Create Tables｜✔｜✔

Create New Database｜✔｜✔

Edit Existing Table properties｜✔｜✔

Create table relationships｜✔｜✔

Edit security settings｜✔｜✔

Support for Compression attribute for column data｜✔

Edit stored, basic SQL queries or views｜✔｜✔

Create permanent queries that are accessible only through code.｜✔

Create queries accessible through database container/UI and code.｜✔

Compact/Encode database｜✔｜✔

Refresh Cache｜✔｜✔

Make Database Replicable｜✔｜✔

Make Database Replicas｜✔｜✔

Synchronize Replicas｜✔｜✔

Edit Database properties｜✔

Create custom database properties｜✔

Edit table column properties｜✔