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

时间:2013-02-06 17:56:12

标签: 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_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);

它运行正常,但不会获取我请求的字符串信息,而第二个参数(获取整数)工作正常。我已经尝试将ParameterType更改为多个不同的东西,但我得到了错误(例如SQL_LONGVARCHAR,不推荐使用)。

在SQL中,我想要获取的数据如下:

@Path nvarchar(4000) OUT
set @Path = 'test'

提前感谢任何能够阐明这一点的人。我一整天都在拔头发。

1 个答案:

答案 0 :(得分:2)

ODBC支持Unicode parameter types,因此请分别使用SQL_C_WCHARSQL_WVARCHAR代替SQL_C_CHARSQL_VARCHAR

您还有其他两个问题。

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

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

您需要声明WCHAR数组缓冲区并将其传递给SQLBindParameter,这将为其提供一个有效的缓冲区来写入数据。然后,如果在C ++对象中需要,可以将该缓冲区传输到wstring

这样的事情:

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);

修改

从查看ODBC data conversion table看来,如果您不想在应用程序中处理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);