Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Dotyczy:programu SQL Server
Azure SQL Database
W tym szybkim starcie budujesz aplikację konsolową C++ na Windows, Linux lub macOS. Aplikacja łączy się z bazą AdventureWorksLT danych, używając sterownika Microsoft ODBC 18 dla SQL Server, wiąże parametr zapytania, wykonuje zapytanie i odczytuje wiersze wyników.
Prerequisites
- Microsoft ODBC Driver 18 dla SQL Server. Zainstaluj sterownik dla Windows, Linux lub macOS.
- Kompilator C++17 oraz pliki programistyczne ODBC na platformie:
- Na Windows zainstaluj Visual Studio 2022 lub Build Tools for Visual Studio 2022 wraz z programowaniem desktopowym z C++. Pakiet SDK systemu Windows zawiera nagłówki ODBC oraz
odbc32.lib. - Na Linuksie zainstaluj kompilator C++ oraz pakiet programistyczny unixODBC dla swojej dystrybucji. Pakiet dostarcza nagłówki ODBC oraz
libodbc. - Na macOS zainstaluj narzędzia wiersza poleceń Xcode oraz unixODBC z Homebrew.
- Na Windows zainstaluj Visual Studio 2022 lub Build Tools for Visual Studio 2022 wraz z programowaniem desktopowym z C++. Pakiet SDK systemu Windows zawiera nagłówki ODBC oraz
- Baza danych w Azure SQL Database lub SQL Server, która zawiera przykładowe
AdventureWorksLTdane. W przypadku Azure SQL Database wybierz przykładowe źródło danych podczastworzenia pojedynczej bazy danych. Dla SQL Server przywróć kopię zapasowąAdventureWorksLTz przykładowych baz danych AdventureWorks.
Zweryfikowaj sterownika
Potwierdź, że menedżer sterowników znajduje sterownik Microsoft ODBC Driver 18 dla SQL Server.
Wykonaj to polecenie w PowerShell:
Get-OdbcDriver -Name "ODBC Driver 18 for SQL Server"
Każde polecenie powinno zawierać ODBC Driver 18 for SQL Server. Jeśli sterownik nie jest wymieniony, zainstaluj go ponownie przed kontynuacją.
Konfiguruj połączenie
Aplikacja odczytuje cały parametry połączenia ze zmiennej środowiskowejODBC_CONNECTION_STRING. Nie wyświetla parametry połączenia ani nie akceptuje go jako argumentu wiersza poleceń.
Użyj parametrów połączenia sterownika Driver 18, które są prawidłowe dla twojej bazy danych i metody uwierzytelniania. Poniższy przykład uwierzytelniania SQL działa na Windows, Linux i macOS, gdy baza danych umożliwia uwierzytelnianie SQL:
Driver={ODBC Driver 18 for SQL Server};Server=tcp:<server>,1433;Database=<database>;UID=<user_id>;PWD=<password>;Encrypt=yes;TrustServerCertificate=no;
Aby poznać opcje uwierzytelniania w usłudze Microsoft Entra, zobacz Używanie identyfikatora Microsoft Entra ID ze sterownikiem ODBC. Aby poznać wszystkie obsługiwane ustawienia, zobacz DSN i słowa kluczowe oraz atrybuty parametrów połączenia.
Sterownik Microsoft ODBC 18 domyślnie umożliwia szyfrowanie. Określ Encrypt=yes tak, aby wymagania aplikacji były jednoznaczne. Trzymaj TrustServerCertificate=no w produkcji, aby sterownik weryfikował certyfikat serwera. Certyfikat musi dopasować nazwę serwera i łańcuch do organu certyfikacyjnego, któremu klient ufa. Aby uzyskać wskazówki dotyczące konfiguracji, zobacz Błędy walidacji certyfikatu.
Caution
TrustServerCertificate=yes Pomija walidację certyfikatów. Używaj tego tylko w izolowanym lokalnym środowisku programistycznym podczas konfigurowania certyfikatu, któremu klient ufa. Nie używaj go w środowisku produkcyjnym.
Ustaw zmienną środowiskową bez dodawania parametrów połączenia do historii powłoki.
Open Developer PowerShell for VS 2022. Wykonaj te polecenia, a następnie wklej parametry połączenia w monicie:
$secureConnectionString = Read-Host "ODBC connection string" -AsSecureString
$env:ODBC_CONNECTION_STRING = [System.Net.NetworkCredential]::new(
"", $secureConnectionString).Password
$secureConnectionString = $null
Zmienna środowiskowa utrzymuje parametry połączenia poza plikiem źródłowym, ale proces i jego procesy potomne mogą go odczytać. W aplikacjach produkcyjnych stosuj uwierzytelnianie Microsoft Entra, gdzie to możliwe, i pobieraj sekrety z bezpiecznego magazynu w czasie działania.
Tworzenie aplikacji
Stwórz katalog projektów i zmień go na niego:
Utwórz plik o nazwie
odbc-quickstart.cppzawierający następujący kod:#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; }
Aplikacja korzysta wyłącznie ze standardowego API ODBC, więc zawiera nagłówki menedżera sterowników oraz linki do biblioteki menedżera sterowników. Parametry połączenia określają użycie sterownika Microsoft ODBC Driver 18 for SQL Server w czasie wykonywania.
SQL_DRIVER_NOPROMPT uniemożliwia SQLDriverConnect otwarcie dialogu konfiguracyjnego. Jeśli parametry połączenia są niepełne, wywołanie zwraca błąd, a aplikacja wyświetla każdy rekord diagnostyczny.
Zapytanie wiąże 0 jako parametr SQL Server typu int, odczytuje pierwszych pięć produktów w SalesLT.Product i pobiera identyfikator oraz nazwę każdego produktu za pomocą SQLGetData.
Kompilowanie i uruchamianie aplikacji
W tym samym oknie PowerShell dla deweloperów kompiluj aplikację:
cl /std:c++17 /EHsc /W4 odbc-quickstart.cpp /link odbc32.libUruchom aplikację:
.\odbc-quickstart.exe
Standardowe wyjście aplikacji to:
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
Wyczyść parametry połączenia po zakończeniu gry.