Я пытаюсь извлечь строку из базы данных 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'
Заранее спасибо всем, кто может пролить свет на это. Я вырывал свои волосы весь день.
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);
Других решений пока нет …