-
ODBC BindParametert 사용 시 문자열의 길이로는 SQL_NTS를 넣어줘야 한다.프로그래밍/의문 2015. 10. 28. 20:27반응형
내가 실행할 쿼리
const char* query = "{ call get_account_info_by_id ( ? ) }";
인자로는 유저의 id를 받는다. 그리고 유저의 계정 정보를 반환한다.
그런데 쿼리는 정상적으로 실행이 되는데, fetch의 반환 값이 SQL_NO_DATA인 것이었다.
왜지? 존재하는 유저로 요청을 했는데?
여기저기 검색을 해서 찾아봤는데, SQLBindParameter에 문자열을 쓰려면(출력 또는 입력으로)
SQL_NTS를 인자를 줘야한다는 내용이 보였다.
그리고 정말 되나 실행해봤는데 검색이 정상적으로 되더라.
123456789connector.prepare(query);// 쿼리의 출력 인자를 설정합니다.SQLINTEGER procreslen = SQL_NTS; // !!auto idlen = std::strlen(id.data());// 쿼리의 입력를 설정합니다.(id)connector.bind_parameter_in(SQL_C_CHAR, SQL_CHAR, id.size(), 0, (void*)id.data(), idlen, &procreslen); // id 설정cs (bind_parameter_in은 SQLBindParameter에 파라미터 타입 값을 SQL_PARAM_INPUT로 설정해둔 함수이다.)
해당 부분의 전체적 소스코드.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162boost::optional<user_info> database_cache_server::get_user_info_from_database(const std::array<char, PACKET::max_id_length>& id){constexpr char query[] = "{ call get_account_info_by_id ( ? ) }";std::lock_guard<decltype(load_data_mutex)> guard{ load_data_mutex };boost::optional<user_info> opt;// 쿼리를 준비합니다.if (connector.prepare(query)){// 쿼리의 출력 인자를 설정합니다.SQLINTEGER procreslen = SQL_NTS;auto idlen = std::strlen(id.data());// 쿼리의 입력를 설정합니다.(id)connector.bind_parameter_in(SQL_C_CHAR, SQL_CHAR, id.size(), 0, (void*)id.data(), idlen, &procreslen); // id 설정// select 값을 받을 변수들std::array<char, 20> out_id;std::array<wchar_t, 20> out_pw;std::array<wchar_t, 20> out_nickname;SQLINTEGER out_win = -1; // winSQLINTEGER out_lose = -1; // loseSQLINTEGER out_idlen = -1;SQLINTEGER out_pwlen = -1;SQLINTEGER out_nicknamelen = -1;SQLINTEGER out_winlen = sizeof(out_win);SQLINTEGER out_loselen = sizeof(out_lose);// select 결과 값을 받을 변수들을 지정합니다.(id, pw, nickname, win, lose)connector.bind_column(SQL_C_CHAR, out_id.data(), sizeof(out_id), &out_idlen); // idconnector.bind_column(SQL_C_WCHAR, out_pw.data(), sizeof(out_pw), &out_pwlen); // pwconnector.bind_column(SQL_C_WCHAR, out_nickname.data(), sizeof(out_nickname), &out_nicknamelen); // nicknameconnector.bind_column(SQL_C_SLONG, &out_win, sizeof(out_win), &out_winlen); // winconnector.bind_column(SQL_C_SLONG, &out_lose, sizeof(out_lose), &out_loselen); // lose// 쿼리 실행if(connector.excute()){// 출력 결과를 받습니다.if (connector.fetch()){user_info info;info.id = out_id;info.pw = out_pw;info.nickname = out_nickname;info.num_win = out_win;info.num_lose = out_lose;opt = info;}}}// 커서를 닫습니다.connector.close_cursor();return opt;}cs 어느정도 정리가 되면 커넥터 부분도 좀 더 깔끔하게 바꿔야겠다. stmt가 커넥터랑 하나로 뭉쳐있는 것도 그렇고 흐으으
반응형'프로그래밍 > 의문' 카테고리의 다른 글
코드 안에 if~else 구문이 많다는 건 다른 성격의 것들을 한 데에 모아놨다는 것이다. (0) 2015.11.14 간결하고 깨끗한 코드 vs 높은 성능 (0) 2015.11.11 VS NuGet으로 라이브러리가 설치되지 않았던 문제 (0) 2015.08.23 std::shared_ptr shared_from_this 잘못된 사용 (0) 2015.08.07 asio udp client 작업 중 람다 캡처를 잘못 사용한 문제 (0) 2015.07.14