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.
Version: 18.7.1.1
Datum: 7. September 2026
Um die ODBC-API aus C oder C++ aufzurufen, binden Sie sql.h, sqlext.h und sqltypes.h ein und verknüpfen Sie dann mit der Importbibliothek des Treibermanagers. Um die SQL Server-Erweiterungen zu verwenden, die der Microsoft ODBC-Treiber für SQL Server über den ODBC-Standard hinaus hinzufügt, binden Sie auch msodbcsql.h ein, und zwar nach den ODBC-Kernheadern.
Gilt für: Microsoft ODBC Driver 18 für SQL Server unter Windows, Linux und macOS. Version 17 verwendet denselben Header-Namen mit einem 170 Installationspfad und einem msodbcsql17 Bibliotheksnamen.
Header und Bibliotheken
Die Plattform stellt die Kern-ODBC-Header und den Treibermanager bereit, nicht das Treiberpaket. Unter Windows werden sie im Windows SDK ausgeliefert. Unter Linux und macOS sind sie im unixODBC-Entwicklungspaket enthalten. Das Treiber-SDK stellt nur msodbcsql.h und die Bulk-Copy-Importbibliothek bereit.
| Was du nennst | Headers | Windows | Linux | macOS |
|---|---|---|---|---|
| ODBC-API |
sql.h, sqlext.h, sqltypes.h |
odbc32.lib |
-lodbc |
-lodbc |
| ODBC API, Unicode-Einstiegspunkte | Fügen Sie sqlucode.h hinzu. |
odbc32.lib |
-lodbc |
-lodbc |
| API des ODBC-Installationsprogramms | Fügen Sie odbcinst.h hinzu. |
odbccp32.lib |
-lodbcinst |
-lodbcinst |
| SQL Server-Treibererweiterungen | Fügen Sie msodbcsql.h hinzu. |
Keine zusätzliche Bibliothek | Keine zusätzliche Bibliothek | Keine zusätzliche Bibliothek |
Massenkopie-Funktionen (bcp_*) |
Fügen Sie msodbcsql.h hinzu. |
msodbcsql18.lib |
-lmsodbcsql-18 |
-lmsodbcsql.18 |
Der Name des Bulk-Copy-Links variiert je nach Plattform, da die Dateinamen unterschiedlich sind. Unter Linux wird -lmsodbcsql-18 über einen libmsodbcsql-18.so symbolischen Link in /usr/lib aufgelöst, das der Linker bereits durchsucht, sodass du -L nicht benötigst. Auf macOS wird der Treiber als libmsodbcsql.18.dylib ausgeliefert, was zu -lmsodbcsql.18 passt, aber das Bibliotheksverzeichnis von Homebrew befindet sich auf Apple Silicon nicht im Standardsuchpfad. Füge -L$(brew --prefix)/lib hinzu, wenn du die Massenkopierfunktionen verlinkst.
Nur die Massenkopierfunktionen benötigen die eigene Bibliothek des Treibers. Verbindungsattribute, Anweisungsattribute, Spaltenattribute und SQL Server-Typkennungen sind Makros und Typdefinitionen, daher reicht das Einbeziehen msodbcsql.h für sie aus.
Die Installer-API ist eine separate Bibliothek von der ODBC-API. Ein Aufruf einer Funktion wie SQLGetPrivateProfileString ohne -lodbcinst auf Linux oder macOS schlägt zur Linkzeit mit einer undefinierten Referenz fehl, nicht zur Kompilierungszeit.
Um das unixODBC-Entwicklungspaket zu installieren, das die Kernheader unter Linux und macOS bereitstellt, siehe Install the unixODBC driver manager.
Wchar.h vor msodbcsql.h in C-Code unter Linux und macOS einfügen
Die Linux- und macOS-Versionen von msodbcsql.h deklarieren die Always Encrypted-Keystoreanbieterschnittstelle unter Verwendung von wchar_t, enthalten jedoch keine Headerdatei, die diesen Typ definiert. In C++ wchar_t ist ein Schlüsselwort, sodass C++-Übersetzungseinheiten ohne zusätzliche Header gebaut werden. In C ist wchar_t ein typedef, daher musst du <wchar.h> zuerst in eine C-Übersetzungseinheit einbinden:
#include <wchar.h>
Wenn du <wchar.h> nicht angibst, meldet der Compiler unknown type name 'wchar_t'-Fehler aus msodbcsql.h. Das Einbinden ist unter Windows unproblematisch, daher sollte es dem gemeinsam genutzten Quellcode hinzugefügt werden, anstatt es hinter eine Plattformabfrage zu stellen.
Fügen Sie msodbcsql.h nach den Kern-ODBC-Headern hinzu
Alles, was msodbcsql.h über die Treibernamen-Makros hinaus definiert, befindet sich innerhalb eines #ifdef ODBCVER-Blocks, und es ist sql.h, das ODBCVER definiert. Wenn du zuerst einfügst msodbcsql.h , überspringt der Präprozessor diesen ganzen Block und der Header trägt nichts bei. Der Compiler gibt keine Warnung aus.
/* Correct order. */
#ifdef _WIN32
#include <windows.h>
#endif
#include <wchar.h>
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
#include <msodbcsql.h>
Das Einfügen von sql.h vor ODBCVER lässt alles innerhalb des msodbcsql.h-Blocks undefiniert. Der Compiler meldet den Fehler am Anwendungspunkt, nicht am Include:
order-wrong.c(7): error C2065: 'SQL_COPT_SS_BCP': undeclared identifier
Unter Windows musst du vor den ODBC-Headern einbauenwindows.h. Die Windows-SDK-Versionen von sqltypes.h und sql.h verwenden Windows-Typen wie DWORD und LONG.
msodbcsql.humschließt seine SQL Server-Strukturen in pshpack8.h und poppack.h. Ohne windows.hschlägt der Build innerhalb der SDK-Header selbst fehl.
Wo die SDK-Dateien installiert sind
| Platform | msodbcsql.h |
Bibliothek für Massenkopien |
|---|---|---|
| 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, mit einem Symlink /usr/lib/libmsodbcsql-18.so |
| macOS | $(brew --prefix msodbcsql18)/include/msodbcsql18 |
$(brew --prefix)/lib/libmsodbcsql.18.dylib |
Unter Windows enthält der Lib Ordner einen Unterordner für jede Prozessorarchitektur, die der Installer auf der Maschine platziert hat, wie x64, x86, oder arm64. Fügen Sie den Include Ordner zum Include-Pfad des Compilers hinzu und den Architektur-Unterordner zum Bibliothekspfad des Linkers.
Unter Linux ist das geteilte Objekt versioniert, benannt wie , libmsodbcsql-18.6.so.2.1und trägt keine SONAME. Das Paket installiert /usr/lib/libmsodbcsql-18.so, das darauf verweist, wodurch -L auch ohne die Option -lmsodbcsql-18 aufgelöst wird. Linke über diesen Symlink, anstatt die versionierte Datei zu benennen, damit ein Treiber-Update deinen Build nicht kaputt macht.
Unter macOS installiert Homebrew sich in seinem eigenen Präfix, und zwar unter /usr/local auf Apple Silicon und unter /opt/homebrew auf Intel. Beide Präfixe sind Symlinks in das versionierte Cellar-Verzeichnis. Nutze brew --prefix msodbcsql18 und brew --prefix unixodbc in deinem Build-Skript, anstatt eines von beiden fest zu programmieren.
Die Nummer im Pfad gibt die Hauptversion des Treibers an. Version 17 wird unter Windows in ...\ODBC\170\SDK\ und unter Linux in /opt/microsoft/msodbcsql17/ installiert, und die Importbibliothek ist msodbcsql17.lib.
Für das vollständige Dateiinventar pro Plattform siehe Systemanforderungen, Installation und Treiberdateien (Windows),Installiere den ODBC-Treiber unter Linux und Installiere den ODBC-Treiber auf macOS.
Überprüfe deine Build-Konfiguration
Dieses Programm kompiliert zu den Headern, verlinkt mit dem Treibermanager und listet die Treiber auf, die der Fahrermanager sehen kann. Es verbindet sich nicht, sodass ein Build- oder Registrierungsproblem von einem Netzwerk- oder Zugangsdatenproblem getrennt wird.
#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;
}
Erstellen Sie es als Programm mit schmalen Zeichen.
SQLODBC_DRIVER_NAME dehnt sich auf eine breite Zeichenkette aus, wenn UNICODE oder _UNICODE definiert ist, was printf mit %s nicht nehmen kann.
cl /W4 /I "%ProgramFiles%\Microsoft SQL Server\Client SDK\ODBC\180\SDK\Include" odbc-build-check.c /link odbc32.lib
Unter Windows gibt /W4 zwei C4201: nonstandard extension used: nameless struct/union Warnungen von der Windows-SDK-Kopie von sqlext.h aus. Diese Warnungen kommen vom SDK-Header, nicht von deinem Code, und der Build funktioniert.
Die erste Zeile meldet den Fahrernamen, der in deine Binärdatei kompiliert wurde. Der Rest ist die eigene Liste der Treiberverwaltung, daher ist ein Treiber, den Sie erwarten, aber nicht sehen, ein Registrierungsproblem und kein Build-Problem. Deine Liste wird unterschiedlich sein, und sie enthält jeden installierten ODBC-Treiber, nicht nur die SQL Server-Treiber:
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)
Erstellen Sie die Verbindungszeichenfolge aus SQLODBC_DRIVER_NAME und nicht aus einem String-Literal. Das Makro verfolgt den Header, gegen den du kompiliert hast, daher aktualisiert das Upgrade des SDK den Treibernamen an einer Stelle.
Was msodbcsql.h zur ODBC-API hinzufügt
msodbcsql.herweitert die Standard-ODBC-API um SQL Server-Spezifikationen. Jede Familie nimmt einen zusammenhängenden Zahlenbereich ein, der aus einer Grundkonstante gezählt wird. Die Bereiche sind nicht familienübergreifend eindeutig, daher ist die Funktion, der du den Wert übergibst, diejenige, die sie voneinander unterscheidet.
| Familie | Basiskonstante | Value |
|---|---|---|
Verbindungsattribute für SQLSetConnectAttr |
SQL_COPT_SS_BASE |
1200 |
Statement-Attribute für SQLSetStmtAttr |
SQL_SOPT_SS_BASE |
1225 |
Spaltenattribute für SQLColAttribute |
SQL_CA_SS_BASE |
1200 |
Informationstypen für SQLGetInfo |
SQL_INFO_SS_FIRST |
1199 |
Diagnostische Felder für SQLGetDiagField |
SQL_DIAG_SS_BASE |
-1150 |
| Dynamische Diagnose-Funktionscodes | SQL_DIAG_DFC_SS_BASE |
-200 |
Die Überschrift erklärt außerdem:
- Authentifizierungsattribute, einschließlich
SQL_COPT_SS_AUTHENTICATIONundSQL_COPT_SS_ACCESS_TOKEN, die Microsoft Entra ID-Einstellungen und Zugriffstoken enthalten. - SQL-Typbezeichner im Bereich von -150 bis -199 für SQL-Server-Typen, die ODBC nicht definiert:
SQL_SS_VARIANT,SQL_SS_UDT,SQL_SS_XML,SQL_SS_TIMESTAMPOFFSET,SQL_SS_TABLE,SQL_SS_TIME2undSQL_SS_VECTOR. Diese benennen einen SQL-Typ , sodass man sie dort passiert, wo ODBC einen SQL-Typ erwartet, wie zum Beispiel dasParameterTypeArgument vonSQLBindParameter. - Drei passende C-Typen für die Pufferseite:
SQL_C_SS_TIME2,SQL_C_SS_TIMESTAMPOFFSET, undSQL_C_SS_VECTOR. Die anderen SQL Server-Typen binden an einen Standard-ODBC-C-Typ wieSQL_C_BINARYoderSQL_C_WCHAR, sodass sie keinSQL_C_SS_*Gegenstück haben. - Die Strukturen, an die die Typen
SQL_C_SS_*binden:SQL_SS_TIME2_STRUCT,SQL_SS_TIMESTAMPOFFSET_STRUCT, undSQL_SS_VECTOR_STRUCT. - Kopien von Prototypen und Makros in großen Mengen, darunter
bcp_init,bcp_bind,bcp_sendrow,bcp_batch, undbcp_done. DieBCP_ENCRYPT_OFFOptionen ,BCP_ENCRYPT_ON, undBCP_ENCRYPT_STRICTsind nur im Windows-Header zu finden.
Jede Plattform liefert ihre eigene Kopie von msodbcsql.h, und sie deklarieren nicht alle dieselben Symbole. Die Struktur SQLPERF und die Performance-Verbindungsattribute, die sie ausfüllen, wie SQL_COPT_SS_PERF_DATA und SQL_COPT_SS_PERF_QUERY, befinden sich nur im Windows-Header. Die Linux- und macOS-Header deklarieren sie nicht, und der Treiber sammelt keine Leistungsdaten auf diesen Plattformen. Siehe Programmierrichtlinien (Linux und macOS).
Für die Verbindungszeichenfolge-Schlüsselwörter, denen diese Attribute entsprechen, siehe DSN- und Verbindungszeichenfolge-Schlüsselwörter und -attribute. Informationen zur Einrichtung von Microsoft Entra ID finden Sie unter Microsoft Entra ID mit dem ODBC-Treiber verwenden. Für den Vektortyp siehe Vektordatentyp.
Wählen Sie zwischen asynchroner Ausführung und Threads
Einige ODBC-Funktionen können entweder synchron oder asynchron ausgeführt werden. Im synchronen Modus gibt der Treiber die Kontrolle erst zurück, wenn der Server antwortet. Im asynchronen Modus kehrt der Treiber sofort zurück SQL_STILL_EXECUTING , und die Anwendung wiederholt denselben Aufruf mit denselben Argumenten, bis sie einen anderen Rückgabecode erhält. Jeder andere Rückgabecode, einschließlich SQL_ERROR, bedeutet, dass die Operation abgeschlossen ist.
Der asynchrone Modus hat zwei Formen, und du benutzt eine davon. Rufen Sie SQLGetInfo mit SQL_ASYNC_MODE auf, um herauszufinden, welche Variante der Treiber unterstützt. Es gibt zurück, SQL_AM_STATEMENT wenn der Treiber die Steuerung pro Anweisung unterstützt, SQL_AM_CONNECTION ob die Einstellung auf die gesamte Verbindung gilt oder SQL_AM_NONE wenn der Treiber überhaupt keine Funktionen asynchron ausführt.
Die Anweisungsform schaltet den asynchronen Modus für ein Anweisungs-Handle ein. Alle anderen Anweisungen auf der Verbindung bleiben synchron, sodass du beide Arten gleichzeitig ausführen kannst:
SQLSetStmtAttr(hStmt, SQL_ATTR_ASYNC_ENABLE,
(SQLPOINTER)SQL_ASYNC_ENABLE_ON, SQL_IS_INTEGER);
Wenn SQL_ASYNC_MODESQL_AM_CONNECTION zurückgibt, ist das Anweisungsattribut schreibgeschützt, und dieser Aufruf gibt HYC00 mit SQLSTATE SQL_ERROR zurück. Verwenden Sie stattdessen das Verbindungsformular.
Das Verbindungsformular schaltet den asynchronen Modus für jedes Statement-Handle ein, das du danach für diese Verbindung zuweist. Ob es auch bereits existierende Handles betrifft, ist vom Treiber definiert, also setze es ein, bevor du Anweisungen zuweist:
SQLSetConnectAttr(hDbc, SQL_ATTR_ASYNC_ENABLE,
(SQLPOINTER)SQL_ASYNC_ENABLE_ON, SQL_IS_INTEGER);
Der Aufruf gibt HY010 mit SQLSTATE SQL_ERROR zurück, wenn eine Funktion für diese Verbindung noch asynchron auf einer Anweisung ausgeführt wird. Ein offener Cursor allein blockiert den Anruf nicht. Die Übergabe von SQL_ASYNC_ENABLE_OFF versetzt alle Statements der Verbindung wieder in den synchronen Modus.
Um herauszufinden, wie viele asynchrone Anweisungen der Treiber gleichzeitig auf einer Verbindung unterstützt, rufen Sie SQL_MAX_ASYNC_CONCURRENT_STATEMENTS mit SQLGetInfo auf. Microsoft ODBC Driver 18 für SQL Server gibt 1 zurück; planen Sie daher pro Verbindung einen ausstehenden asynchronen Vorgang ein und öffnen Sie zusätzliche Verbindungen oder verwenden Sie Threads, wenn Sie mehr benötigen. Siehe Asynchrone Ausführung (Polling-Methode).
Threads sind die andere Möglichkeit, mehrere Operationen am Laufen zu halten. ODBC verlangt, dass Treiber auf Multithreaded-Betriebssystemen threadsicher sind, sodass ein Thread einen blockierenden ODBC-Aufruf durchführen kann, während andere Threads weiterarbeiten. Das vermeidet die Abfrageschleife und die wiederholten Funktionsaufrufe, die der asynchrone Modus benötigt. Gib jedem Thread einen eigenen Statement-Handle. Ein Treiber serialisiert wahrscheinlich zwei Threads, die gleichzeitig denselben Handle verwenden, daher kostet das Teilen eines Threads die Nebenläufigkeit. Siehe Multithreading. Bevorzuge Threads für neuen Code und messe deine eigene Arbeitsbelastung, bevor du asynchronen Code konvertierst, der bereits funktioniert.
Unter Windows unterstützt der Treibermanager auch die Benachrichtigungsmethode, die die Abfrageschleife entfernt. Sie verknüpfen ein Win32-Ereignis mit dem Verbindungs- oder Statement-Handle. Die Funktion kehrt weiterhin sofort zurück SQL_STILL_EXECUTING , und der Treibermanager signalisiert das Ereignis, wenn die Operation abgeschlossen ist. Polling ist in diesem Modus deaktiviert: Ein erneuter Aufruf der ursprünglichen Funktion liefert IM017 mit SQLSTATE SQL_ERROR zurück. Ruf stattdessen auf, SQLCompleteAsync um das Ergebnis abzurufen. Dafür braucht man den Treibermanager der Version ODBC 3.81 und neuere Versionen, und der Treiber muss das ebenfalls unterstützen. Rufen Sie SQLGetInfo mit SQL_ASYNC_NOTIFICATION zur Überprüfung an. Der Wert, den Sie zurückerhalten, hängt von der ODBC-Version ab, die Ihre Anwendung deklariert: Mit Microsoft ODBC Driver 18 for SQL Server erhält eine Anwendung, die SQL_ATTR_ODBC_VERSION auf SQL_ASYNC_NOTIFICATION_CAPABLE setzt, SQL_OV_ODBC3, und eine Anwendung, die SQL_ASYNC_NOTIFICATION_NOT_CAPABLE deklariert, erhält SQL_OV_ODBC3_80 von demselben Treiber. Deklarieren Sie SQL_OV_ODBC3_80, bevor Sie die Verbindung zuweisen. Siehe Asynchrone Ausführung (Benachrichtigungsmethode) und das Beispiel der Benachrichtigungsmethode.
Eine ausstehende Operation abbrechen
SQLCancel hebt eine Operation ab, die noch auf einem Statement-Handle läuft. Rufen Sie sie von einem anderen Thread oder aus der Polling-Schleife auf und übergeben Sie dabei das Handle des ausstehenden Aufrufs.
Nur dafür verwenden SQLCancel . Um eine Ergebnismenge, die Sie nicht mehr auslesen möchten, zu verwerfen, rufen Sie stattdessen SQLCloseCursor oder SQLMoreResults auf.
Migration von sqlncli.h zu msodbcsql.h
Der SQL Server Native Client ist eingestellt, daher sollten Anwendungen, die ihn nutzen, auf den Microsoft ODBC-Treiber für SQL Server wechseln. Die API ist dieselbe ODBC-API, daher besteht der Großteil der Arbeit darin, Build-Eingaben und den Treibernamen in der Verbindungszeichenfolge umzubenennen.
| SQL Server Native Client | Microsoft ODBC-Treiber 18 für 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 |
Der Header msodbcsql.h definiert weiterhin die SQLNCLI_* Name-Makros, sodass der Quellcode, der sie verwendet, weiter kompiliert. Diese Definitionen werden durch #ifndef __sqlncli_h__geschützt, was bedeutet, dass man nicht beide Header in derselben Übersetzungseinheit einbauen kann. Entfernen Sie die sqlncli.h-Einbindung.
Zwei Dinge werden nicht übernommen:
- Die Funktionen der API für Metadaten verteilter Abfragen, die Listen mit verknüpften Servern und ihren Katalogen zurückgeben, sind in
msodbcsql.hnicht deklariert. Sie waren spezifisch für den SQL Server Native Client. - Version 18 verschlüsselt die Verbindungen standardmäßig und validiert das Serverzertifikat. Native Client tat das nicht. Eine Verbindungszeichenfolge, die mit Native Client funktioniert hat, kann bei der ersten Verbindung fehlschlagen, bis Sie das Zertifikatsvertrauen korrigieren oder
Encryptexplizit festlegen. Siehe Fehlerbehebung der Verbindungsverschlüsselung.
Für die übrigen Änderungen von Version 17 bis Version 18 siehe Wesentliche Versionsunterschiede.