最近需要将文件字符编码为utf-8中的文本数据插入到数据库中,由于使用mfc的CString 类型。在读取到内存中的时候看到的是乱码,一般情况下可以将utf-8转成ascii编码然后在进行插入。但是utf-8字符编码下的有些字符在ascii码中找不到对应的字符,从而会显示??,因此会产生数据丢失。所以此方法不太可行,除非是没有特殊字符:如数学中公式符号、集合符号等。
由于之前在别的工程中使用unicode编码也可以正常将字段插入到数据库中。又unicode和utf-8之间进行转换并不会发生信息丢失,于是尝试使用unicode来进行尝试,开始还担心需要将数据库操作类全部改成unicode,后来发现并不需要,只需要在数据库操作类中重载一个函数即可,即接受CStringW作为传入参数,然后执行插入操作。(我使用的是ADO的一套东西,需要在StdAfx.h中加入:
#import"c:\program files\common files\system\ado\msado15.dll" no_namespace rename ("EOF","EndOfFile"))
BOOL CDBOperator::ExecuteQuery(CStringW strSql)
{
_RecordsetPtr repRs;
_variant_t RecordsAffected;
try
{
repRs.CreateInstance(__uuidof(Recordset));
repRs->Open(strSql.GetBuffer(strSql.GetLength()+10), m_pConn.GetInterfacePtr(), adOpenKeyset, adLockOptimistic, adCmdUnknown);
strSql.ReleaseBuffer();
return TRUE;
}
catch(_com_error &e)
{
//CString strErrorSql;
//WStringToChar(strSql, strErrorSql);
//ShowError(e, strErrorSql);
return FALSE;
}
return FALSE;
}
这个函数与
BOOL CDBOperator::ExecuteQuery(CString strSql)就是一个参数差别。居然也能运行,看来
_RecordsetPtr
这个东西确实挺智能的。当然这样做的后果是,你需要在写插入语句的地方进行utf-8转unicode,这个函数:
std::wstring UTF8ToWString(const char* lpcszString)
{
int len = strlen(lpcszString);
int unicodeLen = ::MultiByteToWideChar(CP_UTF8, 0, lpcszString, -1, NULL, 0);
wchar_t* pUnicode;
pUnicode = new wchar_t[unicodeLen + 1];
memset((void*)pUnicode, 0, (unicodeLen + 1) * sizeof(wchar_t));
::MultiByteToWideChar(CP_UTF8, 0, lpcszString, -1, (LPWSTR)pUnicode, unicodeLen);
wstring wstrReturn(pUnicode);
delete [] pUnicode;
return wstrReturn;
}
当然这个不是纯天然的utf-8字符操作,具体直接插入utf-8参见大神博客:
http://blog.csdn.net/iaccepted/article/details/32939679
注:插入前请确认自己的数据库默认语言是什么: 使用show variables like '%char%'