Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Версия: 18.7.1.1
Дата: 7 сентября 2026 года
Чтобы вызвать ODBC API из C или C++, включите sql.h, sqlext.h, и sqltypes.h, затем свяжитесь с библиотекой импорта менеджера драйверов. Чтобы использовать расширения SQL Server, которые Microsoft ODBC Driver for SQL Server добавляет поверх стандарта ODBC, также включайте msodbcsql.h, и включайте его после основных заголовков ODBC.
Относится к: Microsoft ODBC Driver 18 for SQL Server на Windows, Linux и macOS. В версии 17 используется то же имя заголовочного файла, с путём установки 170 и именем библиотеки msodbcsql17.
Заголовки и библиотеки
Платформа предоставляет основные заголовки ODBC и менеджер драйверов, а не пакет драйверов. На Windows они поставляются в Windows SDK. На Linux и macOS они поставляются в пакете разработки unixODBC. SDK драйвера предоставляет только msodbcsql.h и библиотеку для импорта массового копирования.
| То, что ты называешь | Headers | Windows | Linux | macOS |
|---|---|---|---|---|
| ODBC API |
sql.h, sqlext.h, sqltypes.h |
odbc32.lib |
-lodbc |
-lodbc |
| ODBC API, точки входа в Unicode | Добавить sqlucode.h |
odbc32.lib |
-lodbc |
-lodbc |
| API установщика ODBC | Добавить odbcinst.h |
odbccp32.lib |
-lodbcinst |
-lodbcinst |
| Расширения драйверов SQL Server | Добавить msodbcsql.h |
Никакой дополнительной библиотеки | Никакой дополнительной библиотеки | Никакой дополнительной библиотеки |
Функции массового копирования (bcp_*) |
Добавить msodbcsql.h |
msodbcsql18.lib |
-lmsodbcsql-18 |
-lmsodbcsql.18 |
Имя ссылки для массового копирования различается в зависимости от платформы, потому что имена файлов различаются. В Linux -lmsodbcsql-18 разрешается через символическую ссылку libmsodbcsql-18.so в /usr/lib, в котором компоновщик уже ищет, поэтому -L не нужен. В macOS драйвер поставляется как libmsodbcsql.18.dylib, которому соответствует -lmsodbcsql.18, но каталог библиотек Homebrew не входит в стандартный путь поиска на Apple Silicon. Добавьте -L$(brew --prefix)/lib, когда связываете функции массового копирования.
Только функции массового копирования нуждаются в собственной библиотеке драйвера. Атрибуты соединения, атрибуты операторов, атрибуты столбцов и идентификаторы типов SQL Server — это макросы и определения типов, поэтому включение msodbcsql.h для них достаточно.
API установщика является отдельной библиотекой от ODBC API. Вызов функции, такой как SQLGetPrivateProfileString без -lodbcinst , на Linux или macOS не работает во время ссылки с неопределённой ссылкой, а не во время компиляции.
Чтобы установить пакет разработки unixODBC, который предоставляет основные заголовки на Linux и macOS, см. раздел «Установить менеджер драйверов unixODBC».
Включите wchar.h до msodbcsql.h в коде на C на Linux и macOS
Версии msodbcsql.h для Linux и macOS объявляют интерфейс поставщика хранилища ключей Always Encrypted с помощью wchar_t, но не включают заголовочный файл, в котором определяется этот тип. В C++ — wchar_t это ключевое слово, поэтому единицы перевода на C++ строятся без необходимости дополнительных заголовков. В C — wchar_t это typedef, поэтому сначала нужно включить <wchar.h> в единицу перевода на C:
#include <wchar.h>
Если не включить <wchar.h>, компилятор сообщает об ошибках unknown type name 'wchar_t' внутри msodbcsql.h. Добавление директивы include в Windows безвредно, поэтому лучше добавить её в общий исходный файл, а не помещать под условную компиляцию для платформы.
Включите msodbcsql.h после основных заголовков ODBC
Всё, что msodbcsql.h определяет за пределами макросов драйвера, находится внутри #ifdef ODBCVER блока и sql.h определяет ODBCVER. Если вы включите msodbcsql.h сначала, препроцессор пропускает весь этот блок, и заголовок ничего не добавляет. Компилятор не выдаёт предупреждения.
/* Correct order. */
#ifdef _WIN32
#include <windows.h>
#endif
#include <wchar.h>
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
#include <msodbcsql.h>
Включая msodbcsql.h до sql.h , всё внутри ODBCVER блока остаётся неопределённым. Компилятор сообщает об ошибке в месте использования, а не в директиве include:
order-wrong.c(7): error C2065: 'SQL_COPT_SS_BCP': undeclared identifier
В Windows необходимо подключить windows.h перед заголовками ODBC. Копии sqltypes.h и sql.h в Windows SDK используют типы Windows, такие как DWORD и LONG.
msodbcsql.hобворачивает свои структуры SQL Server в pshpack8.h и poppack.h. Без windows.hэтого сборка проваливается внутри самих заголовков SDK.
Где установлены SDK-файлы
| Platform | msodbcsql.h |
Библиотека для массового копирования |
|---|---|---|
| Windows | %ProgramFiles%\Microsoft SQL Server\Client SDK\ODBC\180\SDK\Include |
%ProgramFiles%\Microsoft SQL Server\Client SDK\ODBC\180\SDK\Lib\<architecture>\msodbcsql18.lib |
| Linux | /opt/microsoft/msodbcsql18/include |
/opt/microsoft/msodbcsql18/lib64, с символьной /usr/lib/libmsodbcsql-18.so ссылкой |
| macOS | $(brew --prefix msodbcsql18)/include/msodbcsql18 |
$(brew --prefix)/lib/libmsodbcsql.18.dylib |
В Windows папка Lib содержит подпапку для каждой архитектуры процессора, которую установщик размещал на машине, напримерx64, , x86, или arm64. Добавьте папку Include в путь поиска включаемых файлов компилятора, а подпапку архитектуры — в путь поиска библиотек компоновщика.
В Linux разделяемый объект имеет номер версии, имя вида libmsodbcsql-18.6.so.2.1 и не содержит SONAME. Пакет устанавливает /usr/lib/libmsodbcsql-18.so, указывающий на него, что и позволяет -lmsodbcsql-18 разрешаться без параметра -L. Ссылайтесь через эту символическую ссылку, а не называйте версионный файл, чтобы обновление драйвера не сломало вашу сборку.
На macOS Homebrew устанавливается в свой собственный префикс: /opt/homebrew на компьютерах с Apple silicon и /usr/local на компьютерах с Intel. Оба префикса являются символическими ссылками в версионный каталог Cellar. Используйте brew --prefix msodbcsql18 и brew --prefix unixodbc в вашем скрипте сборки вместо того, чтобы жёстко прописывать любой из этих вариантов.
Число в пути указывает на основную версию драйвера. Версия 17 устанавливается в ...\ODBC\170\SDK\ в Windows и в /opt/microsoft/msodbcsql17/ в Linux, а её библиотека импорта — msodbcsql17.lib.
Для полного инвентаря файлов по платформам смотрите Системные требования, установка и файлы драйверов (Windows), Установка драйвера ODBC на Linux и Установка драйвера ODBC на macOS.
Проверьте свою конфигурацию сборки
Эта программа компилирует по заголовкам, ссылается на менеджер драйверов и перечисляет драйверы, которые менеджер драйверов видит. Он не подключается, поэтому отделяет проблему сборки или регистрации от сети или учетных данных.
#include <stdio.h>
#include <wchar.h>
#ifdef _WIN32
#include <windows.h>
#endif
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
#include <msodbcsql.h>
static void PrintDiagnostics(SQLSMALLINT handleType, SQLHANDLE handle)
{
SQLCHAR state[6];
SQLINTEGER native;
SQLCHAR message[SQL_MAX_MESSAGE_LENGTH];
SQLSMALLINT length;
for (SQLSMALLINT record = 1;
SQL_SUCCEEDED(SQLGetDiagRec(handleType, handle, record, state, &native,
message, sizeof(message), &length));
++record)
{
fprintf(stderr, " [%s] (%ld) %s\n", state, (long)native, message);
}
}
int main(void)
{
SQLHENV environment = SQL_NULL_HENV;
SQLRETURN rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &environment);
if (!SQL_SUCCEEDED(rc))
{
fprintf(stderr, "SQLAllocHandle for the environment failed.\n");
return 1;
}
rc = SQLSetEnvAttr(environment, SQL_ATTR_ODBC_VERSION,
(SQLPOINTER)SQL_OV_ODBC3_80, 0);
if (!SQL_SUCCEEDED(rc))
{
fprintf(stderr, "SQLSetEnvAttr for SQL_OV_ODBC3_80 failed.\n");
PrintDiagnostics(SQL_HANDLE_ENV, environment);
SQLFreeHandle(SQL_HANDLE_ENV, environment);
return 1;
}
printf("Driver name from msodbcsql.h: %s\n", SQLODBC_DRIVER_NAME);
printf("Installed drivers:\n");
SQLCHAR description[256];
SQLSMALLINT descriptionLength = 0;
SQLUSMALLINT direction = SQL_FETCH_FIRST;
while (SQL_SUCCEEDED(SQLDrivers(environment, direction,
description, sizeof(description), &descriptionLength,
NULL, 0, NULL)))
{
printf(" %s\n", description);
direction = SQL_FETCH_NEXT;
}
SQLFreeHandle(SQL_HANDLE_ENV, environment);
return 0;
}
Создайте её как узкую программу для персонажей.
SQLODBC_DRIVER_NAME расширяется в широкую строку, когда определён UNICODE или _UNICODE, что printf с %s не может обработать.
cl /W4 /I "%ProgramFiles%\Microsoft SQL Server\Client SDK\ODBC\180\SDK\Include" odbc-build-check.c /link odbc32.lib
На Windows, /W4 сообщает о двух предупреждениях C4201: nonstandard extension used: nameless struct/union из копии sqlext.h из Windows SDK. Эти предупреждения поступают из заголовка SDK, а не из вашего кода, и сборка проходит успешно.
Первая строка показывает имя водителя, скомпилированное в ваш бинарный файл. Остальное — это собственный список менеджера драйверов, поэтому если драйвер, который вы ожидаете увидеть, отсутствует, то это проблема регистрации, а не проблема сборки. Ваш список будет отличаться, и он включает все установленные драйверы ODBC, а не только SQL Server:
Driver name from msodbcsql.h: ODBC Driver 18 for SQL Server
Installed drivers:
SQL Server
ODBC Driver 17 for SQL Server
ODBC Driver 18 for SQL Server
Microsoft Access Driver (*.mdb, *.accdb)
Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)
Microsoft Access Text Driver (*.txt, *.csv)
Microsoft Access dBASE Driver (*.dbf, *.ndx, *.mdx)
Формируйте строку подключения из SQLODBC_DRIVER_NAME, а не из строкового литерала. Макрос учитывает заголовочный файл, по которому выполнялась компиляция, поэтому при обновлении SDK имя драйвера обновляется в одном месте.
Что msodbcsql.h добавляет в API ODBC
msodbcsql.h расширяет стандартный API ODBC специфическими возможностями SQL Server. Каждое семейство занимает непрерывный числовой диапазон, отсчитываемый от базовой константы. Диапазоны не уникальны для разных семейств, поэтому функция, которой вы передаёте значение, отличает их.
| Семья | Базовая константа | Value |
|---|---|---|
Атрибуты соединения для SQLSetConnectAttr |
SQL_COPT_SS_BASE |
1200 |
Атрибуты утверждений для SQLSetStmtAttr |
SQL_SOPT_SS_BASE |
1225 |
Атрибуты столбцов для SQLColAttribute |
SQL_CA_SS_BASE |
1200 |
Типы информации для SQLGetInfo |
SQL_INFO_SS_FIRST |
1199 |
Диагностические поля для SQLGetDiagField |
SQL_DIAG_SS_BASE |
-1150 |
| Диагностические динамические коды функций | SQL_DIAG_DFC_SS_BASE |
-200 |
Заголовок также объявляет:
- Атрибуты аутентификации, включая
SQL_COPT_SS_AUTHENTICATIONиSQL_COPT_SS_ACCESS_TOKEN, которые содержат настройки Microsoft Entra ID и токены доступа. - Идентификаторы типов SQL в диапазоне -150–-199 для SQL Server типов, которые ODBC не определяет:
SQL_SS_VARIANT,SQL_SS_UDT, ,SQL_SS_XMLSQL_SS_TABLE,SQL_SS_TIME2SQL_SS_TIMESTAMPOFFSET, , иSQL_SS_VECTOR. Они обозначают тип SQL, поэтому их передают там, где ODBC ожидает тип SQL, например, в качестве аргументаParameterTypeуSQLBindParameter. - Три совпадающих типа C для буферной стороны:
SQL_C_SS_TIME2,SQL_C_SS_TIMESTAMPOFFSET, иSQL_C_SS_VECTOR. Другие типы SQL Server связываются со стандартным типом ODBC C, таким какSQL_C_BINARYилиSQL_C_WCHAR, поэтому у них нетSQL_C_SS_*аналога. - Структуры, к которым типы
SQL_C_SS_*связываются:SQL_SS_TIME2_STRUCT,SQL_SS_TIMESTAMPOFFSET_STRUCT, иSQL_SS_VECTOR_STRUCT. - Массовое копирование прототипов и макросов, включая
bcp_init,bcp_bind,bcp_sendrowbcp_batch, иbcp_done. ПараметрыBCP_ENCRYPT_OFF,BCP_ENCRYPT_ONиBCP_ENCRYPT_STRICTопции находятся только в заголовке Windows.
Каждая платформа поставляет свою копию msodbcsql.h, и не каждая из них объявляет одни и те же символы. Структура SQLPERF и атрибуты подключения к счётчику производительности, которые её заполняют, такие как SQL_COPT_SS_PERF_DATA и SQL_COPT_SS_PERF_QUERY, определены только в заголовочном файле Windows. Заголовки Linux и macOS не указывают их, и драйвер не собирает данные о производительности на этих платформах. См. Руководство по программированию (Linux и macOS).
Сведения о ключевых словах строки подключения, которым соответствуют эти атрибуты, см. в разделе DSN, ключевые слова и атрибуты строки подключения. Для настройки Microsoft Entra ID см. раздел «Использовать Microsoft Entra ID с драйвером ODBC». Для векторного типа см. Векторный тип данных.
Выберите между асинхронным выполнением и потоками
Некоторые функции ODBC могут выполняться как синхронно, так и асинхронно. В синхронном режиме драйвер не возвращает управление, пока сервер не ответит. В асинхронном режиме драйвер возвращается SQL_STILL_EXECUTING сразу, и приложение повторяет тот же вызов с теми же аргументами, пока не получит другой код возврата. Любой другой код возврата, включая SQL_ERROR, означает завершение операции.
Асинхронный режим имеет две формы, и вы используете одну из них. Вызовите SQLGetInfo с SQL_ASYNC_MODE, чтобы узнать, какой из них поддерживается драйвером. Возвращает SQL_AM_STATEMENT, если драйвер поддерживает управление для каждого оператора, SQL_AM_CONNECTION, если этот параметр применяется ко всему соединению, или SQL_AM_NONE, если драйвер вообще не выполняет функции асинхронно.
Форма инструкции включает асинхронный режим для одного дескриптора инструкции. Все остальные инструкции в этом соединении остаются синхронными, поэтому вы можете выполнять оба типа одновременно:
SQLSetStmtAttr(hStmt, SQL_ATTR_ASYNC_ENABLE,
(SQLPOINTER)SQL_ASYNC_ENABLE_ON, SQL_IS_INTEGER);
Если SQL_ASYNC_MODE возвращает значение SQL_AM_CONNECTION, атрибут оператора доступен только для чтения, и этот вызов возвращает SQL_ERROR с SQLSTATE HYC00. Используйте форму соединения вместо этого.
Форма дескриптора соединения включает асинхронный режим для каждого дескриптора оператора, который вы впоследствии выделяете для этого соединения. Влияет ли это также на уже существующие дескрипторы — определяется драйвером, поэтому задайте его перед выделением каких-либо операторов:
SQLSetConnectAttr(hDbc, SQL_ATTR_ASYNC_ENABLE,
(SQLPOINTER)SQL_ASYNC_ENABLE_ON, SQL_IS_INTEGER);
Вызов возвращает SQL_ERROR с SQLSTATE HY010, если для оператора данного соединения функция всё ещё выполняется асинхронно. Открытый курсор сам по себе не блокирует вызов. Передача SQL_ASYNC_ENABLE_OFF переводит все инструкции в соединении обратно в синхронный режим.
Чтобы узнать, сколько асинхронных инструкций драйвер поддерживает одновременно в одном соединении, вызовите SQLGetInfo, передав SQL_MAX_ASYNC_CONCURRENT_STATEMENTS. Microsoft ODBC Driver 18 для SQL Server возвращает 1, поэтому исходите из того, что для каждого соединения возможна только одна незавершённая асинхронная операция, а сверх этого открывайте дополнительные соединения или используйте потоки. См. асинхронное исполнение (метод опроса).
Нити — это другой способ поддерживать несколько операций в полёте. ODBC требует, чтобы драйверы на многопоточных операционных системах были безопасны для потоков, поэтому поток может выполнять блокирующий вызов ODBC, пока другие потоки продолжают работать. Это позволяет избежать цикла опроса и повторяющихся вызовов функций, необходимых асинхронному режиму. Предоставьте каждому потоку собственный дескриптор оператора. Скорее всего, драйвер будет выполнять последовательно два потока, если они одновременно используют один и тот же дескриптор, поэтому при совместном использовании одного дескриптора вы теряете возможность параллельного выполнения. См. Многопоточность. Предпочитайте потоки для нового кода и измеряйте свою нагрузку перед конвертацией асинхронного кода, который уже работает.
В Windows менеджер драйверов также поддерживает метод уведомлений, который убирает цикл опросов. Вы связываете событие Win32 с дескриптором соединения или дескриптором инструкции. Функция всё равно возвращается SQL_STILL_EXECUTING сразу, и менеджер драйвера сигнализирует о событии после завершения операции. Опрос отключён в этом режиме: повторный вызов исходной функции возвращает SQL_ERROR с SQLSTATE IM017. Вызовите SQLCompleteAsync, чтобы вместо этого получить результат. Для этого нужны версии ODBC 3.81 и более поздние версии менеджера драйверов, и драйвер тоже должен это поддерживать. Позвоните SQLGetInfo с помощью SQL_ASYNC_NOTIFICATION, чтобы проверить. Получаемое вами значение зависит от версии ODBC, которую объявляет ваше приложение: при использовании Microsoft ODBC Driver 18 for SQL Server приложение, которое задаёт SQL_ATTR_ODBC_VERSION значение SQL_OV_ODBC3_80, получает SQL_ASYNC_NOTIFICATION_CAPABLE, а приложение, которое объявляет SQL_OV_ODBC3, получает SQL_ASYNC_NOTIFICATION_NOT_CAPABLE от того же драйвера. Объявите SQL_OV_ODBC3_80 перед тем, как выделять соединение. См. асинхронное выполнение (метод уведомления) и пример метода уведомления.
Отменить невыполненную операцию
SQLCancel отменяет операцию, которая всё ещё выполняется с использованием дескриптора инструкции. Вызовите его из другого потока или из цикла опроса, передав дескриптор незавершённого вызова.
Используйте SQLCancel только для этого. Чтобы прекратить чтение набора результатов, который вам больше не нужен, вместо этого вызовите SQLCloseCursor или SQLMoreResults.
Переход с sqlncli.h на msodbcsql.h
SQL Server Native Client закрыт, поэтому приложения, использующие его, должны перейти на Microsoft ODBC Driver for SQL Server. Это тот же API ODBC, поэтому большая часть работы связана с переименованием входных данных сборки и имени драйвера в строке подключения.
| Нативный клиент SQL Server | Microsoft драйвер ODBC 18 для SQL Server |
|---|---|
sqlncli.h |
msodbcsql.h |
sqlncli11.lib |
msodbcsql18.lib |
sqlncli11.dll |
msodbcsql18.dll |
Driver={SQL Server Native Client 11.0} |
Driver={ODBC Driver 18 for SQL Server} |
SQLNCLI_VER |
SQLODBC_VER |
Заголовок msodbcsql.h по-прежнему определяет макросы имён SQLNCLI_*, поэтому исходный код, который их использует, по-прежнему компилируется. Эти определения защищены с помощью #ifndef __sqlncli_h__, а это значит, что нельзя включать оба заголовочных файла в одну и ту же единицу трансляции. Уберите включение sqlncli.h .
Две вещи не переносятся:
- Функции API метаданных распределённых запросов, возвращающие списки связанных серверов и их каталогов, не декларируются в
msodbcsql.h. Они были специфичны для нативного клиента SQL Server. - Версия 18 по умолчанию шифрует соединения и подтверждает сертификат сервера. Native Client — нет. Строка подключения, которая работала с Native Client, может завершиться ошибкой при первом подключении, пока вы не настроите доверие к сертификату или явно не зададите
Encrypt. См. раздел «Устранение неисправности шифрования соединения».
Для остальных изменений версий с 17 по версию 18 см . раздел «Основные различия в версиях».