下载 OLE DB 驱动程序
Microsoft OLE DB Driver for SQL Server是一个独立的数据访问应用程序接口(API),属于OLE DB的一部分。 它使 C 和 C++ 应用程序能够连接到 Azure SQL 数据库、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连接的起点。 它从应用配置加载服务器名称和数据库名称,使用托管身份认证,确保连接字符串中不出现秘密信息,并支持表式数据流(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 Count 并 Connect Retry Interval 启用 空闲连接弹性,透明地恢复空闲时断开的连接。 它们不会重试初始连接,这也是为什么这个片段还实现了应用层的重试。 两者都留着。
此代码片段为 IDataInitialize::GetDataSource 构建其连接字符串,该字符串使用此处显示的带空格的关键字名称,例如 Use Encryption for Data 和 Connect Retry Count。
IDBInitialize::Initialize 和ADO则使用不同名称表示相同设定,如 Encrypt 和 ConnectRetryCount。
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 |
|
命令 |
ICommand 接口和命令执行所基于的命令对象模型。 |
|
命令语法 |
驱动程序在命令文本中接受的 ODBC SQL、ISO 和 Transact-SQL 语法组合。 |
|
命令参数 |
在命令文本中标记参数,并为每个参数绑定驱动支持的类型。 |
|
使用多重有效结果集(MARS) |
在同一连接上保持不止一个待处理结果集处于打开状态。 |
|
执行异步操作 |
启动某项操作而不阻塞调用线程,然后轮询或等待其完成。 |
|
处理查询通知 |
注册以获取查询结果在服务器上发生变化时的通知。 |
|
处理结果操作指南 |
执行存储过程或函数并读取返回码、输出参数和行的工作示例。 |
使用行集和游标
| Article |
Description |
|
行集 |
行集接口,以及决定你获得哪种行集的属性。 |
|
正在获取行 |
使用 IRowset 依次提取行、读取列值并释放行。 |
|
在行集中更新数据 |
请求 IRowsetChange 或 IRowsetUpdate 获得可修改的行集,并控制其锁定。 |
|
Bookmarks |
保存行位置,稍后再返回到该位置,而不是按顺序重新获取。 |
|
行集与 SQL Server 光标 |
驱动程序何时使用默认结果集,以及何时改为打开服务器游标。 |
批量复制
表值参数
处理大型和二进制数据
管理表、索引和存储过程
| Article |
Description |
|
表格与索引 |
通过 IIndexDefinition 和 ITableDefinition 创建、修改和删除表和索引。 |
|
创建 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 用户定义类型,驱动程序将其表示为带有类型元数据的二进制值。 |
|
稀疏柱支撑 |
驱动程序对稀疏列的支持,这些稀疏列经过优化以存储 NULL 值。 |
|
UTF-8 支持 |
使用 UTF-8 服务器排序规则和 UTF-8 客户端编码。 |
|
UTF-16支持 |
驱动程序在填充客户端缓冲区时如何处理代理配对。 |
|
日期和时间改进 |
绑定 date、time、datetime2 和 datetimeoffset 类型,以及这些类型所允许的转换。 |
Transactions
| Article |
Description |
|
交易概述 |
本地事务支持,以及用于分布式事务的 Microsoft 分布式事务处理协调器。 |
|
隔离级别 |
设置会话的隔离级别,以及每个级别允许的并发。 |
|
使用快照隔离 |
使用行版本控制可提高读取并发性,而不阻塞写入操作。 |
|
支持分布式事务 |
使用 ITransactionJoin::JoinTransaction 使会话加入分布式事务。 |
诊断和故障排除
| Article |
Description |
|
错误 |
驱动程序如何报告故障,以及哪些接口包含详细信息。 |
|
获取错误信息 |
遍历错误接口以读取消息文本、SQLSTATE 和本机错误编号。 |
|
访问扩展事件日志中的诊断信息 |
打开驾驶员追踪,阅读由此产生的扩展事件日志。 |
|
已知问题 |
当前驱动中的未解决问题,以及可用的变通方法(如有)。 |
|
发行说明 |
每个驱动版本中发生了哪些变化,先从最新的开始。 |
迁移到当前版本的驱动程序
用于 SQL Server 的 Microsoft OLE DB 提供程序共有三代。 对于新的和现有的应用程序,请使用 MSOLEDBSQL19,并将现有的连接字符串转换为它。 OLE DB提供商于2018年 取消升级 并重新发布。
Reference
相关内容