Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Область применения: SQL Server База данных SQL Azure
В этом быстром старте вы создаёте консольное приложение на C++ на Windows, Linux или macOS. Приложение подключается к AdventureWorksLT базе данных с помощью Microsoft ODBC Driver 18 for SQL Server, привязывает параметр запроса, выполняет запрос и считывает строки результатов.
Prerequisites
- Microsoft ODBC Driver 18 для SQL Server. Установите драйвер для Windows, Linux или macOS.
- Компилятор C++17 и файлы разработки платформы ODBC:
- На Windows установите Visual Studio 2022 или Build Tools for Visual Studio 2022 с рабочей нагрузкой для настольной разработки на C++. Windows SDK включает заголовочные файлы ODBC и
odbc32.lib. - На Linux установите компилятор на C++ и пакет разработки unixODBC для вашего дистрибутива. Пакет содержит заголовки ODBC и
libodbc. - На macOS установите командные инструменты Xcode и unixODBC из Homebrew.
- На Windows установите Visual Studio 2022 или Build Tools for Visual Studio 2022 с рабочей нагрузкой для настольной разработки на C++. Windows SDK включает заголовочные файлы ODBC и
- База данных в База данных SQL Azure или SQL Server, содержащая
AdventureWorksLTобразцы данных. Для База данных SQL Azure при создании одной базы данных выберите источник данных Sample. Для SQL Server восстанавливайтеAdventureWorksLTрезервную копию из образцов баз данных AdventureWorks.
Проверьте драйвер
Убедитесь, что менеджер драйверов может найти Microsoft ODBC Driver 18 for SQL Server.
Выполните эту команду в PowerShell:
Get-OdbcDriver -Name "ODBC Driver 18 for SQL Server"
Каждая команда должна содержать список ODBC Driver 18 for SQL Server. Если драйвера нет, переустановите его перед продолжением.
Настройте соединение
Приложение считывает полную строку подключения из переменной окружения ODBC_CONNECTION_STRING. Он не отображает строка подключения и не принимает её как аргумент командной строки.
Используйте Driver 18 строка подключения, которая подходит для вашей базы данных и метода аутентификации. Следующий пример SQL-аутентификации работает на Windows, Linux и macOS, когда база данных поддерживает SQL-аутентификацию:
Driver={ODBC Driver 18 for SQL Server};Server=tcp:<server>,1433;Database=<database>;UID=<user_id>;PWD=<password>;Encrypt=yes;TrustServerCertificate=no;
Для вариантов аутентификации Microsoft Entra см. раздел «Использовать Microsoft Entra ID с драйвером ODBC». Сведения обо всех поддерживаемых параметрах см. в разделе Ключевые слова и атрибуты DSN и строки подключения.
Microsoft ODBC Driver 18 по умолчанию поддерживает шифрование. Уточните Encrypt=yes , чтобы требования приложения были чётко выражены. Оставьте TrustServerCertificate=no в рабочей среде, чтобы драйвер проверял сертификат сервера. Сертификат должен сопоставлять имя сервера и цепочку с органом сертификации, которому доверяет клиент. Для рекомендаций по конфигурации см. раздел Сбои проверки сертификатов.
Предостережение
TrustServerCertificate=yes Пропускает проверку сертификата. Используйте его только для изолированной локальной разработки, пока настраиваете сертификат, которому доверяет клиент. Не используйте его в рабочей среде.
Задайте переменную окружения, не добавляя строку подключения в историю оболочки.
Open Developer PowerShell для VS 2022. Выполните эти команды, а затем вставьте строку подключения в ответ на приглашение:
$secureConnectionString = Read-Host "ODBC connection string" -AsSecureString
$env:ODBC_CONNECTION_STRING = [System.Net.NetworkCredential]::new(
"", $secureConnectionString).Password
$secureConnectionString = $null
Переменная среды позволяет не хранить строку подключения в исходном файле, но процесс и его дочерние процессы могут её читать. Для производственных приложений используйте аутентификацию Microsoft Entra, где возможно, и извлекайте секреты из защищённого хранилища во время выполнения.
Создание приложения
Создайте каталог проекта и перейдите в него:
Создайте файл с именем
odbc-quickstart.cppсо следующим кодом:#ifdef _WIN32 #include <windows.h> #endif #include <sql.h> #include <sqlext.h> #include <sqltypes.h> #include <cstdlib> #include <iomanip> #include <iostream> #include <string> std::string ReadEnvironmentVariable(const char* name) { #ifdef _WIN32 char* value = nullptr; std::size_t length = 0; if (_dupenv_s(&value, &length, name) != 0 || value == nullptr) return {}; std::string result(value); std::free(value); return result; #else const char* value = std::getenv(name); return value == nullptr ? std::string{} : value; #endif } void PrintDiagnostics(SQLSMALLINT handleType, SQLHANDLE handle) { SQLCHAR state[6]; SQLINTEGER nativeError; SQLCHAR message[SQL_MAX_MESSAGE_LENGTH]; SQLSMALLINT messageLength; for (SQLSMALLINT record = 1; SQL_SUCCEEDED(SQLGetDiagRec(handleType, handle, record, state, &nativeError, message, sizeof(message), &messageLength)); ++record) { std::cerr << '[' << state << "] (" << nativeError << ") " << message << '\n'; } } bool Succeeded(SQLRETURN result, SQLSMALLINT handleType, SQLHANDLE handle) { if (SQL_SUCCEEDED(result)) return true; PrintDiagnostics(handleType, handle); return false; } struct OdbcHandles { SQLHENV environment = SQL_NULL_HENV; SQLHDBC connection = SQL_NULL_HDBC; SQLHSTMT statement = SQL_NULL_HSTMT; ~OdbcHandles() { if (statement != SQL_NULL_HSTMT) SQLFreeHandle(SQL_HANDLE_STMT, statement); if (connection != SQL_NULL_HDBC) { SQLDisconnect(connection); SQLFreeHandle(SQL_HANDLE_DBC, connection); } if (environment != SQL_NULL_HENV) SQLFreeHandle(SQL_HANDLE_ENV, environment); } }; int main() { std::string connectionString = ReadEnvironmentVariable("ODBC_CONNECTION_STRING"); if (connectionString.empty()) { std::cerr << "Set ODBC_CONNECTION_STRING before running.\n"; return 1; } OdbcHandles handles; SQLRETURN result = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &handles.environment); if (!SQL_SUCCEEDED(result)) { std::cerr << "Unable to allocate an ODBC environment handle.\n"; return 1; } result = SQLSetEnvAttr( handles.environment, SQL_ATTR_ODBC_VERSION, reinterpret_cast<SQLPOINTER>(SQL_OV_ODBC3_80), 0); if (!Succeeded(result, SQL_HANDLE_ENV, handles.environment)) return 1; result = SQLAllocHandle( SQL_HANDLE_DBC, handles.environment, &handles.connection); if (!Succeeded(result, SQL_HANDLE_ENV, handles.environment)) return 1; result = SQLDriverConnect( handles.connection, nullptr, reinterpret_cast<SQLCHAR*>(connectionString.data()), SQL_NTS, nullptr, 0, nullptr, SQL_DRIVER_NOPROMPT); if (!Succeeded(result, SQL_HANDLE_DBC, handles.connection)) return 1; result = SQLAllocHandle( SQL_HANDLE_STMT, handles.connection, &handles.statement); if (!Succeeded(result, SQL_HANDLE_DBC, handles.connection)) return 1; SQLINTEGER minimumProductId = 0; SQLLEN minimumProductIdLength = 0; result = SQLBindParameter( handles.statement, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 10, 0, &minimumProductId, 0, &minimumProductIdLength); if (!Succeeded(result, SQL_HANDLE_STMT, handles.statement)) return 1; SQLCHAR query[] = "SELECT TOP (5) ProductID, Name " "FROM SalesLT.Product " "WHERE ProductID > ? " "ORDER BY ProductID;"; result = SQLExecDirect(handles.statement, query, SQL_NTS); if (!Succeeded(result, SQL_HANDLE_STMT, handles.statement)) return 1; std::cout << "Product ID Name\n" << "---------- ----\n"; while (SQL_SUCCEEDED(result = SQLFetch(handles.statement))) { SQLINTEGER productId; SQLLEN productIdLength; SQLCHAR productName[256]; SQLLEN productNameLength; result = SQLGetData( handles.statement, 1, SQL_C_SLONG, &productId, sizeof(productId), &productIdLength); if (!Succeeded(result, SQL_HANDLE_STMT, handles.statement)) return 1; result = SQLGetData( handles.statement, 2, SQL_C_CHAR, productName, sizeof(productName), &productNameLength); if (!Succeeded(result, SQL_HANDLE_STMT, handles.statement)) return 1; std::cout << std::left << std::setw(12) << productId << productName << '\n'; } if (result != SQL_NO_DATA) { PrintDiagnostics(SQL_HANDLE_STMT, handles.statement); return 1; } return 0; }
Приложение использует только стандартный ODBC API, поэтому включает заголовки менеджера драйверов и ссылки на библиотеку менеджера драйверов. Строка строка подключения выбирает Microsoft ODBC Driver 18 для SQL Server во время выполнения.
SQL_DRIVER_NOPROMPT препятствует SQLDriverConnect открытию диалога настройки. Если строка подключения неполная, вызов завершается с ошибкой, и приложение печатает все диагностические записи.
Запрос связывает 0 с параметром SQL Server типа int, считывает первые пять продуктов из SalesLT.Product и извлекает идентификатор и имя каждого продукта с помощью SQLGetData.
Создание и запуск приложения
В том же окне Developer PowerShell скомпилировать приложение:
cl /std:c++17 /EHsc /W4 odbc-quickstart.cpp /link odbc32.libЗапустите приложение:
.\odbc-quickstart.exe
Стандартный вывод приложения следующий:
Product ID Name
---------- ----
680 HL Road Frame - Black, 58
706 HL Road Frame - Red, 58
707 Sport-100 Helmet, Red
708 Sport-100 Helmet, Black
709 Mountain Bike Socks, M
Очистите строку подключения по завершении.