如何在Visual Studio中为C++项目连接Azure SQL Database?
问题描述
Azure SQL Database是SQL Server的云端版本。现有演示针对的是C# Web应用程序,请问如何为C++项目实现类似SSMS连接SQL Server那样的Azure SQL Database连接?
实现方法
C++项目连接Azure SQL Database可以通过ODBC或OLE DB两种常用方式实现,以下是具体步骤和代码示例:
方法一:使用ODBC驱动
前置准备
- 安装Microsoft ODBC Driver 17 for SQL Server(适配Azure SQL的官方驱动)
- 确认Azure SQL的防火墙规则已添加当前客户端IP,允许访问
- 准备好Azure SQL的连接信息:服务器名称(格式:
xxx.database.windows.net)、数据库名称、SQL认证用户名和密码
代码示例
#include <windows.h> #include <sql.h> #include <sqlext.h> #include <stdio.h> int main() { SQLHENV henv; SQLHDBC hdbc; SQLHSTMT hstmt; SQLRETURN retcode; // 初始化ODBC环境 retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0); // 分配连接句柄 retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); // 构建连接字符串,替换为你的Azure SQL信息 SQLCHAR connStr[] = "DRIVER={ODBC Driver 17 for SQL Server};SERVER=<你的服务器名称>.database.windows.net;DATABASE=<数据库名称>;UID=<用户名>;PWD=<密码>"; // 发起连接 retcode = SQLDriverConnect(hdbc, NULL, connStr, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE); if (SQL_SUCCEEDED(retcode)) { printf("连接Azure SQL Database成功!\n"); // 分配语句句柄并执行查询示例 retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); retcode = SQLExecDirect(hstmt, (SQLCHAR*)"SELECT @@VERSION", SQL_NTS); // 读取查询结果 SQLCHAR version[256]; SQLLEN len; if (SQL_SUCCEEDED(retcode) && SQL_SUCCEEDED(SQLFetch(hstmt))) { SQLGetData(hstmt, 1, SQL_C_CHAR, version, sizeof(version), &len); printf("数据库版本:%s\n", version); } // 释放资源 SQLFreeHandle(SQL_HANDLE_STMT, hstmt); SQLDisconnect(hdbc); } else { printf("连接失败!\n"); SQLCHAR errMsg[256]; SQLSMALLINT errLen; SQLGetDiagRec(SQL_HANDLE_DBC, hdbc, 1, NULL, NULL, errMsg, sizeof(errMsg), &errLen); printf("错误信息:%s\n", errMsg); } // 清理环境和连接句柄 SQLFreeHandle(SQL_HANDLE_DBC, hdbc); SQLFreeHandle(SQL_HANDLE_ENV, henv); return 0; }
编译说明
编译时需要链接odbc32.lib库,在Visual Studio中可通过项目属性 -> 链接器 -> 输入 -> 附加依赖项添加该库。
方法二:使用OLE DB
前置准备
- 确保项目启用COM支持(Visual Studio中可通过ATL项目模板或手动初始化COM)
- 准备好Azure SQL的连接信息,同ODBC方法
代码示例
#include <windows.h> #include <oledb.h> #include <oledberr.h> #include <stdio.h> int main() { HRESULT hr; IDBInitialize* pIDBInitialize = NULL; IDBCreateSession* pIDBCreateSession = NULL; IDBCreateCommand* pIDBCreateCommand = NULL; ICommandText* pICommandText = NULL; // 初始化COM环境 hr = CoInitialize(NULL); if (FAILED(hr)) { printf("COM初始化失败!\n"); return -1; } // 创建SQL Server数据源对象 hr = CoCreateInstance(CLSID_SQLNCLI11, NULL, CLSCTX_INPROC_SERVER, IID_IDBInitialize, (void**)&pIDBInitialize); if (FAILED(hr)) { printf("创建数据源对象失败!\n"); CoUninitialize(); return -1; } // 设置连接属性 DBPROPSET dbpropset[1]; DBPROP dbprops[4]; memset(dbprops, 0, sizeof(dbprops)); // 服务器名称 dbprops[0].dwPropertyID = DBPROP_INIT_DATASOURCE; dbprops[0].vValue.vt = VT_BSTR; dbprops[0].vValue.bstrVal = SysAllocString(L"<你的服务器名称>.database.windows.net"); dbprops[0].dwOptions = DBPROPOPTIONS_REQUIRED; // 数据库名称 dbprops[1].dwPropertyID = DBPROP_INIT_CATALOG; dbprops[1].vValue.vt = VT_BSTR; dbprops[1].vValue.bstrVal = SysAllocString(L"<数据库名称>"); dbprops[1].dwOptions = DBPROPOPTIONS_REQUIRED; // 用户名 dbprops[2].dwPropertyID = DBPROP_AUTH_USERID; dbprops[2].vValue.vt = VT_BSTR; dbprops[2].vValue.bstrVal = SysAllocString(L"<用户名>"); dbprops[2].dwOptions = DBPROPOPTIONS_REQUIRED; // 密码 dbprops[3].dwPropertyID = DBPROP_AUTH_PASSWORD; dbprops[3].vValue.vt = VT_BSTR; dbprops[3].vValue.bstrVal = SysAllocString(L"<密码>"); dbprops[3].dwOptions = DBPROPOPTIONS_REQUIRED; dbpropset[0].rgProperties = dbprops; dbpropset[0].cProperties = 4; dbpropset[0].guidPropertySet = DBPROPSET_DBINIT; // 发起连接 hr = pIDBInitialize->Initialize(dbpropset, 1); if (SUCCEEDED(hr)) { printf("连接Azure SQL Database成功!\n"); // 创建会话和命令对象执行查询 if (SUCCEEDED(pIDBInitialize->QueryInterface(IID_IDBCreateSession, (void**)&pIDBCreateSession)) && SUCCEEDED(pIDBCreateSession->CreateSession(NULL, IID_IDBCreateCommand, (IUnknown**)&pIDBCreateCommand)) && SUCCEEDED(pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText, (IUnknown**)&pICommandText))) { hr = pICommandText->SetCommandText(DBGUID_SQL, L"SELECT @@VERSION"); if (SUCCEEDED(hr)) { printf("查询执行成功!\n"); // 此处可添加结果读取逻辑 } } // 断开连接 pIDBInitialize->Uninitialize(); } else { printf("连接失败!\n"); } // 释放资源 if (pICommandText) pICommandText->Release(); if (pIDBCreateCommand) pIDBCreateCommand->Release(); if (pIDBCreateSession) pIDBCreateSession->Release(); if (pIDBInitialize) pIDBInitialize->Release(); CoUninitialize(); return 0; }
编译说明
编译时需要链接oledb.lib和sqlncli11.lib库,根据驱动版本调整库名称(如使用最新驱动可改为sqlncli17.lib)。
注意事项
- 务必将代码中的占位符替换为实际的Azure SQL连接信息
- 优先使用SQL Server认证方式(用户名+密码),与SSMS连接逻辑一致
- 若连接失败,先检查防火墙规则是否生效,再排查连接字符串是否正确
内容的提问来源于stack exchange,提问作者Zhang
相关产品推荐
相关产品推荐

