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.
Aplica-se a:SQL Server
Banco de Dados SQL do Azure
Neste quickstart, constróis uma aplicação de consola C++ no Windows, Linux ou macOS. A aplicação liga-se a uma AdventureWorksLT base de dados usando o Microsoft ODBC Driver 18 para SQL Server, associa um parâmetro de consulta, executa a consulta e lê as linhas de resultados.
Prerequisites
- Microsoft ODBC Driver 18 para SQL Server. Instala o driver para Windows, Linux ou macOS.
- Um compilador C++17 e os ficheiros de desenvolvimento ODBC da plataforma:
- No sistema Windows, instale o Visual Studio 2022 ou as Ferramentas de Compilação para o Visual Studio 2022 com a carga de trabalho Desenvolvimento para ambiente de trabalho com C++. O SDK do Windows fornece os cabeçalhos ODBC e
odbc32.lib. - No Linux, instala um compilador C++ e o pacote de desenvolvimento unixODBC para a tua distribuição. O pacote fornece os cabeçalhos ODBC e
libodbc. - No macOS, instala as ferramentas de linha de comandos do Xcode e unixODBC a partir do Homebrew.
- No sistema Windows, instale o Visual Studio 2022 ou as Ferramentas de Compilação para o Visual Studio 2022 com a carga de trabalho Desenvolvimento para ambiente de trabalho com C++. O SDK do Windows fornece os cabeçalhos ODBC e
- Uma base de dados no Base de Dados SQL do Azure ou SQL Server que contém os
AdventureWorksLTdados de exemplo. Para Base de Dados SQL do Azure, selecione a fonte de dados de exemplo ao criar uma única base de dados. Para o SQL Server, restaura umaAdventureWorksLTcópia de segurança a partir de bases de dados de exemplo do AdventureWorks.
Verifique o condutor
Confirme que o gestor de drivers consegue encontrar o Microsoft ODBC Driver 18 para SQL Server.
Execute este comando no PowerShell:
Get-OdbcDriver -Name "ODBC Driver 18 for SQL Server"
Cada comando deve listar ODBC Driver 18 for SQL Server. Se o driver não estiver listado, reinstale-o antes de continuar.
Configurar a ligação
A aplicação lê a cadeia de ligação completa da ODBC_CONNECTION_STRING variável de ambiente. Não mostra a cadeia de ligação nem a aceita como argumento de linha de comandos.
Usa uma cadeia de ligação do Driver 18 que seja válida para a tua base de dados e método de autenticação. O seguinte exemplo de autenticação SQL funciona no Windows, Linux e macOS quando a base de dados permite autenticação SQL:
Driver={ODBC Driver 18 for SQL Server};Server=tcp:<server>,1433;Database=<database>;UID=<user_id>;PWD=<password>;Encrypt=yes;TrustServerCertificate=no;
Para opções de autenticação Microsoft Entra, veja Usar Microsoft Entra ID com o driver ODBC. Para todas as configurações suportadas, consulte DSN e palavras-chave e atributos da cadeia de ligação.
O Microsoft ODBC Driver 18 ativa a encriptação por defeito. Especifique Encrypt=yes para que o requisito da aplicação seja explícito. Mantém TrustServerCertificate=no em produção para que o driver valide o certificado do servidor. O certificado deve associar o nome e a cadeia do servidor a uma autoridade certificadora em que o cliente confie. Para orientações de configuração, veja Falhas de validação de certificados.
Atenção
TrustServerCertificate=yes ignora a validação do certificado. Use-o apenas para desenvolvimento local isolado enquanto configura um certificado em que o cliente confia. Não o uses na produção.
Define a variável ambiente sem adicionar a cadeia de ligação ao histórico do teu shell.
OpenDeveloper PowerShell para VS 2022. Execute estes comandos e depois cole a cadeia de ligação no prompt:
$secureConnectionString = Read-Host "ODBC connection string" -AsSecureString
$env:ODBC_CONNECTION_STRING = [System.Net.NetworkCredential]::new(
"", $secureConnectionString).Password
$secureConnectionString = $null
Uma variável de ambiente mantém a cadeia de ligação fora do ficheiro de origem, mas o processo e os seus processos filhos podem lê-la. Para aplicações de produção, utilize a autenticação do Microsoft Entra sempre que possível e obtenha os segredos a partir de um repositório seguro em tempo de execução.
Criar o aplicativo
Crie um diretório de projeto e altere para ele:
Crie um arquivo chamado
odbc-quickstart.cppcom o seguinte código:#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; }
A aplicação utiliza apenas a API ODBC standard, pelo que inclui os cabeçalhos do gestor de controladores e faz a ligação à biblioteca do gestor de controladores. A cadeia de ligação seleciona o Microsoft ODBC Driver 18 para SQL Server em tempo de execução.
SQL_DRIVER_NOPROMPT impede SQLDriverConnect a abertura de um diálogo de configuração. Se a cadeia de ligação estiver incompleta, a chamada devolve um erro e a aplicação imprime todos os registos de diagnóstico.
A consulta associa 0 como parâmetro int do SQL Server, lê os primeiros cinco produtos de SalesLT.Product e obtém o ID e o nome de cada produto com SQLGetData.
Compilar e executar o aplicativo
Na mesma janela do PowerShell do Desenvolvedor, compila a aplicação:
cl /std:c++17 /EHsc /W4 odbc-quickstart.cpp /link odbc32.libExecute a aplicação:
.\odbc-quickstart.exe
A saída padrão da aplicação é:
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
Apague a cadeia de ligação quando terminar.