Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Gilt für:SQL Server
Azure SQL-Datenbank
In diesem Quickstart baust du eine C++-Konsolenanwendung auf Windows, Linux oder macOS. Die Anwendung verbindet sich mit einer AdventureWorksLT Datenbank, indem sie den Microsoft ODBC Driver 18 für SQL Server verwendet, bindet einen Abfrageparameter, führt die Abfrage aus und liest die resultierenden Zeilen.
Voraussetzungen
- Microsoft ODBC Driver 18 für SQL Server. Installiere den Treiber für Windows, Linux oder macOS.
- Ein C++17-Compiler und die ODBC-Entwicklungsdateien der Plattform:
- Unter Windows installieren Sie Visual Studio 2022 oder die Build Tools für Visual Studio 2022 mit der Desktop-Entwicklung mit C++ Workload. Das Windows SDK liefert die ODBC-Header und
odbc32.lib. - Unter Linux installiere einen C++-Compiler und das unixODBC-Entwicklungspaket für deine Distribution. Das Paket liefert die ODBC-Header und
libodbc. - Installiere auf macOS die Xcode-Kommandozeilen-Tools und unixODBC aus Homebrew.
- Unter Windows installieren Sie Visual Studio 2022 oder die Build Tools für Visual Studio 2022 mit der Desktop-Entwicklung mit C++ Workload. Das Windows SDK liefert die ODBC-Header und
- Eine Datenbank in Azure SQL-Datenbank oder SQL Server, die die
AdventureWorksLTBeispieldaten enthält. Für die Azure SQL-Datenbank wählen Sie die Beispiel-Datenquelle aus, wenn Sie eine einzelne Datenbank erstellen. Für SQL Server sollten Sie einAdventureWorksLTBackup aus AdventureWorks-Beispieldatenbanken wiederherstellen.
Überprüfen Sie den Fahrer
Bestätigen Sie, dass der Treibermanager den Microsoft ODBC Driver 18 für SQL Server finden kann.
Führe diesen Befehl in PowerShell aus:
Get-OdbcDriver -Name "ODBC Driver 18 for SQL Server"
Jeder Befehl sollte ODBC Driver 18 for SQL Server angeben. Wenn der Treiber nicht aufgeführt ist, installiere ihn neu, bevor du weitermachst.
Konfigurieren Sie die Verbindung
Die Anwendung liest den vollständigen Verbindungszeichenfolge aus der ODBC_CONNECTION_STRING Umgebungsvariable. Sie zeigt den Verbindungszeichenfolge nicht an und akzeptiert ihn nicht als Kommandozeilenargument.
Verwenden Sie eine Driver-18-Verbindungszeichenfolge, die für Ihre Datenbank und Ihre Authentifizierungsmethode gültig ist. Das folgende Beispiel zur SQL-Authentifizierung funktioniert unter Windows, Linux und macOS, wenn die Datenbank SQL-Authentifizierung erlaubt:
Driver={ODBC Driver 18 for SQL Server};Server=tcp:<server>,1433;Database=<database>;UID=<user_id>;PWD=<password>;Encrypt=yes;TrustServerCertificate=no;
Für Microsoft Entra-Authentifizierungsoptionen siehe Verwenden Sie Microsoft Entra ID mit dem ODBC-Treiber. Für alle unterstützten Einstellungen siehe DSN- und Verbindungszeichenfolge-Schlüsselwörter und -attribute.
Microsoft ODBC Driver 18 aktiviert standardmäßig die Verschlüsselung. Geben Sie an, Encrypt=yes damit die Anforderungen der Anwendung explizit sind.
TrustServerCertificate=no im Produktivbetrieb beibehalten, damit der Treiber das Serverzertifikat überprüft. Das Zertifikat muss den Servernamen und die Kette mit einer Zertifizierungsstelle abstimmen, der der Client vertraut. Für Konfigurationshinweise siehe Zertifikatsvalidierungsfehler.
Caution
TrustServerCertificate=yes Überspringt die Zertifikatsvalidierung. Nutze es nur für isolierte lokale Entwicklung, während du ein Zertifikat konfigurierst, dem der Client vertraut. Verwenden Sie sie nicht in der Produktion.
Setze die Umgebungsvariable, ohne die Verbindungszeichenfolge zu deiner Shell-Historie hinzuzufügen.
Öffne Developer PowerShell für VS 2022. Führe diese Befehle aus und füge dann die Verbindungszeichenfolge am Prompt ein:
$secureConnectionString = Read-Host "ODBC connection string" -AsSecureString
$env:ODBC_CONNECTION_STRING = [System.Net.NetworkCredential]::new(
"", $secureConnectionString).Password
$secureConnectionString = $null
Eine Umgebungsvariable hält die Verbindungszeichenfolge aus der Quelldatei heraus, aber der Prozess und seine Kindprozesse können sie lesen. Für Produktionsanwendungen verwenden Sie, wo möglich, die Microsoft Entra-Authentifizierung, und rufen Sie Geheimnisse zur Laufzeit aus einem sicheren Speicher ab.
Erstellen der Anwendung
Erstellen Sie ein Projektverzeichnis und ändern Sie es:
Erstellen Sie eine Datei mit dem Namen
odbc-quickstart.cppund dem folgenden Code:#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; }
Die Anwendung verwendet nur die Standard-ODBC-API, daher enthält sie die Treiber-Manager-Header und Links zur Treiber-Manager-Bibliothek. Die Verbindungszeichenfolge wählt zur Laufzeit Microsoft ODBC Driver 18 für SQL Server aus.
SQL_DRIVER_NOPROMPT verhindert SQLDriverConnect , dass ein Konfigurationsdialog geöffnet wird. Ist der Verbindungszeichenfolge unvollständig, gibt der Anruf einen Fehler zurück und die Anwendung druckt jeden Diagnosedatensatz.
Die Abfrage bindet 0 als SQL Server int Parameter, liest die ersten fünf Produkte in SalesLT.Productund ruft jede Produkt-ID und jeden Namen mit SQLGetDataab.
Erstellen und Ausführen der Anwendung
Kompiliere im selben Entwickler-PowerShell-Fenster die Anwendung:
cl /std:c++17 /EHsc /W4 odbc-quickstart.cpp /link odbc32.libFühren Sie die Anwendung aus:
.\odbc-quickstart.exe
Die Standardausgabe der Anwendung lautet:
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
Lösche die Verbindungszeichenfolge, wenn du fertig bist.