Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
ODBC — это нативный интерфейс прикладного программирования (API) для доступа к данным для приложений, написанных на C и C++. Драйвер Microsoft ODBC для SQL Server подключается к SQL Server, База данных SQL Azure, Управляемый экземпляр SQL Azure, Azure Synapse Analytics и базе данных SQL в Microsoft Fabric. Для версий базы данных, поддерживаемых каждым драйвером, см. совместимость версий SQL.
Ваше приложение вызывает менеджер драйверов ODBC, который загружает драйвер и передаёт ему вызовы ODBC. Используйте Windows ODBC Driver Manager в Windows и unixODBC в Linux и macOS.
К другим языкам, которые могут использовать ODBC, относятся COBOL, Perl, PHP и Python. ODBC широко используется в сценариях интеграции данных, и драйверы Microsoft для PHP для SQL Server построены на этом драйвере.
ODBC-версия sqlcmd и утилита bcp используют этот драйвер, но устанавливаются отдельно: пакет mssql-tools18 на Linux и macOS, а утилиты командной строки Microsoft — в Windows. Вариант sqlcmd для Go не использует этот драйвер.
Используйте sqlcmd для запуска операторов Transact-SQL (T-SQL), системных процедур и скриптов. Используйте bcp для массового копирования данных между экземпляром SQL Server и файлом данных, в любом направлении.
Выберите начальную точку
- Чтобы установить драйвер, перейдите в раздел Системные требования, установка и файлы драйверов для Windows, или установите драйвер ODBC на Linux, установите драйвер ODBC на macOS и установите менеджер драйверов unixODBC.
- Чтобы написать своё первое приложение, перейдите в Подключение к базе данных и выполнение запросов с помощью C++. Для опций имени источника данных (DSN) и строка подключения используйте ключевые слова и атрибуты DSN и строка подключения. Если компилятор не может найти заголовки или сборка не связывается, перейдите в Develop C и C++ applications с драйвером ODBC.
- Чтобы подключиться к Azure SQL с аутентификацией без пароля, перейдите в раздел Use Microsoft Entra ID с драйвером ODBC.
- Чтобы сделать существующее приложение устойчивым к временным сбоям, перейдите в разделы «Устойчивость подключения » и «Высокая доступность и восстановление после катастроф».
- Чтобы обновиться с версии 17, перейдите в разделы «Основные различия в версиях » и «Устранение неисправностей шифрования соединения».
- Чтобы диагностировать проблему соединения или запроса, перейдите в раздел Устранение неполадок шифрования соединения и Известные проблемы (Linux и macOS).
Производственные базовые показатели для Azure SQL
Используйте эту полную программу на C++17 как отправную точку для приложения, размещённого на Azure. Подключается, запускает SELECT 1, проверяет результат и освобождает ODBC-дескрипторы. Установите драйвер 18 и файлы разработки ODBC для платформы перед сборкой. Для предварительных требований см. «Разработка приложений C и C++ с драйвером ODBC».
Установите ODBC_CONNECTION_STRING в среде приложения как полную строку подключения. В следующем примере используется управляемое удостоверение, назначенное системой. На хосте должна быть включена эта идентичность, и база данных должна предоставить ей доступ. Для требований к хосту, назначаемым пользователем удостоверениям и аутентификации для локальной разработки см. раздел «Использование Microsoft Entra ID с драйвером ODBC».
Driver={ODBC Driver 18 for SQL Server};Server=tcp:<server>.database.windows.net,1433;Database=<database>;Authentication=ActiveDirectoryMsi;Encrypt=strict;ConnectRetryCount=3;ConnectRetryInterval=2;
Encrypt=strict требует конечную точку, поддерживающую Tabular Data Stream (TDS) 8.0. В противном случае используйте Encrypt=yes;TrustServerCertificate=no. Настройте сертификат, которому клиент доверяет и чьё имя совпадает с именем сервера. Для настройки и проверки см. раздел Устранение неполадок шифрования соединения.
Держите учетные данные вне исходных файлов и истории shell. Команды для установки переменной среды см. в разделе «Настройка подключения». На Linux и macOS укажите его значение в кодировке UTF-8. Сохраните следующую программу как odbc-baseline.cpp:
#ifdef _WIN32
#include <windows.h>
#else
#include <iconv.h>
#endif
#include <sql.h>
#include <sqlext.h>
#include <chrono>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <random>
#include <stdexcept>
#include <string>
#include <thread>
#include <vector>
struct Handles {
SQLHENV env = SQL_NULL_HENV;
SQLHDBC dbc = SQL_NULL_HDBC;
SQLHSTMT stmt = SQL_NULL_HSTMT;
bool connected = false;
~Handles() {
if (stmt) SQLFreeHandle(SQL_HANDLE_STMT, stmt);
if (connected) SQLDisconnect(dbc);
if (dbc) SQLFreeHandle(SQL_HANDLE_DBC, dbc);
if (env) SQLFreeHandle(SQL_HANDLE_ENV, env);
}
};
bool logDiagnostics(SQLSMALLINT type, SQLHANDLE handle) {
bool retry = false;
bool permanent = false;
for (SQLSMALLINT record = 1; ; ++record) {
SQLWCHAR state[6] = {};
SQLWCHAR message[1024] = {};
SQLINTEGER native = 0;
SQLRETURN rc = SQLGetDiagRecW(type, handle, record, state, &native,
message, 1024, nullptr);
if (rc == SQL_NO_DATA) break;
if (!SQL_SUCCEEDED(rc)) {
std::cerr << "event=diagnostics_failed rc=" << rc << '\n';
return false;
}
std::string sqlstate;
for (int i = 0; i < 5; ++i) {
sqlstate += static_cast<char>(state[i]);
}
std::cerr << "event=odbc_diagnostic sqlstate=" << sqlstate
<< " native_error=" << native << '\n';
permanent |= sqlstate.substr(0, 2) == "28" ||
sqlstate.substr(0, 2) == "IM" ||
sqlstate == "HY024" || sqlstate == "HY092";
retry |= sqlstate == "08S01" || sqlstate == "HYT00" ||
sqlstate == "HYT01";
switch (native) {
case 10928: case 10929: case 10936:
case 40197: case 40501: case 40613:
case 49918: case 49919: case 49920:
retry = true;
}
}
return retry && !permanent;
}
void requireSuccess(SQLRETURN rc, SQLSMALLINT type, SQLHANDLE handle,
const char* operation) {
if (rc == SQL_SUCCESS) return;
logDiagnostics(type, handle);
if (!SQL_SUCCEEDED(rc)) throw std::runtime_error(operation);
}
std::vector<SQLWCHAR> readConnectionString() {
static_assert(sizeof(SQLWCHAR) == 2, "Use a driver manager with 16-bit SQLWCHAR");
#ifdef _WIN32
size_t length = 0;
if (_wgetenv_s(&length, nullptr, 0, L"ODBC_CONNECTION_STRING") != 0 ||
length == 0) {
throw std::runtime_error("ODBC_CONNECTION_STRING is required");
}
std::vector<wchar_t> raw(length);
if (_wgetenv_s(&length, raw.data(), raw.size(), L"ODBC_CONNECTION_STRING") != 0) {
throw std::runtime_error("Cannot read ODBC_CONNECTION_STRING");
}
std::vector<SQLWCHAR> result(raw.begin(), raw.end() - 1);
#else
const char* raw = std::getenv("ODBC_CONNECTION_STRING");
if (!raw) throw std::runtime_error("ODBC_CONNECTION_STRING is required");
iconv_t converter = iconv_open("UTF-16LE", "UTF-8");
if (converter == reinterpret_cast<iconv_t>(-1)) {
throw std::runtime_error("Cannot create UTF-8 converter");
}
size_t inputBytes = std::strlen(raw);
std::vector<SQLWCHAR> result(inputBytes + 1);
char* input = const_cast<char*>(raw);
char* output = reinterpret_cast<char*>(result.data());
size_t outputBytes = result.size() * sizeof(SQLWCHAR);
const size_t capacity = outputBytes;
size_t status = iconv(converter, &input, &inputBytes, &output, &outputBytes);
int closeStatus = iconv_close(converter);
if (status == static_cast<size_t>(-1) || inputBytes != 0 || closeStatus != 0) {
throw std::runtime_error("ODBC_CONNECTION_STRING must be valid UTF-8");
}
result.resize((capacity - outputBytes) / sizeof(SQLWCHAR));
#endif
if (result.empty() || result.size() >= 32767) {
throw std::runtime_error("Invalid ODBC_CONNECTION_STRING length");
}
result.push_back(0);
return result;
}
void connectWithRetry(SQLHDBC dbc, std::vector<SQLWCHAR>& connectionString) {
constexpr int maxAttempts = 4;
std::mt19937 random{std::random_device{}()};
std::uniform_int_distribution<int> jitter{0, 250};
for (int attempt = 1; attempt <= maxAttempts; ++attempt) {
requireSuccess(SQLSetConnectAttr(
dbc, SQL_ATTR_LOGIN_TIMEOUT,
reinterpret_cast<SQLPOINTER>(std::uintptr_t{30}), 0),
SQL_HANDLE_DBC, dbc, "Set login timeout");
SQLRETURN rc = SQLDriverConnectW(
dbc, nullptr, connectionString.data(), SQL_NTS,
nullptr, 0, nullptr, SQL_DRIVER_NOPROMPT);
if (SQL_SUCCEEDED(rc)) {
if (rc == SQL_SUCCESS_WITH_INFO) logDiagnostics(SQL_HANDLE_DBC, dbc);
std::cout << "event=connected attempt=" << attempt << '\n';
return;
}
bool transient = logDiagnostics(SQL_HANDLE_DBC, dbc);
if (!transient || attempt == maxAttempts) {
throw std::runtime_error("Connect failed");
}
auto delay = std::chrono::milliseconds{
(1 << (attempt - 1)) * 10000 + jitter(random)};
std::cerr << "event=connect_retry attempt=" << attempt
<< " delay_ms=" << delay.count() << '\n';
std::this_thread::sleep_for(delay);
}
}
int main() {
try {
auto connectionString = readConnectionString();
Handles handles;
if (!SQL_SUCCEEDED(SQLAllocHandle(
SQL_HANDLE_ENV, SQL_NULL_HANDLE, &handles.env))) {
throw std::runtime_error("Allocate environment");
}
requireSuccess(SQLSetEnvAttr(
handles.env, SQL_ATTR_ODBC_VERSION,
reinterpret_cast<SQLPOINTER>(std::uintptr_t{SQL_OV_ODBC3}), 0),
SQL_HANDLE_ENV, handles.env, "Set ODBC version");
requireSuccess(SQLAllocHandle(SQL_HANDLE_DBC, handles.env, &handles.dbc),
SQL_HANDLE_ENV, handles.env, "Allocate connection");
connectWithRetry(handles.dbc, connectionString);
handles.connected = true;
requireSuccess(SQLAllocHandle(SQL_HANDLE_STMT, handles.dbc, &handles.stmt),
SQL_HANDLE_DBC, handles.dbc, "Allocate statement");
requireSuccess(SQLSetStmtAttr(
handles.stmt, SQL_ATTR_QUERY_TIMEOUT,
reinterpret_cast<SQLPOINTER>(std::uintptr_t{10}), 0),
SQL_HANDLE_STMT, handles.stmt, "Set query timeout");
SQLWCHAR query[] = {'S', 'E', 'L', 'E', 'C', 'T', ' ', '1', 0};
requireSuccess(SQLExecDirectW(handles.stmt, query, SQL_NTS),
SQL_HANDLE_STMT, handles.stmt, "Execute probe");
requireSuccess(SQLFetch(handles.stmt),
SQL_HANDLE_STMT, handles.stmt, "Fetch probe");
SQLINTEGER value = 0;
SQLLEN indicator = 0;
requireSuccess(SQLGetData(handles.stmt, 1, SQL_C_SLONG,
&value, sizeof(value), &indicator),
SQL_HANDLE_STMT, handles.stmt, "Read probe");
if (indicator == SQL_NULL_DATA || value != 1) {
throw std::runtime_error("Unexpected probe result");
}
std::cout << "event=ready result=" << value << '\n';
return 0;
} catch (const std::exception& error) {
std::cerr << "event=failed operation=\"" << error.what() << "\"\n";
return 1;
}
}
Программа запрашивает 30-секундный тайм-аут соединения для каждой из не более четырёх попыток подключения и 10-секундный тайм-аут для запроса. Между неудачными попытками подключения после кратковременных сбоев он ждёт 10, 20 и 40 секунд, каждая с 0–250 миллисекундами случайного джиттера. Эти ограничения не устанавливают жёсткого общего предельного срока для аутентификации. В примере классифицируются выбранные временные ошибки подключения; адаптируйте политику к вашей рабочей нагрузке с помощью каталога временных ошибок Azure SQL. Он не повторяет команды приложения и операции записи.
ConnectRetryCount и ConnectRetryInterval настраивают устойчивость соединения для подходящих соединений, которые отключаются во время простоя. Они не повторяют начальное подключение и не повторно выполняют команды приложения. Держите задержки восстановления после простоя короче, чем тайм-аут вашего запроса. В примере фиксируются значения SQLSTATE и нативные номера ошибок вместо строк соединения или полных диагностических сообщений. Если вам нужен текст сообщения для устранения неполадок, зафиксируйте его в защищённом диагностическом журнале.
Соберите и запустите базовую версию
Используйте среду компиляции, соответствующую архитектуре процессора вашего приложения. В Windows выполните команды в Developer PowerShell for Visual Studio. В Linux и macOS используйте командную оболочку, в которой доступны компилятор и файлы разработки unixODBC.
cl /nologo /std:c++17 /EHsc /W4 odbc-baseline.cpp odbc32.lib
.\odbc-baseline.exe
Успешное первое соединение выводит следующий результат. Также могут появиться дополнительные диагностические записи.
event=connected attempt=1
event=ready result=1
Очищайте ODBC_CONNECTION_STRING , когда закончите: используйте Remove-Item Env:\ODBC_CONNECTION_STRING в PowerShell, или unset ODBC_CONNECTION_STRING в Bash или Zsh.
Для прослушивателей групп доступности и параметров отработки отказа используйте высокую доступность и аварийное восстановление.
Ключевые особенности
- Кроссплатформенность: тот же API на Windows, Linux и macOS.
- Аутентификация Microsoft Entra ID: управляемая идентификация, субъект-служба и интегрированная аутентификация, а также интерактивная аутентификация в Windows. Доступные методы зависят от конфигурации хоста и базы данных.
- Строгое шифрование: подключения TDS 8.0 с полной валидацией сертификата в версиях 18 и позднее.
- Always Encrypted: клиентское шифрование для конфиденциальных столбцов с поддержкой пользовательских поставщиков хранилищ ключей.
- Устойчивость соединения: Прозрачное восстановление соединения, которое оторвалось во время простоя.
-
Высокая доступность: поддержка прослушивателя группы доступности с
MultiSubnetFailover. - Классификация данных: Метаданные чувствительности для классифицированных столбцов.
- Векторный тип данных: нативная поддержка векторного типа.
- Распределённые транзакции: поддержка транзакций XA через координатор распределенных транзакций (Майкрософт) (MSDTC).
- Сопутствующие инструменты: sqlcmd и bcp, устанавливаются отдельно.
Начало работы
| Статья | Description |
|---|---|
| Скачайте драйвер ODBC для SQL Server | Установщики и пакеты для загрузки для всех поддерживаемых версий драйверов на всех трёх платформах. |
| Разработка приложений на C и C++ с помощью драйвера ODBC | Какие заголовки включать, в каком порядке, какие библиотеки связывать и как выбирать между асинхронным выполнением и потоками. |
| Подключитесь к базе данных и отправьте к ней запрос на C++ | Полный сэмпл на C++, который подключается, выполняет запрос и читает результаты, чтобы вы могли подтвердить свою настройку от конца до конца. |
| Жизненный цикл поддержки | Какие версии драйверов всё ещё поддерживаются, и дата прекращения поддержки каждой из них. |
| Различия между мажорными версиями | Что ломается при переходе с версии 17 на версию 18, начиная с изменения по умолчанию шифрования? |
Установка драйвера
| Статья | Description |
|---|---|
| Системные требования, установка и файлы драйверов (Windows) | Поддерживаемые версии Windows, командная строка установщика для тихого развертывания и место, где каждый файл драйвера попадает на диск. |
| Системные требования (Linux и macOS) | Какие дистрибутивы Linux и релизы macOS поддерживают каждая версия драйверов, плюс совместимость версий SQL Server. |
| Установите драйвер ODBC на Linux | Шаги менеджера пакетов для Alpine, Debian, Red Hat, SUSE, Ubuntu и Azure Linux, а также офлайн-установка и расположение файлов драйверов. |
| Установите драйвер ODBC на macOS | Шаги для tap-репозитория и формулы Homebrew в macOS, включая инструкции по установке версий 18, 17 или 13.1. |
| Установите менеджер драйверов unixODBC (Linux и macOS) | Установите или обновите unixODBC — менеджер драйверов, который загружает драйвер ODBC на Linux и macOS. |
Настройка и подключение
| Статья | Description |
|---|---|
| Ключевые слова и атрибуты DSN и строки подключения | Полный каталог ключевых слов строк подключения, записей DSN и атрибутов SQLSetConnectAttr с допустимыми значениями для каждого из них. |
| Ключевые слова для строк соединения и имена источников данных (Linux и macOS) | Как odbc.ini и odbcinst.ini определяют DSN в Linux и macOS, а также настройки безопасности транспортного уровня (TLS) и поддержания соединения протокола управления передачей (TCP), специфичные для этих платформ. |
| Администратор источников данных ODBC DSN (Windows) | Настройте источник данных через пользовательский интерфейс Windows вместо строка подключения. |
| Пул соединений с учётом драйвера (Windows) | Какие ключевые слова и атрибуты строка подключения помещают соединение в отдельный пул, а какие требуют дополнительного сброса. |
Аутентифицировать и защитить
| Статья | Description |
|---|---|
| Используйте Microsoft Entra ID с драйвером ODBC | Каждое Authentication значение ключевого слова — от управляемой идентичности и принципа сервиса до интерактивных и интегрированных, с необходимой каждой системой. |
| Используйте Always Encrypted с драйвером ODBC | Зашифруйте чувствительные значения столбцов перед отправкой в базу данных, учитывая описание API драйвера и задокументированные ограничения. |
| Классификация данных | Считывать метки конфиденциальности, которые сервер назначает классифицированным столбцам, чтобы приложение могло применять собственную политику защиты данных. |
| Используйте интегрированную аутентификацию (Linux и macOS) | Настройте Kerberos так, чтобы клиент Linux или macOS мог подключаться к учетным данным Windows вместо входа через SQL Server. |
Высокий уровень доступности и устойчивость
| Статья | Description |
|---|---|
| Устойчивость подключения | Как ConnectRetryCount и ConnectRetryInterval восстанавливают соединение, когда сервер разрывает его во время простоя, и какие IMCxx ошибки возвращает драйвер, когда восстановление невозможно. |
| Высокий уровень доступности и аварийное восстановление | Подключайтесь через прослушиватель группы доступности и используйте MultiSubnetFailover, чтобы переключение при отказе не зависало из-за тайм-аута подсети. |
| Используйте прозрачное разрешение сетевых IP-адресов | Как устаревший TransparentNetworkIPResolution запасной вариант упорядочивает попытки подключения по нескольким IP-адресам Интернет-протокола и почему MultiSubnetFailover заменяет его. |
Работа с данными
| Статья | Description |
|---|---|
| Векторный тип данных | Привязать, отправить и получить тип vector, включая его нативное представление на C и поддержку пакетного копирования. |
| Используйте транзакции XA с DTC | Зарегистрируйте SQL Server в распределённой транзакции через координатор распределенных транзакций (Майкрософт) на Windows, Linux или macOS. |
| Руководство по программированию (Linux и macOS) | Найдите рекомендации по программированию Linux и macOS, включая статус функций, параметры набора символов, OpenSSL и Alpine Linux. |
Диагностика и устранение неполадок
| Статья | Description |
|---|---|
| Устранение неполадок шифрования соединения | Исправьте ошибки сертификата и шифрования, которые появляются в версии 18, потому что она шифрует по умолчанию. |
| Трассировка доступа к данным (Linux и macOS) | Включите трассировку драйверов и зафиксируйте файл журнала, когда вам нужно увидеть, какие вызовы действительно совершает ваше приложение. |
| Известные проблемы (Linux и macOS) | Подтверждённые дефекты и их обходные пути. Проверьте здесь, прежде чем подавать заявление в поддержку. |
| Часто задаваемые вопросы (Linux и macOS) | Краткие ответы на вопросы, которые чаще всего возникают о драйвере на Linux и macOS. |
Примечания к релизу и исправления ошибок
| Статья | Description |
|---|---|
| Заметки к релизу для Windows | Новые функции, изменения поведения и исправления в каждом выпуске драйверов Windows. |
| Заметки к релизу для Linux и macOS | Новые функции, изменения поведения и исправления в каждом выпуске драйверов Linux и macOS. |
| Заметки к релизу инструментов SQL Server | Изменения в утилитах sqlcmd и bcp , которые устанавливаются отдельно от драйвера на Linux и macOS. |
Ссылки
| Статья | Description |
|---|---|
| Драйвер ODBC на Windows | Обзор версий по версиям того, что поддерживает драйвер в Windows, и индекс статей, специфичных для Windows. |
| Особенности драйвера ODBC в Windows | В каком релизе появились все функции Windows, а также изменения в поведении, связанные с ней. |
Запрашивание функции
Чтобы запросить новую функцию, отправьте предложение через отзывы о SQL Server.
Связанные материалы
- Справочник программиста ODBC: спецификация ODBC API, которую реализует этот драйвер, задокументирована отдельно от самого драйвера.
- Функции нативного клиента SQL Server: исторический контекст API. Проверьте актуальную документацию драйверов на предмет поддержки платформ, аутентификации и поведения шифрования. Руководство по нативному клиенту и OLE DB не определяет текущую поддержку драйверов ODBC.
- Утилита BCP: Утилита массового копирования, устанавливаемая отдельно от драйвера.
- Утилита sqlcmd: Утилита командного запроса, устанавливаемая отдельно от драйвера.
- Матрица поддержки характеристик драйвера
- Блог о драйверах SQL Server