Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
ODBC est une interface de programmation d’application native d’accès aux données (API) pour applications écrites en C et C++. Le pilote Microsoft ODBC pour SQL Server se connecte à SQL Server, Azure SQL Database, Azure SQL Managed Instance, Azure Synapse Analytics et la base de données SQL dans Microsoft Fabric. Pour les versions de base de données prises en charge par chaque version de pilote, voir compatibilité avec SQL.
Votre application appelle le gestionnaire de pilotes ODBC, qui charge le pilote et lui transmet les appels ODBC. Utilisez le Windows ODBC Driver Manager sur Windows et unixODBC sur Linux et macOS.
Les autres langages qui peuvent utiliser ODBC incluent COBOL, Perl, PHP et Python. ODBC est largement utilisé dans les scénarios d’intégration de données, et les pilotes Microsoft pour PHP pour SQL Server sont construits sur ce pilote.
La variante ODBC de sqlcmd et l’utilitaire bcp utilisent ce pilote, mais ils s’installent séparément : le package mssql-tools18 sous Linux et macOS, et les utilitaires de ligne de commande Microsoft sur Windows. La variante Go de sqlcmd n’utilise pas ce pilote. Utilisez sqlcmd pour exécuter des instructions Transact-SQL (T-SQL), des procédures système et des fichiers script. Utilisez BCP pour copier en masse des données entre une instance de SQL Server et un fichier de données, dans les deux sens.
Choisir votre point de départ
- Pour installer le pilote, allez dans Exigences système, installations et fichiers de pilotes pour Windows, ou installez le pilote ODBC sur Linux, installez le pilote ODBC sur macOS, et installez le gestionnaire de pilotes unixODBC.
- Pour écrire votre première application, accédez à Se connecter et interroger une base de données avec C++. Pour les options de nom de source de données (DSN) et de chaîne de connexion, utilisez Mots clés et attributs de chaîne de connexion et de nom de source de données (DSN). Si votre compilateur ne trouve pas les en-têtes ou si votre build ne veut pas lier, allez dans Développer des applications C et C++ avec le pilote ODBC.
- Pour se connecter à Azure SQL avec une authentification sans mot de passe, allez dans Utiliser Microsoft Entra ID avec le pilote ODBC.
- Pour rendre une application existante résiliente aux pannes transitoires, allez dans Résilience de connexion , Haute disponibilité et reprise après sinistre.
- Pour passer à la version 17, allez dans Différences majeures de version et Dépannage du chiffrement de connexion.
- Pour diagnostiquer un problème de connexion ou de requête, allez dans Dépannage du chiffrement de connexion et Problèmes connus (Linux et macOS).
Base de référence de production pour Azure SQL
Utilisez ce programme complet en C++17 comme point de départ pour une application hébergée sur Azure. Il se connecte, exécute l’opération SELECT 1, vérifie le résultat et libère les handles ODBC. Installez le pilote 18 et les fichiers de développement ODBC de la plateforme avant de le compiler. Pour les prérequis, voir Développer des applications C et C++ avec le pilote ODBC.
Définissez ODBC_CONNECTION_STRING dans l’environnement de l’application à votre chaîne de connexion complète. L’exemple suivant utilise une identité managée attribuée par le système. L’hôte doit avoir cette identité activée, et la base de données doit lui accorder l’accès. Pour la configuration requise de l’hôte, les identités attribuées par l’utilisateur et l’authentification du développement local, voir Utiliser Microsoft Entra ID avec le pilote ODBC.
Driver={ODBC Driver 18 for SQL Server};Server=tcp:<server>.database.windows.net,1433;Database=<database>;Authentication=ActiveDirectoryMsi;Encrypt=strict;ConnectRetryCount=3;ConnectRetryInterval=2;
Encrypt=strict nécessite un point de terminaison qui prend en charge le flux de données tabulaire (TDS) 8.0. Sinon, utilisez Encrypt=yes;TrustServerCertificate=no. Configurez un certificat auquel le client fait confiance et dont le nom correspond à celui du serveur. Pour la configuration et la vérification, voir Dépannage du chiffrement de connexion.
Gardez les identifiants hors des fichiers sources et de l’historique du shell. Pour les commandes visant à définir la variable d’environnement, voir Configurer la connexion. Sur Linux et macOS, fournissez sa valeur en UTF-8. Enregistrez le programme suivant sous odbc-baseline.cpp:
#ifdef _WIN32
#include <windows.h>
#else
#include <iconv.h>
#endif
#include <sql.h>
#include <sqlext.h>
#include <chrono>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <random>
#include <stdexcept>
#include <string>
#include <thread>
#include <vector>
struct Handles {
SQLHENV env = SQL_NULL_HENV;
SQLHDBC dbc = SQL_NULL_HDBC;
SQLHSTMT stmt = SQL_NULL_HSTMT;
bool connected = false;
~Handles() {
if (stmt) SQLFreeHandle(SQL_HANDLE_STMT, stmt);
if (connected) SQLDisconnect(dbc);
if (dbc) SQLFreeHandle(SQL_HANDLE_DBC, dbc);
if (env) SQLFreeHandle(SQL_HANDLE_ENV, env);
}
};
bool logDiagnostics(SQLSMALLINT type, SQLHANDLE handle) {
bool retry = false;
bool permanent = false;
for (SQLSMALLINT record = 1; ; ++record) {
SQLWCHAR state[6] = {};
SQLWCHAR message[1024] = {};
SQLINTEGER native = 0;
SQLRETURN rc = SQLGetDiagRecW(type, handle, record, state, &native,
message, 1024, nullptr);
if (rc == SQL_NO_DATA) break;
if (!SQL_SUCCEEDED(rc)) {
std::cerr << "event=diagnostics_failed rc=" << rc << '\n';
return false;
}
std::string sqlstate;
for (int i = 0; i < 5; ++i) {
sqlstate += static_cast<char>(state[i]);
}
std::cerr << "event=odbc_diagnostic sqlstate=" << sqlstate
<< " native_error=" << native << '\n';
permanent |= sqlstate.substr(0, 2) == "28" ||
sqlstate.substr(0, 2) == "IM" ||
sqlstate == "HY024" || sqlstate == "HY092";
retry |= sqlstate == "08S01" || sqlstate == "HYT00" ||
sqlstate == "HYT01";
switch (native) {
case 10928: case 10929: case 10936:
case 40197: case 40501: case 40613:
case 49918: case 49919: case 49920:
retry = true;
}
}
return retry && !permanent;
}
void requireSuccess(SQLRETURN rc, SQLSMALLINT type, SQLHANDLE handle,
const char* operation) {
if (rc == SQL_SUCCESS) return;
logDiagnostics(type, handle);
if (!SQL_SUCCEEDED(rc)) throw std::runtime_error(operation);
}
std::vector<SQLWCHAR> readConnectionString() {
static_assert(sizeof(SQLWCHAR) == 2, "Use a driver manager with 16-bit SQLWCHAR");
#ifdef _WIN32
size_t length = 0;
if (_wgetenv_s(&length, nullptr, 0, L"ODBC_CONNECTION_STRING") != 0 ||
length == 0) {
throw std::runtime_error("ODBC_CONNECTION_STRING is required");
}
std::vector<wchar_t> raw(length);
if (_wgetenv_s(&length, raw.data(), raw.size(), L"ODBC_CONNECTION_STRING") != 0) {
throw std::runtime_error("Cannot read ODBC_CONNECTION_STRING");
}
std::vector<SQLWCHAR> result(raw.begin(), raw.end() - 1);
#else
const char* raw = std::getenv("ODBC_CONNECTION_STRING");
if (!raw) throw std::runtime_error("ODBC_CONNECTION_STRING is required");
iconv_t converter = iconv_open("UTF-16LE", "UTF-8");
if (converter == reinterpret_cast<iconv_t>(-1)) {
throw std::runtime_error("Cannot create UTF-8 converter");
}
size_t inputBytes = std::strlen(raw);
std::vector<SQLWCHAR> result(inputBytes + 1);
char* input = const_cast<char*>(raw);
char* output = reinterpret_cast<char*>(result.data());
size_t outputBytes = result.size() * sizeof(SQLWCHAR);
const size_t capacity = outputBytes;
size_t status = iconv(converter, &input, &inputBytes, &output, &outputBytes);
int closeStatus = iconv_close(converter);
if (status == static_cast<size_t>(-1) || inputBytes != 0 || closeStatus != 0) {
throw std::runtime_error("ODBC_CONNECTION_STRING must be valid UTF-8");
}
result.resize((capacity - outputBytes) / sizeof(SQLWCHAR));
#endif
if (result.empty() || result.size() >= 32767) {
throw std::runtime_error("Invalid ODBC_CONNECTION_STRING length");
}
result.push_back(0);
return result;
}
void connectWithRetry(SQLHDBC dbc, std::vector<SQLWCHAR>& connectionString) {
constexpr int maxAttempts = 4;
std::mt19937 random{std::random_device{}()};
std::uniform_int_distribution<int> jitter{0, 250};
for (int attempt = 1; attempt <= maxAttempts; ++attempt) {
requireSuccess(SQLSetConnectAttr(
dbc, SQL_ATTR_LOGIN_TIMEOUT,
reinterpret_cast<SQLPOINTER>(std::uintptr_t{30}), 0),
SQL_HANDLE_DBC, dbc, "Set login timeout");
SQLRETURN rc = SQLDriverConnectW(
dbc, nullptr, connectionString.data(), SQL_NTS,
nullptr, 0, nullptr, SQL_DRIVER_NOPROMPT);
if (SQL_SUCCEEDED(rc)) {
if (rc == SQL_SUCCESS_WITH_INFO) logDiagnostics(SQL_HANDLE_DBC, dbc);
std::cout << "event=connected attempt=" << attempt << '\n';
return;
}
bool transient = logDiagnostics(SQL_HANDLE_DBC, dbc);
if (!transient || attempt == maxAttempts) {
throw std::runtime_error("Connect failed");
}
auto delay = std::chrono::milliseconds{
(1 << (attempt - 1)) * 10000 + jitter(random)};
std::cerr << "event=connect_retry attempt=" << attempt
<< " delay_ms=" << delay.count() << '\n';
std::this_thread::sleep_for(delay);
}
}
int main() {
try {
auto connectionString = readConnectionString();
Handles handles;
if (!SQL_SUCCEEDED(SQLAllocHandle(
SQL_HANDLE_ENV, SQL_NULL_HANDLE, &handles.env))) {
throw std::runtime_error("Allocate environment");
}
requireSuccess(SQLSetEnvAttr(
handles.env, SQL_ATTR_ODBC_VERSION,
reinterpret_cast<SQLPOINTER>(std::uintptr_t{SQL_OV_ODBC3}), 0),
SQL_HANDLE_ENV, handles.env, "Set ODBC version");
requireSuccess(SQLAllocHandle(SQL_HANDLE_DBC, handles.env, &handles.dbc),
SQL_HANDLE_ENV, handles.env, "Allocate connection");
connectWithRetry(handles.dbc, connectionString);
handles.connected = true;
requireSuccess(SQLAllocHandle(SQL_HANDLE_STMT, handles.dbc, &handles.stmt),
SQL_HANDLE_DBC, handles.dbc, "Allocate statement");
requireSuccess(SQLSetStmtAttr(
handles.stmt, SQL_ATTR_QUERY_TIMEOUT,
reinterpret_cast<SQLPOINTER>(std::uintptr_t{10}), 0),
SQL_HANDLE_STMT, handles.stmt, "Set query timeout");
SQLWCHAR query[] = {'S', 'E', 'L', 'E', 'C', 'T', ' ', '1', 0};
requireSuccess(SQLExecDirectW(handles.stmt, query, SQL_NTS),
SQL_HANDLE_STMT, handles.stmt, "Execute probe");
requireSuccess(SQLFetch(handles.stmt),
SQL_HANDLE_STMT, handles.stmt, "Fetch probe");
SQLINTEGER value = 0;
SQLLEN indicator = 0;
requireSuccess(SQLGetData(handles.stmt, 1, SQL_C_SLONG,
&value, sizeof(value), &indicator),
SQL_HANDLE_STMT, handles.stmt, "Read probe");
if (indicator == SQL_NULL_DATA || value != 1) {
throw std::runtime_error("Unexpected probe result");
}
std::cout << "event=ready result=" << value << '\n';
return 0;
} catch (const std::exception& error) {
std::cerr << "event=failed operation=\"" << error.what() << "\"\n";
return 1;
}
}
Le programme demande un délai d’attente de connexion de 30 secondes pour chacune des tentatives de connexion, dans la limite de quatre, et un délai d’attente de requête de 10 secondes. Entre les tentatives temporaires de connexion ayant échoué, il attend 10, 20 et 40 secondes, chacune avec 0 à 250 millisecondes d’instabilité aléatoire. Ces limites n’imposent pas de date limite stricte à l’authentification. L’exemple classe les erreurs de connexion temporaires sélectionnées ; adaptez la stratégie à votre charge de travail avec le catalogue des erreurs temporaires Azure SQL. Il ne réessaie pas les commandes de l’application et n’effectue pas les opérations d’écriture.
ConnectRetryCount et ConnectRetryInterval configurent la résilience des connexions pour les connexions éligibles qui se déconnectent lorsqu’elles sont inactives. Ils ne réessaient pas la connexion initiale ni ne rejouent les commandes d’application. Limitez les délais de récupération au repos à une durée inférieure au délai d’expiration de votre requête. L’exemple enregistre les valeurs SQLSTATE et les numéros d’erreur natifs au lieu de chaînes de connexion ou de messages de diagnostic complets. Si vous avez besoin du texte du message pour dépanner, enregistrez-le dans un journal de diagnostic protégé.
Créer et exécuter la base de référence
Utilisez un environnement de compilateur qui correspond à l’architecture processeur de votre application. Sous Windows, exécutez les commandes dans Developer PowerShell pour Visual Studio. Sous Linux et macOS, utilisez un shell avec votre compilateur et les fichiers de développement unixODBC disponibles.
cl /nologo /std:c++17 /EHsc /W4 odbc-baseline.cpp odbc32.lib
.\odbc-baseline.exe
Une première connexion réussie affiche la sortie suivante. D’autres dossiers diagnostiques peuvent également apparaître.
event=connected attempt=1
event=ready result=1
Effacez ODBC_CONNECTION_STRING quand vous avez fini : utilisez Remove-Item Env:\ODBC_CONNECTION_STRING dans PowerShell, ou unset ODBC_CONNECTION_STRING dans Bash ou Zsh.
Pour les écouteurs de groupes de disponibilité et les paramètres de bascule, utilisez Haute disponibilité et reprise après sinistre.
Principales fonctionnalités
- Multiplateforme : La même API sur Windows, Linux et macOS.
- Authentification Microsoft Entra ID : Identité managée, principal de service et authentification intégrée, plus authentification interactive sous Windows. Les méthodes disponibles dépendent de l’hôte et de la configuration de la base de données.
- Chiffrement strict : connexions TDS 8.0 avec validation complète des certificats dans la version 18 et les versions ultérieures.
- Always Encrypted : Chiffrement côté client pour les colonnes sensibles, avec prise en charge des fournisseurs de magasins de clés personnalisés.
- Résilience de la connexion : Restauration transparente d’une connexion qui a été coupée alors qu’elle était inactive.
-
Haute disponibilité : prise en charge de l'écouteur de groupe de disponibilité avec
MultiSubnetFailover. - Classification des données : Métadonnées de sensibilité pour les colonnes classifiées.
- Type de données vectorielles : support natif du type de vecteur .
- Transactions distribuées : prise en charge des transactions XA via le Microsoft Distributed Transaction Coordinator (MSDTC).
- Outils compagnons : sqlcmd et bcp, installés séparément.
Get started
| Article | Description |
|---|---|
| Télécharger un pilote ODBC pour SQL Server | Installateurs et téléchargements de paquets pour toutes les versions de pilotes prises en charge, sur les trois plateformes. |
| Développer des applications en C et C++ avec le pilote ODBC | Quels en-têtes inclure, dans quel ordre, quelles bibliothèques lier, et comment choisir entre l’exécution asynchrone et les threads. |
| Connectez-vous et interrogez une base de données en C++ | Un échantillon complet en C++ qui connecte, lance une requête et lit les résultats, afin que vous puissiez confirmer votre installation de bout en bout. |
| Cycle de vie de support | Quelles versions de pilotes sont encore prises en charge, et à quelle date chacune cesse de l’être. |
| Différences entre les versions principales | Qu’est-ce qui casse quand on passe de la version 17 à la version 18, en commençant par le changement par défaut du chiffrement ? |
Installer le pilote
| Article | Description |
|---|---|
| Exigences système, installations et fichiers de pilotes (Windows) | Versions Windows prises en charge, la ligne de commande d’installateur pour le déploiement silencieux, et où chaque fichier pilote atterrit sur le disque. |
| Exigences système (Linux et macOS) | Les distributions Linux et les versions de macOS prises en charge par chaque version du pilote, ainsi que la compatibilité avec les versions de SQL Server. |
| Installer le pilote ODBC sur Linux | Étapes du gestionnaire de paquets pour Alpine, Debian, Red Hat, SUSE, Ubuntu et Azure Linux, ainsi que l’installation hors ligne et les emplacements des fichiers des pilotes. |
| Installer le pilote ODBC sur macOS | Étapes relatives au tap Homebrew et à la formule pour macOS, y compris la procédure d’installation des versions 18, 17 ou 13.1. |
| Installer le gestionnaire de pilotes unixODBC (Linux et macOS) | Installez ou mettez à jour unixODBC, le gestionnaire de pilotes qui charge le pilote ODBC sur Linux et macOS. |
Configuration et connexion
| Article | Description |
|---|---|
| DSN et mots-clés et attributs de chaîne de connexion | Le catalogue complet des mots-clés de chaîne de connexion, des entrées DSN et des attributs SQLSetConnectAttr, avec les valeurs acceptées pour chacun d’eux. |
| Mots-clés de chaînes de connexion et noms de sources de données (Linux et macOS) | Comment odbc.ini et odbcinst.ini définissent un DSN sous Linux et macOS, ainsi que les paramètres de maintien de connexion de TLS et de TCP spécifiques à ces plateformes. |
| Administrateur de la source de données ODBC DSN (Windows) | Configurez une source de données via l’interface utilisateur de Windows au lieu d’une chaîne de connexion. |
| Regroupement de connexions prenant en charge les pilotes (Windows) | Quels mots-clés et attributs de la chaîne de connexion placent une connexion dans son propre pool, et lesquels nécessitent un aller-retour supplémentaire pour la réinitialiser. |
Authentifier et être sécurisé
| Article | Description |
|---|---|
| Utilisez Microsoft Entra ID avec le pilote ODBC | Chaque valeur de mot-clé Authentication, de l’identité gérée et du principal de service à l’interactif et intégré, avec la configuration dont chacun a besoin. |
| Utilisez Always Encrypted avec le pilote ODBC | Chiffrez les valeurs sensibles des colonnes avant de les envoyer à la base de données ; consultez le résumé de l’API du pilote et les limitations documentées. |
| Classification des données | Lisez les étiquettes de sensibilité que le serveur attache aux colonnes classifiées, afin que votre application puisse appliquer sa propre politique de protection des données. |
| Utilisez l’authentification intégrée (Linux et macOS) | Configurez Kerberos pour qu’un client Linux ou macOS puisse se connecter avec des identifiants Windows au lieu d’une connexion SQL Server. |
Haute disponibilité et résilience
| Article | Description |
|---|---|
| Résilience des connexions | Comment ConnectRetryCount et ConnectRetryInterval rétablissent une connexion lorsque le serveur l’interrompt alors qu’elle est inactive, et les erreurs IMCxx que le pilote renvoie quand la récupération est impossible. |
| Haute disponibilité et récupération d’urgence | Connectez-vous à l’aide d’un écouteur de groupe de disponibilité et utilisez MultiSubnetFailover pour éviter que le basculement ne soit retardé en cas de délai d’expiration du sous-réseau. |
| Utiliser une résolution IP réseau transparente | Comment le mécanisme de repli hérité TransparentNetworkIPResolution ordonne les tentatives de connexion à travers plusieurs adresses IP (protocole Internet), et pourquoi MultiSubnetFailover le supplante-t-il. |
Utiliser des données
| Article | Description |
|---|---|
| Type de données vectorielles | Associez, envoyez et récupérez le type vector, y compris sa représentation native en C et la prise en charge de la copie en bloc. |
| Utiliser les transactions XA avec DTC | Engagez SQL Server dans une transaction distribuée via le Microsoft Distributed Transaction Coordinator sur Windows, Linux ou macOS. |
| Directives de programmation (Linux et macOS) | Trouvez des conseils de programmation Linux et macOS, incluant l’état des fonctionnalités, les considérations sur les jeux de caractères, OpenSSL et Alpine Linux. |
Diagnostiquer et résoudre les problèmes
| Article | Description |
|---|---|
| Dépannage du chiffrement des connexions | Corrigez les erreurs de certificat et de chiffrement que la version 18 met en avant car elle chiffre par défaut. |
| Traçage des accès aux données (Linux et macOS) | Activez la recherche des conducteurs et capturez un fichier journal lorsque vous avez besoin de voir les appels que votre application effectue réellement. |
| Problèmes connus (Linux et macOS) | Défauts confirmés et leurs solutions de contournement. Vérifiez ici avant de déposer une demande de soutien. |
| Foire aux questions (Linux et macOS) | Des réponses courtes aux questions qui reviennent le plus souvent sur le pilote sous Linux et macOS. |
Notes de publication et corrections de bugs
| Article | Description |
|---|---|
| Notes de version pour Windows | Nouvelles fonctionnalités, changements de comportement et correctifs à chaque version du pilote Windows. |
| Notes de version pour Linux et macOS | Nouvelles fonctionnalités, changements de comportement et corrections dans chaque version des pilotes Linux et macOS. |
| Notes de version pour les outils SQL Server | Modifications apportées aux utilitaires sqlcmd et bcp , qui s’installent séparément du pilote sur Linux et macOS. |
Reference
| Article | Description |
|---|---|
| Pilote ODBC sous Windows | Un résumé version par version de ce que le pilote supporte sous Windows, ainsi qu’un index des articles spécifiques à Windows. |
| Fonctionnalités du pilote ODBC sur Windows | Quelle version a introduit chaque fonctionnalité Windows, ainsi que les changements de comportement qui l’accompagnaient. |
Demander une fonctionnalité
Pour demander une fonctionnalité, soumettez une idée via les retours de SQL Server.
Contenu connexe
- Référence du programmeur ODBC : La spécification API ODBC que ce pilote implémente, documentée séparément du pilote.
- Fonctionnalités natives du client SQL Server : contexte historique de l’API. Consultez la documentation actuelle des pilotes pour le support de la plateforme, l’authentification et le comportement de chiffrement. Les directives Native Client et OLE DB n’établissent pas le support actuel des pilotes ODBC.
- Utilitaire BCP : L’utilitaire de copie en masse, installé séparément du pilote.
- Utilitaire sqlcmd : L’utilitaire de requête en ligne de commande, installé séparément du pilote.
- Matrice de support des fonctionnalités des pilotes
- Blog sur les pilotes SQL Server