sqlite 参数绑定 vs2005

zhou_jlong 2011-12-18 02:54:13
我在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类型的变量没什么关系。。。最好有比较清晰的代码。

在此叩谢!!!
...全文
122 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
flyingkate 2011-12-18
  • 打赏
  • 举报
回复
谢谢大家,问题解决了。的确是编码的问题。

是这样的。。。
1,没用占位符,直接open,prepare,step.
2.将文本框的值(unicode)转化成const char*.构造sql语句。传给prepare就可以了。
代码如下:
CString str_value="文本框的字符串值";
CString strSql.Format(_T("select * from dima where dm = '%s'"),str_value);
LPCSTR sql;
USES_CONVERSION;
sql = W2A(strSql.LockBuffer());
strSql.LockBuffer();

然后,prepare(,sql,-1,,);
step();

程序按查询条件返回结果!

开心啊,了结了我两天的郁闷。结贴。。
kael_9527 2011-12-18
  • 打赏
  • 举报
回复
给一段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);
}
zhou_jlong 2011-12-18
  • 打赏
  • 举报
回复
守望者,Cstr()在2005中好像没有啊。再者,在我上面这个问题中,怎么用Cstr()?
woshi_ziyu 2011-12-18
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 zhou_jlong 的回复:]

NorthCan你好,忘了说明一下。

CString strSQL;
strSQL.Format(TEXT("SELECT * FROM mytable WHERE dm='%s'"), str_value);
compile(strSQL);
... ...

这样做可以,但问题是,以后要将strSql作为输入参数传给sqlite3_prepare_v2(),它的原型是这样的。……
[/Quote]
试试cstr()
zhou_jlong 2011-12-18
  • 打赏
  • 举报
回复
NorthCan你好,忘了说明一下。

CString strSQL;
strSQL.Format(TEXT("SELECT * FROM mytable WHERE dm='%s'"), str_value);
compile(strSQL);
... ...

这样做可以,但问题是,以后要将strSql作为输入参数传给sqlite3_prepare_v2(),它的原型是这样的。
SQLITE_API int sqlite3_prepare_v2(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */

就是第二个参数,它是const char*型的,直接把CString传给它好像不行,编译通不过。
要做什么样的转换呢,折腾N久了,,,,头晕。
zhou_jlong 2011-12-18
  • 打赏
  • 举报
回复
我自己顶顶,也解解心里的郁闷。
vs2005咋这么不好用。举几个例子。
在vc60下,WideCharToMultiByte()或MultiByteToWideChar() 都很好用,放到2005中,编译都通不过;还有,,在vc60中:const char *sql = str.getbuffer(0)可用,在2005中就出错。如此等等,都要疯了,不用2005又不行,vc60不支持wince开发,头大头大。。
zhou_jlong 2011-12-18
  • 打赏
  • 举报
回复
CString strSQL;
strSQL.Format(TEXT("SELECT * FROM mytable WHERE dm='%s'"), str_value);
compile(strSQL);
... ...


我现在不在办公室,。。没法试
compile(strSql);是什么?是sqlite的prepare吗
northcan 2011-12-18
  • 打赏
  • 举报
回复
在执行这句代码之后,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);
... ...



19,502

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧