C és C++ alkalmazások fejlesztése az ODBC illezserrel

Verzió: 18.7.1.1
Dátum: 2026. szeptember 7.

Az ODBC API C- vagy C++-kódból történő meghívásához foglalja bele a(z) sql.h, sqlext.h és sqltypes.h elemeket, majd hivatkozzon a driver manager importkönyvtárára. Az ODBC-szabványon felüli, a Microsoft ODBC Driver for SQL Server által biztosított SQL Server-kiterjesztések használatához foglalja bele a(z) msodbcsql.h elemet is, mégpedig az alap ODBC-fejlécek után.

Érvényes: Microsoft ODBC Driver 18 for SQL Server Windows-on, Linuxon és macOS-en. A 17-es verzió ugyanazt a fejlécnevet használja, telepítési 170 útvonalat és msodbcsql17 könyvtár nevet tartalmaz.

Fejlécek és könyvtárak

A platform az alapvető ODBC-fejlécfájlokat és az illesztőprogram-kezelőt biztosítja, nem az illesztőprogram-csomagot. Windows-on a Windows SDK-val érkeznek. Linuxon és macOS-en az unixODBC fejlesztőcsomagban érkeznek. Az illesztőprogram SDK csak a msodbcsql.h és a tömegesmásolás-importálási függvénytárat biztosítja.

Mit hívsz Fejlécek Windows Linux macOS
ODBC API \, \, \ odbc32.lib -lodbc -lodbc
ODBC API, Unicode belépési pontok Adj hozzá sqlucode.h odbc32.lib -lodbc -lodbc
ODBC-telepítő API Adj hozzá odbcinst.h odbccp32.lib -lodbcinst -lodbcinst
SQL Server driver-bővítmények Adj hozzá msodbcsql.h Nincs extra könyvtár Nincs extra könyvtár Nincs extra könyvtár
Tömeges másolat (bcp_*) függvények Adj hozzá msodbcsql.h msodbcsql18.lib -lmsodbcsql-18 -lmsodbcsql.18

A tömeges másolási link név platformonként eltér, mert a fájlnevek eltérnek. Linuxon a -lmsodbcsql-18 a /usr/lib könyvtárban lévő libmsodbcsql-18.so szimbolikus linken keresztül oldódik fel, amelyben a linker már eleve keres, így nincs szükség a(z) -L elemre. A macOS-en az illesztőprogram libmsodbcsql.18.dylib formában érkezik, amelynek -lmsodbcsql.18 megfelel, de a Homebrew könyvtára Apple siliconos gépeken nem része az alapértelmezett keresési útvonalnak. Add hozzá -L$(brew --prefix)/lib , amikor összekötöd a tömeges másolási funkciókat.

Csak a tömeges másolási függvényekhez van szükség az illesztőprogram saját függvénytárára. A kapcsolati attribútumok, az utasításattribútumok, az oszlopattribútumok és az SQL Server-típusazonosítók makrók és típusdefiníciók, ezért a(z) msodbcsql.h belefoglalása elegendő ezekhez.

A telepítő API egy különálló könyvtár az ODBC API-tól. Egy függvény, például a SQLGetPrivateProfileString, -lodbcinst nélküli hívása Linuxon vagy macOS-en nem fordításkor, hanem linkeléskor eredményez „undefined reference” hibát.

A Linuxon és macOS-en szükséges alapvető fejlécfájlokat biztosító unixODBC fejlesztőcsomag telepítéséhez lásd: A unixODBC illesztőprogram-kezelő telepítése.

A C-kódban Linuxon és macOS-en a wchar.h fájlt az msodbcsql.h előtt foglalja bele.

A msodbcsql.h Linux- és macOS-verziói a Always Encrypted kulcstároló-szolgáltatói felületet a wchar_t használatával deklarálják, de nem tartalmaznak olyan fejlécfájlt, amely definiálja ezt a típust. A C++-ban a wchar_t kulcsszó, így a C++ fordítási egységei további fejlécfájlok nélkül is lefordulnak. A C-ben wchar_t egy típusdefitás, ezért először be kell illesztened <wchar.h> a C fordítási egységbe:

#include <wchar.h>

Ha nem adod meg a(z) <wchar.h> elemet, a fordító msodbcsql.h hibákat jelez a(z) unknown type name 'wchar_t' belsejéből. A "Insert" hozzáadása ártalmatlan Windows-on, ezért add hozzá a közös forráshoz, ne pedig egy platform guard mögé helyeznéd.

Az msodbcsql.h fájlt az alapvető ODBC-fejlécek után foglalja bele

Minden, ami msodbcsql.h a meghajtó név makrókon túl definiál, egy #ifdef ODBCVER blokkban belül van, és sql.h ez határozza ODBCVERmeg . Ha elsőként beilleszted a msodbcsql.h elemet, az előfeldolgozó kihagyja az egész blokkot, és a fejléc semmivel sem járul hozzá. A fordító nem ad figyelmeztetést.

/* Correct order. */
#ifdef _WIN32
#include <windows.h>
#endif

#include <wchar.h>
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
#include <msodbcsql.h>

A(z) sql.h felvétele a(z) msodbcsql.h elé a(z) ODBCVER blokkon belül mindent definiálatlanul hagy. A fordító a hibát a használat helyén jelzi, nem az include utasításnál:

order-wrong.c(7): error C2065: 'SQL_COPT_SS_BCP': undeclared identifier

Windows rendszeren az ODBC fejlécfájlok előtt be kell illeszteni a windows.h elemet. A sqltypes.h és DWORD Windows SDK-beli változatai olyan Windows-típusokat használnak, mint a sql.h és a LONG. msodbcsql.h az SQL Server-struktúráit poppack.h és pshpack8.h elemekbe burkolja. Ha windows.hnincs , a build az SDK fejléceken belül hibázik.

Hol vannak telepítve az SDK fájlok

Platform msodbcsql.h Tömeges másolati könyvtár
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, egy /usr/lib/libmsodbcsql-18.so szimbolikus linkkel
macOS $(brew --prefix msodbcsql18)/include/msodbcsql18 $(brew --prefix)/lib/libmsodbcsql.18.dylib

Windows-on a Lib mappa minden processzorarchitektúra almappáját tartalmazza, amelyet a telepítő a gépen helyezett el, például x64, x86, vagy arm64. Add hozzá a Include mappát a fordító include útvonalához, az architektúra almappát pedig a linker könyvtár útjához.

Linuxon a megosztott objektum verziózott, neve például libmsodbcsql-18.6.so.2.1, és nem tartalmaz SONAME-t. A csomag úgy telepíti a(z) /usr/lib/libmsodbcsql-18.so elemet, hogy az arra mutat, ezért oldódik fel a(z) -lmsodbcsql-18 a(z) -L opció nélkül. Linkelj ezen a symlinken keresztül, ahelyett, hogy a verzióban lévő fájlt neveznéd meg, így a driver frissítés nem töri meg a buildedet.

macOS-en a Homebrew a saját prefixébe települ, amely Apple siliconon a /usr/local, Intelen pedig a /opt/homebrew. Mindkét előtag szimbilinkként szolgál a verziózott Cellar könyvtárba. A buildszkriptedben a brew --prefix msodbcsql18 és a brew --prefix unixodbc elemet használd valamelyik fix beírása helyett.

Az elérési útban szereplő szám az illesztőprogram főverzióját jelöli. A 17-es verzió Windows rendszeren a /opt/microsoft/msodbcsql17/, Linuxon pedig a ...\ODBC\170\SDK\ helyre települ, importkönyvtára pedig a msodbcsql17.lib.

A teljes fájlkészletért platformonként lásd: Rendszerkövetelmények, telepítés és driver fájlok (Windows), Telepítsd az ODBC illesztőprogramot Linuxon, és Telepítsd az ODBC drivert macOS-en.

Ellenőrizd a build beállításodat

Ez a program a fejlécfájlokkal fordul, az illesztőprogram-kezelőhöz linkel, és felsorolja azokat az illesztőprogramokat, amelyeket az illesztőprogram-kezelő lát. Nem csatlakozik, így elválasztja a build vagy regisztrációs problémát a hálózati vagy betekintő adatok problémájától.

#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;
}

Építsd szűk karakterprogramként. SQLODBC_DRIVER_NAME széles karakterlánccá bővül, ha a(z) UNICODE vagy a(z) _UNICODE van definiálva, amit a(z) printf a(z) %s mellett nem tud fogadni.

cl /W4 /I "%ProgramFiles%\Microsoft SQL Server\Client SDK\ODBC\180\SDK\Include" odbc-build-check.c /link odbc32.lib

Windows rendszeren a /W4 két C4201: nonstandard extension used: nameless struct/union figyelmeztetést jelez a sqlext.h Windows SDK-beli példányából. Ezek a figyelmeztetések az SDK fejlécéből származnak, nem a kódodból, és a build sikeres.

Az első sor a driver-nevet mutatja a bináris formátumban összeállítva. A többi az illesztőprogram-kezelő saját listája, ezért ha egy várt illesztőprogram nem jelenik meg, az regisztrációs hiba, nem buildhiba. A te listád eltérő lesz, és minden telepített ODBC drivert tartalmaz, nem csak az SQL Server-eket:

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)

A kapcsolati karakterláncot a(z) SQLODBC_DRIVER_NAME alapján hozd létre, ne sztringliterálból. A makró nyomon követi azt a fejlécet, amellyel szemben fordítottak, így az SDK frissítése egyetlen helyen frissíti az illesztőprogram nevét.

Mit ad hozzá a msodbcsql.h az ODBC API-hoz

msodbcsql.hkiterjeszti a szabványos ODBC API-t SQL Server specifikációival. Minden család egy összefüggő számtartományt foglal el, amelyet egy alapállandóból számolnak. A tartományok nem egyediek a családok között, ezért az a függvény különbözteti meg őket, amelynek átadod az értéket.

Család Alapállandó Value
A(z) SQLSetConnectAttr kapcsolati attribútumai SQL_COPT_SS_BASE 1200
Az SQLSetStmtAttr utasítás attribútumai SQL_SOPT_SS_BASE 1225
A(z) SQLColAttribute oszlop jellemzői SQL_CA_SS_BASE 1200
Információtípusok a SQLGetInfo SQL_INFO_SS_FIRST 1199
Diagnosztikai mezők a SQLGetDiagField SQL_DIAG_SS_BASE -1150
Diagnosztikai dinamikus függvénykódok SQL_DIAG_DFC_SS_BASE -200

A fejléc azt is kijelenti:

  • Hitelesítési attribútumok, beleértve SQL_COPT_SS_AUTHENTICATION és SQL_COPT_SS_ACCESS_TOKEN, amelyek Microsoft Entra ID beállításokat és hozzáférési tokeneket hordoznak.
  • SQL típusazonosítók a -150-től -199-ig terjedő tartományban olyan SQL Server típusok esetén, amelyeket az ODBC nem definiál: SQL_SS_VARIANT, SQL_SS_UDT, SQL_SS_XML, SQL_SS_TIMESTAMPOFFSETSQL_SS_TABLESQL_SS_TIME2, és SQL_SS_VECTOR. Ezek SQL típust neveznek meg, így odaadjuk őket, ahol az ODBC SQL típust vár, például az ParameterType argumentumban .SQLBindParameter
  • Három egyező C típus a pufferoldalra: SQL_C_SS_TIME2, SQL_C_SS_TIMESTAMPOFFSET, és SQL_C_SS_VECTOR. A többi SQL Server típus egy szabványos ODBC C típushoz köt, mint SQL_C_BINARY például vagy SQL_C_WCHAR, így nincs SQL_C_SS_* ellenfelük.
  • A SQL_C_SS_* típusok által kötött struktúrák: SQL_SS_TIME2_STRUCT, SQL_SS_TIMESTAMPOFFSET_STRUCT, és SQL_SS_VECTOR_STRUCT.
  • Prototípusok és makrók tömeges másolása, beleértve a következőket: bcp_init, bcp_bind, bcp_sendrow, bcp_batch és bcp_done. Az BCP_ENCRYPT_OFF, BCP_ENCRYPT_ON, és BCP_ENCRYPT_STRICT opciók csak a Windows fejlécében találhatók.

Minden platform a msodbcsql.h saját példányát szállítja, és nem mindegyik deklarálja ugyanazokat a szimbólumokat. A(z) SQLPERF struktúra és az azt kitöltő teljesítménykapcsolat-attribútumok, például a(z) SQL_COPT_SS_PERF_DATA és SQL_COPT_SS_PERF_QUERY, csak a Windows-fejlécben találhatók. A Linux és macOS fejlécei nem hirdetik meg ezeket, és a meghajtó nem gyűjt teljesítményadatokat ezeken a platformokon. Lásd a programozási irányelveket (Linux és macOS).

A kapcsolati karakterlánc kulcsszavakhoz, amelyekhez ezek az attribútumok tartoznak, lásd a DSN és a kapcsolati karakterlánc kulcsszavakat és attribútumokat. A Microsoft Entra ID beállításához lásd: A Microsoft Entra ID használata az ODBC-illesztőprogrammal. A vektortípusról lásd: Vektoradattípus.

Válasszon aszinkron végrehajtás és szálak között

Néhány ODBC függvény akár szinkron, akár aszinkron módon működhet. Szinkron módban az illesztőprogram addig nem adja vissza a vezérlést, amíg a szerver nem válaszol. Aszinkron módban az illesztőprogram azonnal visszatér SQL_STILL_EXECUTING , és az alkalmazás ugyanazt a hívást ismétli ugyanazokkal az argumentumokkal, amíg nem kap egy másik visszatérési kódot. Bármely más visszaküldési kód, beleértve SQL_ERROR, azt jelenti, hogy a művelet befejeződött.

Az aszinkron módnak két formája van, és egyiket használsz. Hívd meg a SQLGetInfo elemet a(z) SQL_ASYNC_MODE használatával, hogy megtudd, melyiket támogatja az illesztőprogram. Akkor tér vissza SQL_AM_STATEMENT , ha az illesztőprogram támogatja az utasítás szerinti vezérlést, SQL_AM_CONNECTION ha a beállítás az egész kapcsolatra vonatkozik, vagy SQL_AM_NONE ha az illesztőr egyáltalán nem fut aszinkron funkciókkal.

Az utasítási forma egy utasításkezelő esetében bekapcsolja az aszinkron módot. Az adott kapcsolaton minden más utasítás szinkron marad, így mindkét típust egyszerre futtathatod:

SQLSetStmtAttr(hStmt, SQL_ATTR_ASYNC_ENABLE,
               (SQLPOINTER)SQL_ASYNC_ENABLE_ON, SQL_IS_INTEGER);

Ha a(z) SQL_ASYNC_MODE értéke SQL_AM_CONNECTION, az utasításattribútum csak olvasható, és ez a hívás HYC00 értékkel tér vissza, SQLSTATE SQL_ERROR mellett. Használd inkább a kapcsolati űrlapot.

A kapcsolati űrlap minden egyes állítás handle-re bekapcsol aszinkron módot, amelyet később adott kapcsolaton kijelölsz. Hogy ez a már létező fogantyúkat is érinti-e, az driver-definiálva van meghatározva, ezért állítsd be, mielőtt bármilyen állítást kiosztasz:

SQLSetConnectAttr(hDbc, SQL_ATTR_ASYNC_ENABLE,
                  (SQLPOINTER)SQL_ASYNC_ENABLE_ON, SQL_IS_INTEGER);

A hívás SQL_ERROR visszatér SQLSTATE-hez HY010 , ha egy függvény még mindig aszinkron módon fut egy adott állításon adott kapcsolatra. Egy nyitott kurzor önmagában nem blokkolja a hívást. A(z) SQL_ASYNC_ENABLE_OFF átadása az adott kapcsolaton minden utasítást visszaállít szinkron módra.

Annak megállapításához, hogy az illesztőprogram egyszerre hány aszinkron utasítást támogat egyetlen kapcsolaton, hívja meg a(z) SQLGetInfo elemet a(z) SQL_MAX_ASYNC_CONCURRENT_STATEMENTS paraméterrel. A Microsoft ODBC Driver 18 for SQL Server 1-et ad vissza, ezért tervezz egy kiemelkedő aszinkron műveletet minden kapcsolatonként, és nyiss több kapcsolatot, vagy használj ezen túl szálakat. Lásd Aszinkron végrehajtás (lekérdezéses módszer).

A szálak egy másik módját jelentik annak, hogy több műveletet is folyamatban tartsunk. Az ODBC megköveteli, hogy a többszálú operációs rendszerek illesztőprogramjai szálbiztonságúak legyenek, így egy szál blokkoló ODBC hívást indíthat, miközben a többi szál tovább működik. Ez elkerüli a polling loopot és az ismétlődő függvényhívásokat, amire az aszinkron mód szüksége van. Adj minden szálnak saját kiadletuskezelő címet. Egy meghajtó valószínűleg két szálat sorilemez, amelyek egyszerre ugyanazt a handle-t használják, így az egyik megosztása költséget okoz a párhuzamosságnak. Lásd Multithreading. Új kód esetén részesítsd előnyben a szálak használatát, és mérd fel a saját terhelésedet, mielőtt átalakítanád a már működő aszinkron kódot.

Windows-on a driver manager támogatja az értesítési módszert is, amely eltávolítja a szavazási kört. Egy Win32-eseményt a kapcsolat- vagy utasításleíróhoz társít. A függvény továbbra is azonnal visszatér SQL_STILL_EXECUTING , és a driver manager jelzi az eseményt, amikor a művelet befejeződik. A polling ebben a módban le van tiltva: az eredeti függvény újbóli meghívása IM017 értéket ad vissza, SQL_ERROR SQLSTATE kóddal. Az eredmény lekéréséhez inkább a(z) SQLCompleteAsync elemet hívd meg. Ehhez az ODBC 3.81-es verzió és újabb verziók szükségesek, és a drivernek is támogatnia kell. A(z) SQLGetInfo meghívásával, SQL_ASYNC_NOTIFICATION használatával ellenőrizheted. A kapott érték attól függ, hogy az alkalmazás az ODBC melyik verzióját deklarálja: a Microsoft ODBC Driver 18 for SQL Server esetén az az alkalmazás, amely a SQL_ATTR_ODBC_VERSION értékét SQL_OV_ODBC3_80 értékre állítja, a SQL_ASYNC_NOTIFICATION_CAPABLE értéket kapja vissza, míg az, amely a SQL_OV_ODBC3 értéket deklarálja, ugyanattól az illesztőprogramtól a SQL_ASYNC_NOTIFICATION_NOT_CAPABLE értéket kapja vissza. Jelentsd SQL_OV_ODBC3_80 be, mielőtt a kapcsolatot kiosztod. Lásd aszinkron végrehajtást (értesítési módszer) és az értesítési módszer mintát.

Egy függőben lévő művelet megszakítása

SQLCancel Megszakít egy még futó műveletet egy utasításazonosítón. Hívd meg egy másik szálból vagy a lekérdezési ciklusból, a függőben lévő hívás azonosítóját átadva.

Csak erre használd SQLCancel . Ha el szeretné hagyni azt az eredményhalmazt, amelyet már nem kíván tovább olvasni, inkább a SQLCloseCursor vagy a SQLMoreResults elemet hívja meg.

Áttérés az sqlncli.h fájlról az msodbcsql.h fájlra

Az SQL Server Native Client már visszavonult, így azoknak az alkalmazásoknak, amelyek használják, át kell váltaniuk a Microsoft ODBC Driver for SQL Server-re. Az API ugyanaz az ODBC API, így a munka nagy része a buildbemenetek és az illesztőprogram nevének átnevezéséből áll a kapcsolati karakterláncban.

Natív SQL Server-ügyfél Microsoft ODBC Driver 18 for 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

A msodbcsql.h fejléc továbbra is meghatározza a SQLNCLI_* makrók nevét, így azokat használó forráskód folyamatosan fordítódik. Ezeket a definíciókat védi #ifndef __sqlncli_h__, ami azt jelenti, hogy nem lehet mindkét fejlécet ugyanabban a fordítási egységben bevonni. Távolítsd el a sqlncli.h include elemet.

Két dolog nem vihető át:

  • A megosztott lekérdezési metaadat API funkciók, amelyek visszaadják a kapcsolt szerverek listáit és katalógusait, nem vannak kihirdetve .msodbcsql.h Ezek kifejezetten az SQL Server Native Client-re voltak jellemzőek.
  • A 18-as verzió alapértelmezés szerint titkosítja a kapcsolatokat, és érvényesíti a szervertanúsítványt. A Native Client nem így volt. A Native Clienttel működő kapcsolati sztring az első csatlakozási kísérletnél sikertelen lehet, amíg nem állítja be megfelelően a tanúsítvány megbízhatóságát, vagy a Encrypt paramétert kifejezetten be nem állítja. Lásd: Kapcsolat titkosítás hibaelhárítása.

A 17-től 18-ig terjedő verziók további változásaiért lásd: Főbb verzióbeli különbségek.