Я хочу создать общий класс C ++ C ++, который обрабатывает взаимодействие с базой данных SQL Server через ODBC. std :: wstring-s прилегают правильно, но std :: string-s даже не так, если логика одинакова. std :: wstring правильно достигает базы данных, но std :: string нет.
// allocate statement
// prepare statement
// bind return code
template
inline void StoredProc::bindInputParameter(const T& param)
{
lengths.push_back(0); // member of StoredProc class
SQLLEN* len = &lengths.back();
bound_parameters.push_back(param); // member of StoredProc class
auto& stored_param = std::any_cast(bound_parameters.back());
if constexpr (std::is_same_v) {
strings.push_back(param);
std::string& stored_param = strings.back();
errorCode = SQLBindParameter(
statementHandle, paramNumber++, SQL_PARAM_INPUT,
SQL_C_CHAR, SQL_VARCHAR, 80,
0, (SQLPOINTER)(stored_param.c_str()), stored_param.size() + 1,
NULL
);
}
else if constexpr (std::is_same_v) {
errorCode = SQLBindParameter(
statementHandle, paramNumber++, SQL_PARAM_INPUT,
SQL_C_WCHAR, SQL_WVARCHAR, 80,
0, (SQLPOINTER)(stored_param.c_str()), (stored_param.size() + 1) * sizeof(wchar_t),
NULL
);
}
// other types ...
if (!SQL_SUCCEEDED(errorCode)) { // no errors
cleanup();
throw std::exception(Errors::SQL_STATEMENT_BIND_INPUT_ERROR.data());
}
}
//... bind output parameters
// SQLExecute(statementHandle);
// return code == 0 and no errors registered
левый столбец - это varchar (100) , соответствующий std :: string , должен быть "123" , правый столбец - это nvarchar (max) , соответствует std :: wString , является правильным: Image
Ideb std :: ecector , использовал его для обработки `std :: string` parameters привязка, и это сработало. Однако логика загромождена в этом подходе. < /P>
// this works
if constexpr (std::is_same_v) {
strings.push_back(param); //member in StoredProc
std::string& stored_param = strings.back();
errorCode = SQLBindParameter(
statementHandle, paramNumber++, SQL_PARAM_INPUT,
SQL_C_CHAR, SQL_VARCHAR, 80,
0, (SQLPOINTER)(stored_param.c_str()), stored_param.size() + 1,
NULL
);
}
Мне кажется, что преобразование std :: string в std :: any и обратно в std :: string вызывает некоторые проблемы, о которых я не знаю. Что не так в первом фрагменте? Похоже, база данных не знает, что параметр представляет собой нулевую строку. Можете ли вы дать мне какой -нибудь совет? Другие идеи дизайна для класса StoreDProc приветствуются. В настоящее время появляется та же проблема, если я использую std :: variant и std :: view .
Весь код класса:
Я хочу создать общий класс C ++ C ++, который обрабатывает взаимодействие с базой данных SQL Server через ODBC. std :: wstring-s прилегают правильно, но std :: string-s даже не так, если логика одинакова. std :: wstring правильно достигает базы данных, но std :: string нет. [code]// allocate statement // prepare statement // bind return code
template inline void StoredProc::bindInputParameter(const T& param) { lengths.push_back(0); // member of StoredProc class SQLLEN* len = &lengths.back(); bound_parameters.push_back(param); // member of StoredProc class auto& stored_param = std::any_cast(bound_parameters.back()); if constexpr (std::is_same_v) { strings.push_back(param); std::string& stored_param = strings.back(); errorCode = SQLBindParameter( statementHandle, paramNumber++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 80, 0, (SQLPOINTER)(stored_param.c_str()), stored_param.size() + 1, NULL ); } else if constexpr (std::is_same_v) { errorCode = SQLBindParameter( statementHandle, paramNumber++, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WVARCHAR, 80, 0, (SQLPOINTER)(stored_param.c_str()), (stored_param.size() + 1) * sizeof(wchar_t), NULL ); } // other types ... if (!SQL_SUCCEEDED(errorCode)) { // no errors cleanup(); throw std::exception(Errors::SQL_STATEMENT_BIND_INPUT_ERROR.data()); } } //... bind output parameters // SQLExecute(statementHandle); // return code == 0 and no errors registered [/code] левый столбец - это varchar (100) , соответствующий std :: string , должен быть "123" , правый столбец - это nvarchar (max) , соответствует std :: wString , является правильным: Image Ideb std :: ecector , использовал его для обработки `std :: string` parameters привязка, и это сработало. Однако логика загромождена в этом подходе. < /P> [code]// this works if constexpr (std::is_same_v) { strings.push_back(param); //member in StoredProc std::string& stored_param = strings.back(); errorCode = SQLBindParameter( statementHandle, paramNumber++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 80, 0, (SQLPOINTER)(stored_param.c_str()), stored_param.size() + 1, NULL ); } [/code] Мне кажется, что преобразование std :: string в std :: any и обратно в std :: string вызывает некоторые проблемы, о которых я не знаю. Что не так в первом фрагменте? Похоже, база данных не знает, что параметр представляет собой нулевую строку. Можете ли вы дать мне какой -нибудь совет? Другие идеи дизайна для класса StoreDProc приветствуются. В настоящее время появляется та же проблема, если я использую std :: variant и std :: view . Весь код класса: [code]//SoredProc.h #pragma once
// order of types matters: returns an int and a bool as OUTPUT parameters auto t = proc.execute("[dbo][]", in_param1, in_param2, in_param3, in_param4); return 0; } [/code] См. Это для подключения к базе данных SQL Server.