sqlite 参数绑定 vs2005
我在vs2005下用vc做pda开发(Unicode环境),调用sqlite3.dll.
有一问题折腾好几天了没弄明白,求教大家。
调用sqlite3的过程比较简明:不外乎open,prepare,bind,step几步,这没有什么问题。问题在于,我在处理sql语句绑定时,老是出现乱码,为了说明问题,我举个例子。
假如:
char sql[256];
sprintf(sql,"select * from mytable where dm='我');
prepare(...);
bind(...);
step(...);
程序执行成功,并正常返回结果。
如果把sprint语句改成:sprintf(sql,"select * from mytable where dm='%s'",str_value); str_value是窗体一个edit中的内容,那么调试显示:sql语句内容有问题,变量的部分是一个类似回车换行的粗箭头,即乱码,执行当然不成功了。找到了问题,但不明白为什么?在vs2005 Unicode环境下,sql语句中的条件直接输入一个“我”和从文本框中取出来的CString,编码不一样?为什么呢?我只是在vc中调试即发现乱码,还没有进到sqlite库取数据呢,这跟sqlite3的utf8编码没关系吧。。。
我在网上查,有不少人说字符集的问题,要转换,但我一直不明白,这两种方式:直接输入的‘我’是什么编码呢,文本框取出来的CString又是什么编码?是从宽字符转unicode还是从unicode转gb1321?真的很迷糊.
不知道我说明白了没有,但渴望明白人指点一下,不要光说什么WideCharToMultiByte()或MultiByteToWideChar() 之类的,我也知道,但它们好像跟CString类型的变量没什么关系。。。最好有比较清晰的代码。
在此叩谢!!!
[解决办法]
在执行这句代码之后,sql的内容就有了乱码,那问题和SQlite数据库肯定没半点关系了。
sprintf(sql,"select * from mytable where dm='%s'",str_value);
那执行这句代码之前,str_value是从编辑框获取的吧。通过UpdateData或者GetDlgItemText函数等等。
执行sprintf之前,str_value是正常的吗?如果是正常的,问题就出在sprintf函数上了。
因为'我'是一个汉字,是宽字符。char sql[256];,那么sql是个窄字符数组。恐怕直接用sprintf格式化是不行的。
对SQlite数据库的使用有点忘记了。不知道直接这样可不可以:
CString strSQL;
strSQL.Format(TEXT("SELECT * FROM mytable WHERE dm='%s'"), str_value);
compile(strSQL);
... ...
[解决办法]
给一段CppSQLite3U.cpp中的源码,看看你应该能知道编码的问题,我用VS2005+sqlite3在WINCE下面,都很正常的
void CppSQLite3DB::open(LPCTSTR szFile){ int nRet;#if defined(_UNICODE) || defined(UNICODE) nRet = sqlite3_open16(szFile, &mpDB); // not tested under window 98 #else // For Ansi Version//*************- Added by Begemot szFile must be in unicode- 23/03/06 11:04 - **** OSVERSIONINFOEX osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); GetVersionEx ((OSVERSIONINFO *) &osvi); if ( osvi.dwMajorVersion == 5) { WCHAR pMultiByteStr[MAX_PATH+1]; MultiByteToWideChar( CP_ACP, 0, szFile, _tcslen(szFile)+1, pMultiByteStr, sizeof(pMultiByteStr)/sizeof(pMultiByteStr[0]) ); nRet = sqlite3_open16(pMultiByteStr, &mpDB); } else nRet = sqlite3_open(szFile,&mpDB);#endif//************************* if (nRet != SQLITE_OK) { LPCTSTR szError = (LPCTSTR) _sqlite3_errmsg(mpDB); throw CppSQLite3Exception(nRet, (LPTSTR)szError, DONT_DELETE_MSG); } setBusyTimeout(mnBusyTimeoutMs);}