C++, ADO 그리고 MS SQL Server 2008 |
ADO 연결에 삽질했던 시기에 썼던 글입니다. 연동시 참고 할 만합니다.
연동 제대로 하기 |
저와같이 개고생 하지 마시라고 올립니다.
C++, ADO 그리고 MS SQL Server 2008
요 3녀석 때문에 몇일동안 골치를 썩네요.
바로 '인코딩'문제때문인데요,
UTF-8인코딩으로 서비스를 제공해야할 필요가 있었서 적용을 하려하니, MySQL과는 다르게 인코딩방식을 지정해 주는게 없더라구요.
첫번째로 MS SQL SERVER의 인코딩 방식을 찾는라 삽질을 많이 했구요.
두번째로 ADO가 connectionstring시, CharSet=UTF8;을 하더라도, 그것이 제대로 적용이 안되어서 1차적으로 별놈의 삽질을 다했구요.
세번째로 C++에서 INSERT, SELECT, UPDATE 등의 쿼리시 데이터의 치환작업을 제대로 안해줘서 굉장하게 별난 놈의 삽질을 했네요.
결론은 이렇습니다.
첫번째 문제는 N계열의 CHARACTER 타입의 컬럼을 생성하면 됩니다.
NCHAR, NVARCHAR, NTEXT .. 등의 타입이 있죠. 이것은 C++의 wchar_t 와 대응됩니다.
C++의 유니코드 표현방식인 wchar_t은 UTF-8과 표현방식이 다른것은 다들 아실테구요.
두번째 문제는 ADO CharSet을 정하지 않는다 입니다. 정해봤자 이게 도대체 어떤식으로 작동하는지 감이 안잡히는 겁니다. 그래서 CharSet은 제거하구요.
세번째 문제는 받은 데이터는 UTF-8로 저장된 bytes 입니다. 1byte 들로 이루어진 데이터란 뜻이구요.
이것들을 wchar_t로 변경해야 합니다. ms-sql에 정상적인 입력을 위해서요.
변경해서 입력하면 되구요,
이제 이것들을 select 해서 받아올땐, 다시 1byte로 이루어진 UTF-8데이터로 변경해야 합니다.
역시 받아오면 변경해서 출력해 줘야 합니다.
이렇게 하면 MS-SQL에도 제대로된 값이 들어가서 한글표현이 잘되구요,
CLIENT측에서도 제대로된 값을 받습니다.
**위의 문제를 해결하기위한 서버측 코드입니다.
MSSQL을 접속하기 위한 ADO connectionstring = "Provider=sqloledb; Data Source=%s; uid=%s; pwd=%s; Initial Catalog=%s;"
**INSERT 시 필요한 컨버팅작업
std::string szText = recv(...); // 데이터를 받은 곳입니다. 소켓통신으로 받았죠.
swprintf_s(szQuery, 1024, L"INSERT INTO DATA_TEXT(NTXT) VALUES('%s');", UTF8TOANSI(szText).c_str());
**SELECT 시 필요한 컨버팅작업
Excute("SELECT NTXT FROM DATA_TEXT", &pPar);
std::string szText2 = ANSITOUTF8((wchar_t*)pPar->GetString("NTXT"));
std::string ANSITOUTF8(std::wstring szUnicode)
{
std::string szRes;
size_t nUTF8Size = (szUnicode.size()*3)+1;
char *pszUTF8 = new char[nUTF8Size];
memset(pszUTF8, 0, nUTF8Size);
::WideCharToMultiByte(CP_UTF8, 0, szUnicode.c_str(), -1, pszUTF8, nUTF8Size, NULL, NULL);
szRes = pszUTF8;
delete [] pszUTF8;
return szRes;
}
std::wstring UTF8TOANSI(std::string szUTF8)
{
std::wstring szRes;
size_t nUnicodeSize = szUTF8.size() + 1;
wchar_t *pszUnicode = new wchar_t[nUnicodeSize];
memset(pszUnicode, 0, nUnicodeSize);
::MultiByteToWideChar(CP_UTF8, 0, szUTF8.c_str(), -1, pszUnicode, nUnicodeSize);
szRes = pszUnicode;
delete [] pszUnicode;
return szRes;
}
도움이 되시길 바랍니다.
'오래된것' 카테고리의 다른 글
일본 치바현 이즈미시 오오하라 항구에 멸치 시체더미가. (0) | 2012.06.05 |
---|---|
do~while인가, 중복 if문인가 (0) | 2012.06.05 |
KT APN 잡기(3G가 안되요) (0) | 2012.06.05 |
처음으로 내가 맘에 드는 굉장한 스팩의 노트북을 구매했습니다. (0) | 2012.06.04 |
MySQL – 새 사용자 생성 (0) | 2012.06.04 |