Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
ODBC é uma interface nativa de programação de aplicações para acesso a dados (API) para aplicações escritas em C e C++. O Microsoft ODBC Driver for SQL Server estabelece ligação ao SQL Server, ao Base de Dados SQL do Azure, ao Azure SQL Managed Instance, ao Azure Synapse Analytics e à base de dados SQL do Microsoft Fabric. Para as versões da base de dados que cada versão de driver suporta, consulte compatibilidade de versões SQL.
A sua aplicação chama o gestor de drivers ODBC, que carrega o driver e passa as chamadas ODBC para ele. Use o Windows ODBC Driver Manager no Windows e o unixODBC no Linux e macOS.
Outras linguagens que podem usar ODBC incluem COBOL, Perl, PHP e Python. O ODBC é amplamente utilizado em cenários de integração de dados, e os drivers Microsoft para PHP para SQL Server são construídos sobre este driver.
A variante ODBC do sqlcmd e a utilidade bcp usam este driver, mas instalam-se separadamente: o mssql-tools18 pacote no Linux e macOS, e as Utilidades de Linha de Comando da Microsoft no Windows. A variante Go do sqlcmd não usa este driver. Utilize sqlcmd para executar instruções Transact-SQL (T-SQL), procedimentos do sistema e ficheiros de script. Use bcp para copiar dados em massa entre uma instância do SQL Server e um ficheiro de dados, em qualquer das direções.
Escolhe o teu ponto de partida
- Para instalar o driver, vá a Requisitos do sistema, instalação e ficheiros do driver para Windows, ou instale o driver ODBC no Linux, instale o driver ODBC no macOS e instale o gestor de drivers unixODBC.
- Para escrever a tua primeira aplicação, vai a Ligar a e consultar uma base de dados com C++. Para opções de nome de fonte de dados (DSN) e cadeia de ligação, use DSN e palavras-chave e atributos de cadeia de ligação. Se o seu compilador não conseguir encontrar os cabeçalhos ou se a sua compilação não conseguir fazer a ligação, vá a Desenvolver aplicações C e C++ com o controlador ODBC.
- Para se ligar ao SQL do Azure com autenticação sem palavra-passe, vá a Use Microsoft Entra ID com o driver ODBC.
- Para tornar uma aplicação existente resiliente a falhas transitórias, vá a Resiliência de Conexões e Alta Disponibilidade e Recuperação em Desastres.
- Para atualizar da versão 17, vá a Diferenças principais de versão e Resolução de problemas de encriptação de conexão.
- Para diagnosticar um problema de ligação ou de consulta, vá para Resolução de problemas de encriptação da ligação e Problemas conhecidos (Linux e macOS).
Linha de base de produção para o SQL do Azure
Use este programa completo em C++17 como ponto de partida para uma aplicação alojada no Azure. Estabelece a ligação, executa SELECT 1, verifica o resultado e liberta os handles ODBC. Instale o Driver 18 e os ficheiros de desenvolvimento ODBC da plataforma antes de o compilar. Para pré-requisitos, consulte Desenvolver aplicações C e C++ com o driver ODBC.
Defina ODBC_CONNECTION_STRING no ambiente da aplicação como a sua cadeia de ligação completa. O exemplo seguinte utiliza uma identidade gerida atribuída pelo sistema. O anfitrião deve ter essa identidade ativada, e a base de dados deve conceder-lhe acesso. Para requisitos de host, identidades atribuídas pelo utilizador e autenticação de desenvolvimento local, veja Use Microsoft Entra ID com o driver 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 requerem um endpoint que suporte o Tabular Data Stream (TDS) 8.0. Caso contrário, use Encrypt=yes;TrustServerCertificate=no. Configure um certificado em que o cliente confie e cujo nome corresponda ao do servidor. Para configuração e verificação, veja Resolução de problemas de encriptação de ligação.
Mantenha as credenciais fora dos ficheiros de origem e do histórico do shell. Para ver os comandos para definir a variável de ambiente, consulte Configurar a conexão. No Linux e macOS, indique o seu valor como UTF-8. Guardar o seguinte programa como 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;
}
}
O programa solicita um timeout de ligação de 30 segundos para cada uma de, no máximo, quatro tentativas de ligação e um timeout de consulta de 10 segundos. Entre tentativas falhadas de ligação transitória, espera 10, 20 e 40 segundos, cada uma com 0 a 250 milissegundos de jitter aleatório. Estes limites não impõem um prazo global rígido para a autenticação. O exemplo classifica erros selecionados de ligação transitória; adapta a política à sua carga de trabalho com o catálogo de erros de falha transitória do SQL do Azure. Não tenta novamente comandos de aplicação nem operações de escrita.
ConnectRetryCount e ConnectRetryInterval configuram a resiliência da ligação para ligações elegíveis que caem enquanto estão inativas. Eles não tentam novamente a conexão inicial nem reexecutam os comandos da aplicação. Mantenha os atrasos de recuperação em repouso mais curtos do que o tempo limite da sua consulta. A amostra regista valores SQLSTATE e números de erro nativos em vez de cadeias de ligação ou mensagens de diagnóstico completas. Se precisares de texto da mensagem para resolução de problemas, regista-o num registo de diagnóstico protegido.
Constrói e executa a baseline
Utilize um ambiente de compilador que corresponda à arquitetura do processador da sua aplicação. No Windows, execute os comandos no Developer PowerShell para Visual Studio. No Linux e macOS, usa um shell com o compilador e os ficheiros de desenvolvimento unixODBC disponíveis.
cl /nologo /std:c++17 /EHsc /W4 odbc-baseline.cpp odbc32.lib
.\odbc-baseline.exe
Uma primeira ligação bem-sucedida imprime a seguinte saída. Podem também surgir registos diagnósticos adicionais.
event=connected attempt=1
event=ready result=1
Limpa ODBC_CONNECTION_STRING quando terminares: usa Remove-Item Env:\ODBC_CONNECTION_STRING no PowerShell, ou unset ODBC_CONNECTION_STRING no Bash ou Zsh.
Para escutas de grupos de disponibilidade e definições de failover, use Alta disponibilidade e recuperação após desastre.
Principais características
- Multiplataforma: A mesma API no Windows, Linux e macOS.
- Autenticação Microsoft Entra ID: Identidade gerida, principal de serviço e autenticação integrada, além de autenticação interativa no Windows. Os métodos disponíveis dependem do host e da configuração da base de dados.
- Encriptação rigorosa: ligações TDS 8.0 com validação completa de certificados na versão 18 e versões posteriores.
- Always Encrypted: Encriptação do lado do cliente para colunas sensíveis, com suporte para provedores personalizados de arquivo de chaves.
- Resiliência da ligação: Restauração transparente de uma ligação que caiu enquanto estava inativa.
-
Alta disponibilidade: Disponibilidade de apoio de ouvintes em grupo com
MultiSubnetFailover. - Classificação de dados: Metadados de sensibilidade para colunas classificadas.
- Tipo de dado vetorial: Suporte nativo para o tipo vetorial .
- Transações distribuídas: Suporte a transações XA através do Coordenador de Transações Distribuídas da Microsoft (MSDTC).
- Ferramentas complementares: sqlcmd e bcp, instaladas separadamente.
Introdução
| Artigo | Description |
|---|---|
| Descarregar o Controlador ODBC para SQL Server | Instaladores e transferências de pacotes para todas as versões de controladores suportadas, para as três plataformas. |
| Desenvolver aplicações em C e C++ com o driver ODBC | Quais os cabeçalhos a incluir, por que ordem, que bibliotecas a ligar e como escolher entre execução assíncrona e threads. |
| Ligue-se e consulte uma base de dados com C++ | Um exemplo completo em C++ que liga, executa uma consulta e lê resultados, para que possas confirmar a tua configuração de ponta a ponta. |
| Ciclo de vida do suporte | Quais as versões dos drivers ainda suportadas e a data em que cada uma sai do suporte. |
| Principais diferenças de versão | O que falha quando se passa da versão 17 para a versão 18, começando pela alteração padrão da encriptação. |
Instale o controlador
| Artigo | Description |
|---|---|
| Requisitos do sistema, instalação e ficheiros de drivers (Windows) | Versões do Windows suportadas, a linha de comandos do instalador para instalação silenciosa e onde cada ficheiro do controlador é guardado no disco. |
| Requisitos do sistema (Linux e macOS) | Quais distribuições Linux e versões do macOS suportam cada versão do driver, além da compatibilidade com versões do SQL Server. |
| Instale o controlador ODBC no Linux | Etapas do gestor de pacotes para Alpine, Debian, Red Hat, SUSE, Ubuntu e Azure Linux, além da instalação offline e das localizações dos ficheiros dos drivers. |
| Instale o driver ODBC no macOS | Passos para o tap e as fórmulas do Homebrew no macOS, incluindo como instalar a versão 18, 17 ou 13.1. |
| Instale o gestor de drivers unixODBC (Linux e macOS) | Instale ou atualize o unixODBC, o gestor de drivers que carrega o driver ODBC no Linux e macOS. |
Configurar e ligar
| Artigo | Description |
|---|---|
| Palavras-chave e atributos de DSN e de cadeias de ligação | O catálogo completo de palavras-chave de cadeia de ligação, entradas DSN e atributos SQLSetConnectAttr, com os valores aceites para cada um. |
| Palavras-chave de string de ligação e nomes de fontes de dados (Linux e macOS) | Como definir uma DSN no Linux e macOS com odbc.ini e odbcinst.ini, além de definições de Segurança da Camada de Transporte (TLS) e Protocolo de Controlo de Transmissão (TCP) keep-alive específicas para essas plataformas. |
| Administrador de Fonte de Dados ODBC DSN (Windows) | Configure uma fonte de dados através da interface de utilizador do Windows em vez de uma cadeia de ligação. |
| Agrupamento de ligações com reconhecimento do controlador (Windows) | Que palavras‑chave e atributos da cadeia de ligação colocam uma ligação no seu próprio grupo, e quais implicam uma ida e volta adicional para a repor. |
Autenticar e proteger
| Artigo | Description |
|---|---|
| Utilizar o Microsoft Entra ID com o controlador ODBC | Cada Authentication valor de palavra-chave, desde identidade gerida e principal de serviço até interativo e integrado, com a configuração que cada um precisa. |
| Utilizar Always Encrypted com o controlador ODBC | Encripte valores de colunas sensíveis antes de os enviar para a base de dados, com o resumo da API do driver e as limitações documentadas. |
| Classificação dos dados | Leia as etiquetas de sensibilidade que o servidor atribui às colunas classificadas, para que a sua aplicação possa aplicar a sua própria política de proteção de dados. |
| Utilizar autenticação integrada (Linux e macOS) | Configure o Kerberos para que um cliente Linux ou macOS possa ligar-se com credenciais do Windows em vez de um login do SQL Server. |
Alta disponibilidade e resiliência
| Artigo | Description |
|---|---|
| Resiliência da ligação | Como ConnectRetryCount e ConnectRetryInterval restauram uma ligação quando o servidor a interrompe quando esta está inativa, e os erros IMCxx que o controlador devolve quando a recuperação não é possível. |
| Alta disponibilidade e recuperação de desastres | Liga-te através de um ouvinte de grupo de disponibilidade e usa MultiSubnetFailover para que o failover não fique bloqueado num timeout de subrede. |
| Utilizar resolução IP de rede transparente | Como o Fallback legado TransparentNetworkIPResolution ordena as tentativas de ligação através de múltiplos endereços de Protocolo de Internet (IP), e por que MultiSubnetFailover o substitui. |
Trabalhar com dados
| Artigo | Description |
|---|---|
| Tipo de dados vetoriais | Associar, enviar e recuperar o tipo vetor, incluindo a sua representação nativa em C e suporte para cópia em massa. |
| Usar transações XA com DTC | Inscreva o SQL Server numa transação distribuída através do Coordenador de Transações Distribuídas da Microsoft no Windows, Linux ou macOS. |
| Diretrizes de programação (Linux e macOS) | Encontre orientações de programação para Linux e macOS, incluindo o estado das funcionalidades, considerações sobre conjuntos de caracteres, OpenSSL e Alpine Linux. |
Diagnosticar e solucionar problemas
| Artigo | Description |
|---|---|
| Resolução de problemas de encriptação de ligação | Corrigir os erros de certificado e encriptação que a versão 18 revela porque ela encripta por defeito. |
| Rastreio de acesso a dados (Linux e macOS) | Ativa o rastreio de condutores e captura um ficheiro de registo quando precisares de ver as chamadas que a tua aplicação realmente faz. |
| Problemas conhecidos (Linux e macOS) | Defeitos confirmados e as suas soluções alternativas. Consulte aqui antes de submeter um pedido de suporte. |
| Perguntas frequentes (Linux e macOS) | Respostas curtas às perguntas que surgem mais frequentemente sobre o driver no Linux e macOS. |
Notas de lançamento e correções de bugs
| Artigo | Description |
|---|---|
| Notas de lançamento para Windows | Novas funcionalidades, alterações de comportamento e correções em cada versão do driver do Windows. |
| Notas de lançamento para Linux e macOS | Novas funcionalidades, alterações de comportamento e correções em cada lançamento de drivers para Linux e macOS. |
| Notas de atualização para as ferramentas do SQL Server | Alterações às utilidades sqlcmd e bcp , que se instalam separadamente do driver no Linux e macOS. |
Reference
| Artigo | Description |
|---|---|
| Controlador ODBC no Windows | Um resumo, versão por versão, do que é suportado pelo controlador no Windows e um índice dos artigos específicos do Windows. |
| Funcionalidades do driver ODBC no Windows | Qual das versões introduziu cada funcionalidade do Windows, além das alterações de comportamento associadas. |
Pedir uma funcionalidade
Para solicitar uma funcionalidade, submeta uma ideia através do feedback do SQL Server.
Conteúdo relacionado
- Referência do Programador ODBC: A especificação da API ODBC que este driver implementa, documentada separadamente do driver.
- Funcionalidades do SQL Server Native Client: Contexto histórico da API. Consulte a documentação atual dos drivers para suporte à plataforma, autenticação e comportamento de encriptação. A orientação para Native Client e OLE DB não estabelece o suporte atual a controladores ODBC.
- Utilidade BCP: A utilidade de cópia em massa, instalada separadamente do driver.
- Utilidade sqlcmd: A utilidade de consulta na linha de comandos, instalada separadamente do driver.
- Matriz de suporte a funcionalidades do driver
- Blog de drivers do SQL Server