MSVC编译报错:SQL_COPT_SS_MARS_ENABLED未声明标识符及相关疑问
SQL_COPT_SS_MARS_ENABLED 未声明标识符,及Windows版本条件包含头文件方案 问题背景
代码片段
#define _SQLNCLI_ODBC_ #if defined( _MSC_VER ) && !defined( __clang__ ) #include "sqlncli.h" #endif ret = SQLSetConnectAttr( m_hdbc, SQL_COPT_SS_MARS_ENABLED, SQL_MARS_ENABLED_YES, SQL_IS_UINTEGER ); if( ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO && ret != SQL_NO_DATA ) { GetErrorMessage( errorMsg, 2 ); result = 1; }
当前配置
已在项目属性→C/C++→常规→附加包含目录中配置路径:C:\Program Files (x86)\Visual Leak Detector\include;C:\Program Files (x86)\Microsoft SQL Server\110\SDK\Include;%(AdditionalIncludeDirectories)
异常现象
右键点击SQL_COPT_SS_MARS_ENABLED选择「转到定义」时,MSVC可成功定位到sqlncli.h中的该符号,但编译时报错:
error C2065: 'SQL_COPT_SS_MARS_ENABLED': undeclared identifier
限制条件
Windows 8.1 + MSVC 2017环境下,微软推荐的新驱动不兼容,无法切换到新驱动。
额外需求
能否识别编译环境,仅在Windows 10以下系统中包含该头文件?
解决方案
一、解决编译报错问题
确保宏定义的有效性
打开sqlncli.h查看SQL_COPT_SS_MARS_ENABLED的定义,该符号通常被#ifdef _SQLNCLI_ODBC_包裹,只有定义此宏才会暴露该符号。将宏定义移至代码最顶部,避免被其他头文件干扰:#define _SQLNCLI_ODBC_ #if defined( _MSC_VER ) && !defined( __clang__ ) #include "sqlncli.h" #endif全局添加预处理器宏
如果代码内的宏定义仍不生效,直接在项目属性→C/C++→预处理器→预处理器定义中添加_SQLNCLI_ODBC_,确保编译时全局生效,消除编辑器索引与编译环境的宏差异。验证头文件版本
确认使用的是SQL Server 110(2012)SDK中的sqlncli.h,避免因头文件版本不匹配导致符号未定义。
二、按Windows版本条件包含头文件
利用Windows SDK预定义宏_WIN32_WINNT判断系统版本,Windows 10对应的宏值为_WIN32_WINNT_WIN10(0x0A00),修改头文件包含逻辑如下:
// 可选:若项目未设置目标系统版本,先明确定义 #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0602 // 对应Windows 8.1 #endif #define _SQLNCLI_ODBC_ #if defined( _MSC_VER ) && !defined( __clang__ ) && (_WIN32_WINNT < _WIN32_WINNT_WIN10) #include "sqlncli.h" #endif
这样编译时会自动判断目标系统版本,仅在Windows 10及以下(_WIN32_WINNT值小于0x0A00)的环境中包含sqlncli.h。
内容的提问来源于stack exchange,提问作者Igor

