【问题标题】:How do I get an nvarchar from MS SQL as string using ODBC (C++)?如何使用 ODBC (C++) 从 MS SQL 获取 nvarchar 作为字符串?
【发布时间】:2013-02-07 02:23:53
【问题描述】:

我正在尝试从我的 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'

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

【问题讨论】:

    标签: c++ string odbc nvarchar sqlbindparameter


    【解决方案1】:

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

    【讨论】:

    • 非常感谢您提供的信息丰富且准确的答案。非常感谢!
    • 我不确定您是否正确 wrt “如果您使用 Unicode,您需要使用宽字符串”并进行编辑。即使您使用为 ODBC 定义的 unicode 构建应用程序,您也应该能够将 SQL_VARCHAR 传递给 SQLBindParameter,并且驱动程序应该返回一个 ansi 字符串。此外,传递 SQL_WVARCHAR 但提供 char 路径 [401] 仍会将宽字符放在路径中,而不是 ansi chrs。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-18
    • 1970-01-01
    相关资源
    最近更新 更多