Как я могу получить nvarchar из MS SQL в виде строки, используя ODBC (C ++)?

Я пытаюсь извлечь строку из базы данных 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'

Заранее спасибо всем, кто может пролить свет на это. Я вырывал свои волосы весь день.

0

Решение

ODBC поддерживает Типы параметров Unicode так что пользуйтесь SQL_C_WCHAR а также SQL_WVARCHAR вместо SQL_C_CHAR а также SQL_VARCHAR соответственно.

У вас есть еще две проблемы.

Сначала вы передаете ANSI string в качестве параметра. Если вы используете Unicode, вам нужно использовать широкую строку — wstring вместо.

Во-вторых, вы не передаете действительный буфер SQLBindParameter, Значение, возвращаемое string.c_str () это const char* это буфер только для чтения. Недопустимо передавать шляпу функции, которая требует доступного для записи буфера — это повредит вашу строку. Однако вы не увидите никакой коррупции в вашем деле, потому что вы призываете path.length() Вернет ноль так SQLBindParameter никогда не вернет никаких данных.

Вам нужно будет объявить WCHAR буфер массива и передать его SQLBindParameter что даст ему правильный буфер для записи данных. Затем вы можете перенести этот буфер в wstring если вам это нужно в объекте C ++.

Так что-то вроде этого:

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 Похоже, вы должны иметь возможность заставить ODBC преобразовывать эти данные из Unicode в ANSI для вас, если вы не хотите иметь дело со строками Unicode в вашем приложении.

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]