C++ 如何使用ODBC(C+;+;)从MS SQL获取nvarchar作为字符串?

C++ 如何使用ODBC(C+;+;)从MS SQL获取nvarchar作为字符串?,c++,string,odbc,nvarchar,sqlbindparameter,C++,String,Odbc,Nvarchar,Sqlbindparameter,我试图从我的SQL数据库中提取一个字符串,但由于某些原因,我的参数是错误的,我不知道为什么。这是我的密码: SQLHENV environHandle; SQLHDBC connectHandle; SQLHSTMT statement; SQLCHAR* connectString = "MY_CONNECTION_STRING"; string path; int jobID; SQLINTEGER pathstrlen = SQL_NTS; SQLAllocHandle(SQL_HA

我试图从我的SQL数据库中提取一个字符串,但由于某些原因,我的参数是错误的,我不知道为什么。这是我的密码:

SQLHENV environHandle;
SQLHDBC connectHandle;
SQLHSTMT statement;
SQLCHAR* connectString = "MY_CONNECTION_STRING";
string path;
int jobID;  
SQLINTEGER pathstrlen = SQL_NTS;

SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &environHandle);
SQLSetEnvAttr(environHandle, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
SQLAllocHandle(SQL_HANDLE_DBC, environHandle, &connectHandle);
SQLDriverConnect(connectHandle, NULL, connectString, SQL_NTS, NULL, 1024, NULL, SQL_DRIVER_NOPROMPT);
SQLAllocHandle(SQL_HANDLE_STMT, connectHandle, &statement);

//THIS IS THE BINDPARAMETER WITH THE ISSUE...
SQLBindParameter(statement, 1, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, 400, 0, (SQLPOINTER)path.c_str(), path.length(), &pathstrlen);

SQLBindParameter(statement, 2, SQL_PARAM_OUTPUT, SQL_INTEGER, SQL_INTEGER, 10, 0, &jobID, 0, &pathstrlen);

SQLExecDirect(statement, (SQLCHAR*)"{CALL SP(?,?)}", SQL_NTS);
它运行正常,但无法获取我请求的字符串信息,而第二个参数(获取整数)工作正常。我尝试将参数类型更改为多个不同的内容,但我要么收到错误(例如,不推荐使用SQL_LONGVARCHAR)

在SQL中,我尝试获取的数据如下所示:

@Path nvarchar(4000) OUT
set @Path = 'test'
提前感谢任何能够阐明这一点的人。我一整天都在拼命工作。

ODBC支持使用
SQL\u C\u WCHAR
SQL\u WVARCHAR
而不是
SQL\u C\u CHAR
SQL\u VARCHAR

你还有另外两个问题

首先,将ANSI
字符串作为参数传递。如果使用Unicode,则需要使用宽字符串-
wstring

其次,您没有向
sqlbindparmeter
传递有效的缓冲区。返回的值是一个只读缓冲区
常量char*
。将hat传递给需要可写缓冲区的函数是无效的-这样做会损坏字符串。但是,在您的案例中不会看到任何损坏,因为对
path.length()
的调用将返回零,因此
SQLBindParameter
将永远不会返回任何数据

您需要声明
WCHAR
array buffer并将其传递给
SQLBindParameter
,这将为它提供一个有效的缓冲区来写入数据。然后,如果您需要C++对象,则可以将该缓冲区转移到<代码> WStord。 比如说:

WCHAR path[401];  // 401 - width of you column + 1 for the null terminator
SQLBindParameter(statement, 1, SQL_PARAM_OUTPUT, SQL_C_WCHAR, SQL_WVARCHAR, 400, 0,     (SQLPOINTER)path, sizeof(path), &pathstrlen);
编辑

Ffrom查看,如果您不想在应用程序中处理Unicode字符串,那么您应该能够使用ODBC将数据从Unicode转换为ANSI

char path[401];  // 401 - width of you column + 1 for the null terminator
SQLBindParameter(statement, 1, SQL_PARAM_OUTPUT, SQL_C_WCHAR, SQL_WVARCHAR, 400, 0,     (SQLPOINTER)path, sizeof(path), &pathstrlen);

非常感谢您提供的信息丰富且准确的答案。非常感谢!我不确定您是否正确wrt“如果您使用Unicode,则需要使用宽字符串”和wrt您的编辑。即使您已经使用为ODBC定义的unicode构建了应用程序,您也应该能够将SQL_VARCHAR传递给SQLBindParameter,并且驱动程序应该返回一个ansi字符串。此外,传递SQL_WVARCHAR但提供char路径[401]仍将在路径中放置宽chr,而不是ansi chr。