Microsoft OLE DB Driver for SQL Server(適用於 SQL Server 的 Microsoft OLE DB 驅動程式)

下載 OLE DB 驅動程式

Microsoft OLE DB Driver for SQL Server 是一個獨立的資料存取應用程式介面(API),屬於 OLE DB。 它可將 C 和 C++ 應用程式連線到 Azure SQL Database、Microsoft Fabric 中的 SQL 資料庫、Azure SQL 受控執行個體,以及受支援版本的 SQL Server 中的 Microsoft SQL 資料庫引擎。 Microsoft 於 2018 年首次以 18 版本釋出,並納入 SQL Server 2019(15.x)。

MSOLEDBSQL19 是目前的驅動程式。 它通常向下相容於 SQL Server 原生客戶端(SNAC),並提供超越 SNAC 及 Windows Data Access Components(Windows DAC,前稱 Microsoft Data Access Components 或 MDAC)所提供的 SQL Server OLE DB 提供者的功能。

選擇你的起點

Azure SQL 的生產環境基準

請使用此片段作為生產導向 Azure SQL 連線的起點。 它從應用程式設定載入伺服器名稱與資料庫名稱,並以管理身份驗證,確保 連接字串 中不出現秘密,並啟用 Tabular Data Stream(TDS)8.0 加密及完整憑證驗證。 它會設定每次連線嘗試的逾時時間,並以指數退避與抖動機制重試暫時性故障。

本文中的 C++ 程式碼片段為求簡潔,省略了 `#include` 指示詞、COM 初始化,以及記錄輔助程式。

std::wstring BuildConnectionString(const wchar_t* server, const wchar_t* database) {
    std::wstring cs = L"Provider=MSOLEDBSQL19";
    cs += L";Data Source=tcp:"; cs += server; cs += L",1433";
    cs += L";Initial Catalog="; cs += database;
    cs += L";Authentication=ActiveDirectoryMSI";   // managed identity, no stored secret
    cs += L";Use Encryption for Data=Strict";      // TDS 8.0 with certificate validation
    cs += L";Connect Timeout=30";                  // per-attempt connect timeout, in seconds
    cs += L";Connect Retry Count=3";               // idle connection resiliency, not initial connect
    cs += L";Connect Retry Interval=10";
    return cs;
}

// Transient fault codes documented for Azure SQL, plus the resource governance
// codes. Network termination and timeout errors (64, 233, 258, 10053, 10054,
// 10060) are retried a bounded number of times, which is the documented
// guidance for them. 258 is the code the driver reports for a connect timeout.
// 10053 and 10054 can also mean the encryption handshake failed rather than a
// plain network reset, so read the error text before assuming a network fault.
bool IsTransient(LONG nativeError) {
    switch (nativeError) {
        case 615: case 926: case 4060: case 4221:
        case 10928: case 10929: case 10936:
        case 40197: case 40501: case 40613:
        case 42108: case 42109:
        case 49918: case 49919: case 49920:
        case 40020: case 40143: case 40166: case 40540:   // failover subcodes
        case 64: case 233: case 258:
        case 10053: case 10054: case 10060:
            return true;
        default:
            return false;
    }
}

// Retries only errors that a new connection can clear, with exponential backoff
// plus jitter so that concurrent clients don't retry in lockstep.
HRESULT ConnectWithRetry(IDataInitialize* pDataInit, const std::wstring& connectionString,
                         int maxAttempts, IDBInitialize** ppDbInit) {
    HRESULT hr = E_FAIL;
    *ppDbInit = nullptr;
    for (int attempt = 1; attempt <= maxAttempts; ++attempt) {
        IDBInitialize* pDbInit = nullptr;
        hr = pDataInit->GetDataSource(nullptr, CLSCTX_INPROC_SERVER, connectionString.c_str(),
                                      IID_IDBInitialize, reinterpret_cast<IUnknown**>(&pDbInit));
        if (SUCCEEDED(hr) && SUCCEEDED(hr = pDbInit->Initialize())) {
            Log("INFO", "connected on attempt %d/%d", attempt, maxAttempts);
            *ppDbInit = pDbInit;
            return S_OK;
        }

        // Walks IErrorRecords and returns the first record that carries a real
        // SQL Server error number. Transport and timeout failures report a
        // generic wrapper record first, whose native error is 0. Errors the
        // server returns carry the number on the first record.
        LONG native = LogProviderErrors("connect", hr);
        if (pDbInit) pDbInit->Release();
        if (attempt == maxAttempts || !IsTransient(native)) return hr;

        // Cap the backoff at 64 seconds. This also keeps the shift in range
        // when a caller passes a large maxAttempts.
        int shift = (attempt - 1 < 6) ? attempt - 1 : 6;
        DWORD delayMs = (1UL << shift) * 1000UL + (DWORD)(GetTickCount64() % 500);
        Log("WARN", "retrying in %lu ms (attempt %d/%d)", delayMs, attempt + 1, maxAttempts);
        Sleep(delayMs);
    }
    return hr;
}

Connect Retry CountConnect Retry Interval 啟用 閒置連線韌性,透明地恢復閒置時斷線的連線。 它們不會重試初始連線,這也是為什麼這個片段同時實作應用程式層級的重試。 兩者都保留。

此程式碼片段會為 IDataInitialize::GetDataSource 建立其連線字串,而 IDataInitialize::GetDataSource 會使用此處所示的含空格關鍵字名稱,例如 Use Encryption for DataConnect Retry CountIDBInitialize::Initialize 而 ADO 則使用相同設定的不同名稱,例如 EncryptConnectRetryCount

GetDataSource 接受錯誤集合的名稱且不會產生錯誤,且該設定永遠不會生效。 連線會使用驅動程式預設值,這可能會削弱它。 Encrypt=Strict 在此路徑上會在 MSOLEDBSQL19 上將加密維持為 Mandatory,因此連線會停用 TDS 8.0,並在明文的預登入階段協商加密,且在 MSOLEDBSQL 上完全關閉加密。 並非每種情況都會以開放方式失效:設定錯誤的 TrustServerCertificate 也會同樣被捨棄,使該屬性維持在其預設的 false,並讓憑證驗證保持啟用。

不要指望靠錯誤來發現失誤。 不屬於任何集合的名稱,例如 ZzzNotAKeyword,會產生 Invalid 連接字串 attribute 紀錄;但來自錯誤集合的名稱則不會產生任何資料。 要確認設定是否生效,連線前先讀回屬性 IDBProperties::GetProperties 。 如需了解各 API 搭配使用的關鍵字集,請參閱搭配 OLE DB Driver for SQL Server 使用連線字串關鍵字

OLE DB 會透過錯誤物件而非僅透過 HRESULT 來回報診斷資訊,因此在重試之前,應先將失敗情況分類。 驗證或設定錯誤會立即失敗,而不會消耗整個重試預算。

關於此配置各部分的更多資訊,請參見:

關於 Azure SQL 暫態錯誤的目錄,請參見暫態故障錯誤碼。

主要功能

  • Microsoft Entra ID 認證:無密碼連線,包含管理身份、服務主體、互動式及整合流程。
  • 嚴格加密:TDS 8.0 連線,具備完整憑證驗證,以及 19.2.0 及以上版本的 TLS 1.3。
  • 閒置連線復原能力:自動還原在閒置時中斷的連線。
  • 多個主動結果集(MARS):每個連線有多個待處理請求。
  • 批量複製:透過大量複製介面進行高吞吐量插入。
  • 資料表值參數:將整個結果集合作為單一參數傳遞給伺服器。
  • Always On 可用性群組:支援搭配 MultiSubnetFailover 的接聽程式,以實現快速容錯移轉。
  • UTF-8 與 UTF-16 支援:兩種編碼皆可提供字元資料。
  • 資料分類:分類欄位的敏感性元資料。
  • 非同步操作:非阻塞的資料來源與列集操作。

開始

Article Description
何時使用 OLE DB 驅動程式 何時該選擇 OLE DB Driver for SQL Server 而非其他 SQL Server 驅動程式。
下載 每個支援驅動版本的安裝程式下載。
系統需求 支援作業系統、SQL Server 版本,以及安裝前的前提條件。
建築應用 標頭和函式庫檔案、安裝版面,以及從 MDAC 升級時的變動。
建立應用程式 應用程式會遵循的呼叫順序,從連接到執行指令再到讀取結果。
支援生命週期 哪些驅動版本支援,以及每個版本何時退出支援。

設定和連線

Article Description
連接字串關鍵字 驅動程式接受的每個連線字串關鍵字及其可接受的值。
資料來源物件 建立並初始化建立連接所依據的資料來源與會話物件。
使用 ADO 搭配驅動程式 Reach 驅動功能如 MARS、查詢通知,以及 ADO 的 XML 類型。
高可用性與災難復原 透過可用性群組監聽器以及控制故障切換行為的關鍵字來連結。
閒置連線韌性 自動恢復閒置時斷線的連線。
LocalDB 支援 連接 LocalDB 實例進行本地開發與測試。

認證與安全

Article Description
使用 Microsoft Entra ID。 驅動程式支援的 Microsoft Entra 認證模式,包括管理身份與互動式。
加密和憑證驗證 設定 Encrypt 和 TrustServerCertificate,並控制伺服器憑證的驗證方式。
程式化更改密碼 處理過期密碼並設定新密碼,且不離開應用程式。
客戶端連線中的服務主體名稱(SPN)支援 在連線上設定服務主體名稱,讓 Kerberos 互認證成功。
使用資料分類 閱讀 SQL Server 對機密欄位回傳的敏感性標籤。

執行指令與程序結果

Article Description
命令 ICommand 介面以及指令執行所依據的指令物件模型。
指令語法 驅動程式在命令文字中接受的 ODBC SQL、ISO 與 Transact-SQL 混合語法。
指令參數 在指令文字中標記參數,並為每個驅動程式綁定支援的類型。
使用多重主動結果集(MARS) 在同一個連線上保持多個待處理結果設定開啟。
執行非同步操作 啟動操作且不阻塞呼叫執行緒,然後輪詢或等待其完成。
處理查詢通知 當查詢結果在伺服器上變動時,請註冊以接收通知。
處理結果 操作指南文章 執行儲存程序或函式,讀取回傳碼、輸出參數與列的範例。

使用資料列集和游標

Article Description
資料列集 行集介面,以及決定你獲得哪種行集的屬性。
正在擷取資料列 IRowset 來依序擷取資料列、讀取欄位值,以及釋放資料列。
在列集中更新資料 請求 IRowsetChangeIRowsetUpdate 取得可修改的行集,並控制其鎖定。
Bookmarks 先儲存資料列位置,稍後再返回該位置,而不是依序重新擷取。
資料列集合與 SQL Server 游標 驅動程式何時使用預設結果集,以及何時改為開啟伺服器游標。

大量複製

Article Description
執行批量複製操作 透過資料檔或程式變數,將大量資料列移入或移出資料表。
使用 IRowsetFastLoad 批量複製資料 使用 IRowsetFastLoad 介面將資料大量複製到 SQL Server 資料表中。
使用 IRowsetFastLoad 和 ISequentialStream 傳送 BLOB 資料 使用 IRowsetFastLoad 來將每一列的不同長度 BLOB 資料串流傳輸至 SQL Server。

資料表值參數

Article Description
表格值參數概述 資料表值參數如何在單一參數中將多列資料傳遞給伺服器。
資料表值參數參考 參數行集建立與參數類型發現。
將資料插入資料表值參數 用於提供表值參數資料列的推送模型與拉取模型。
使用表格值參數 建立一個資料表值參數,並將其資料列傳遞給預存程序。

處理大型及二進位資料的工作

Article Description
BLOBs 與 OLE 物件 透過 ISequentialStream 以串流方式讀取及寫入 BLOB 欄位。
取得大量資料 分段取回大型欄位值,而不是使用單一繫結緩衝區。
設定大型資料 將大型欄位值從用戶端儲存物件傳送到伺服器。
檔案串流支援 儲存大型二進位值,可以透過 SQL Server 或檔案系統讀取。
FILESTREAM 操作指南文章 使用串流介面讀取及寫入 FILESTREAM 欄位的可運作範例。

管理資料表、索引與儲存程序

Article Description
表格與索引 透過 ITableDefinitionIIndexDefinition 建立、修改及刪除資料表和索引。
建立 SQL Server 資料表 定義欄位並呼叫 ITableDefinition::CreateTable 建立資料表。
建立 SQL Server 索引 在現有資料表上定義一個新的索引,為 IIndexDefinition::CreateIndex
預存程序 呼叫一個以 ODBC CALL 語法或 RPC 為基礎的儲存程序,讀取其回傳碼與輸出參數。

數據類型

Article Description
資料型態概述 當你綁定參數和欄位時,SQL Server 類型如何映射到 OLE DB 類型。
資料型態映射於列集與參數中 列集欄位與命令參數的完整型態映射表。
使用大型值類型 綁定 varchar(max)、nvarchar(max)和 varbinary(max) 類型。
使用 XML 資料型別 將 XML 文件與片段儲存並檢索於 XML 欄位中。
使用使用者自訂型別 繫結 CLR 使用者定義型別;驅動程式會將其表示為附有型別中繼資料的二進位值。
稀疏欄位支撐 驅動程式支援稀疏欄位,這些欄位優化用於儲存空值。
UTF-8 支援 使用 UTF-8 伺服器定序與 UTF-8 客戶端編碼。
UTF-16 支援 驅動程式在填寫客戶端緩衝區時如何處理代理配對。
日期與時間改進 綁定 date、time、datetime2 和 datetimeoffset 類型,以及其允許的轉換。

Transactions

Article Description
交易概覽 本地交易支援,以及用於分散式交易的 Microsoft Distributed Transaction Coordinator。
隔離層 設定每個會話的隔離等級,以及每個等級允許的並發。
使用快照隔離 使用列版本控制來提升讀取並發性,同時不會阻擋寫入者。
支援分散式交易 在分散式交易中使用 ITransactionJoin::JoinTransaction 登錄工作階段。

診斷和疑難解答

Article Description
錯誤 驅動程式如何回報故障,以及哪些介面會顯示詳細資訊。
檢索錯誤資訊 逐一巡覽錯誤介面,以讀取訊息文字、SQLSTATE 以及原生錯誤編號。
存取擴充事件記錄檔中的診斷資訊 開啟駕駛追蹤,並閱讀產生的延伸事件日誌。
已知問題 目前驅動程式有未解決的問題,但有解決方法。
發行說明 每個驅動版本的變化,先從最新的開始。

遷移到目前的驅動程式

適用於 SQL Server 的 Microsoft OLE DB 提供者共有三代。 新舊應用程式都請使用 MSOLEDBSQL19,並將現有的連線字串轉換為使用它。 OLE DB 供應商已於 2018 年不再被列為淘汰項目,並重新發布。

世代 提供者字串 現況
Microsoft OLE DB Driver for SQL Server(本文) MSOLEDBSQL19MSOLEDBSQL 有支援。 MSOLEDBSQL19 是目前使用中的驅動程式,也是新開發應使用的驅動程式。
SQL Server 原生客戶端(SNAC) SQLNCLI11SQLNCLI 已從 SQL Server 2022 及 SQL Server Management Studio 19 移除。 不建議新開發。
Microsoft OLE DB Provider for SQL Server SQLOLEDB 隨附於 Windows 資料存取元件 中。 不再維護。 不建議新開發。
Article Description
MSOLEDBSQL 主要版本差異 OLE DB Driver 19 與版本 18 之間的破壞性變更,包括加密預設值、屬性型別變更及遷移步驟。
從 MDAC 更新應用程式 舊版 OLE DB Provider for SQL Server 與現行驅動程式之間有什麼變化?更新前應該檢查哪些事項?
從 SQL Server 2005 Native Client 更新應用程式 自 SQL Server 2005 (9.x) 中 SQL Server 原生客戶端以來,OLE DB Driver for SQL Server 的重大變更。

Reference

Article Description
OLE DB Driver for SQL Server 的功能 驅動程式專屬功能的索引,以及每項功能的記載位置。
OLE DB 程式設計 驅動程式所展現的 COM API 模型,以及它如何透過 TDS 與 SQL Server 溝通。
OLE DB 操作指南文章 OLE 資料庫操作文章索引,依任務分組。
OLE DB 介面 OLE DB 介面及在此驅動程式中展現提供者特定行為的方法。
結構描述資料列集支援 提供者專屬的結構列集行為,包括從連結伺服器回傳的元資料。
尋找更多資訊 規範、範例及本文件集外的社群資源。