Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Se aplica a:SQL Server
Azure SQL Database
En este inicio rápido, construyes una aplicación de consola C++ en Windows, Linux o macOS. La aplicación se conecta a una AdventureWorksLT base de datos utilizando el controlador ODBC 18 de Microsoft para SQL Server, vincula un parámetro de consulta, ejecuta la consulta y lee las filas de resultados.
Prerequisites
- Microsoft ODBC Driver 18 para SQL Server. Instala el controlador para Windows, Linux o macOS.
- Un compilador C++17 y los archivos de desarrollo ODBC de la plataforma:
- En Windows, instala Visual Studio 2022 o las Herramientas de Compilación para Visual Studio 2022 con la carga de trabajo de desarrollo de escritorio con C++. El SDK de Windows proporciona los encabezados ODBC y
odbc32.lib. - En Linux, instala un compilador en C++ y el paquete de desarrollo unixODBC para tu distribución. El paquete suministra los encabezados ODBC y
libodbc. - En macOS, instala las herramientas de línea de comandos de Xcode y unixODBC desde Homebrew.
- En Windows, instala Visual Studio 2022 o las Herramientas de Compilación para Visual Studio 2022 con la carga de trabajo de desarrollo de escritorio con C++. El SDK de Windows proporciona los encabezados ODBC y
- Una base de datos en Azure SQL Database o SQL Server que contiene los
AdventureWorksLTdatos de ejemplo. Para Azure SQL Database, selecciona la fuente de datos de ejemplo cuando crees una única base de datos. Para SQL Server, restaura unaAdventureWorksLTcopia de seguridad desde bases de datos de ejemplo de AdventureWorks.
Verifica el controlador
Confirma que el gestor de controladores puede encontrar el controlador ODBC 18 de Microsoft para SQL Server.
Ejecuta este comando en PowerShell:
Get-OdbcDriver -Name "ODBC Driver 18 for SQL Server"
Cada comando debería indicar ODBC Driver 18 for SQL Server. Si el controlador no aparece en la lista, reinstálalo antes de continuar.
Configurar la conexión
La aplicación lee la cadena de conexión completa de la variable de entorno ODBC_CONNECTION_STRING. No muestra la cadena de conexión ni la acepta como argumento de línea de comandos.
Usa una cadena de conexión del Driver 18 que sea válida para tu base de datos y método de autenticación. El siguiente ejemplo de autenticación SQL funciona en Windows, Linux y macOS cuando la base de datos permite la autenticación SQL:
Driver={ODBC Driver 18 for SQL Server};Server=tcp:<server>,1433;Database=<database>;UID=<user_id>;PWD=<password>;Encrypt=yes;TrustServerCertificate=no;
Para las opciones de autenticación de Microsoft Entra, consulte Usar Microsoft Entra ID con el controlador ODBC. Para todas las opciones de configuración admitidas, consulta DSN, palabras clave y atributos de la cadena de conexión.
El controlador ODBC 18 de Microsoft habilita el cifrado por defecto. Especifica Encrypt=yes para que el requisito de la solicitud sea explícito. Mantenlo TrustServerCertificate=no en producción para que el controlador valide el certificado del servidor. El certificado debe coincidir el nombre del servidor y la cadena con una autoridad de certificación en la que el cliente confíe. Para orientación de configuración, véase Fallas de validación de certificados.
Caution
TrustServerCertificate=yes Salta la validación de certificados. Úsalo solo para desarrollo local aislado mientras configuras un certificado en el que el cliente confíe. No lo use en producción.
Establece la variable de entorno sin añadir la cadena de conexión al historial de tu shell.
OpenDeveloper PowerShell para VS 2022. Ejecuta estos comandos y luego pega la cadena de conexión en el prompt:
$secureConnectionString = Read-Host "ODBC connection string" -AsSecureString
$env:ODBC_CONNECTION_STRING = [System.Net.NetworkCredential]::new(
"", $secureConnectionString).Password
$secureConnectionString = $null
Una variable de entorno mantiene la cadena de conexión fuera del archivo de código fuente, pero el proceso y sus procesos hijos pueden leerla. Para aplicaciones de producción, utiliza la autenticación de Microsoft Entra siempre que sea posible y recupera secretos de un almacén seguro en tiempo de ejecución.
Creación de la aplicación
Crea un directorio de proyectos y cámbialo a él:
Cree un archivo denominado
odbc-quickstart.cppcon el código siguiente:#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; }
La aplicación utiliza únicamente la API estándar ODBC, por lo que incluye los encabezados de driver-manager y enlaces a la biblioteca driver-manager. La cadena de conexión selecciona el controlador ODBC 18 de Microsoft para SQL Server en tiempo de ejecución.
SQL_DRIVER_NOPROMPT impide SQLDriverConnect abrir un cuadro de diálogo de configuración. Si la cadena de conexión está incompleta, la llamada devuelve un error y la aplicación imprime todos los registros diagnósticos.
La consulta enlaza 0 como un parámetro int de SQL Server, lee los primeros cinco productos de SalesLT.Product y recupera el identificador y el nombre de cada producto con SQLGetData.
Compilación y ejecución de la aplicación
En la misma ventana de PowerShell para desarrolladores, compila la aplicación:
cl /std:c++17 /EHsc /W4 odbc-quickstart.cpp /link odbc32.libEjecute la aplicación:
.\odbc-quickstart.exe
La salida estándar de la aplicación es:
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
Borra la cadena de conexión cuando termines.