分类:
2010-07-25 13:41:34
=====================================================#include#include static int callback(void *NotUsed, int argc, char **argv, char **azColName){ int i; for(i=0; i ============================================================可以看到,SQL访问数据库的非常方便。只需要简单的三个函数。sqlite3_open(char* szDbFileName, sqlite3 ** db)sqlite3_exec(sqlite3 *db, char* szSqlCMD, callback, 0, char **zErrMsg)sqlite3_close(sqlite3 *db)static int callback(void *NotUsed, int argc, char **argv, char **azColName)注意有些行参是两个星.需要解释的关键是sqlite3_exec(sqlite3 *db, char* szSqlCMD, callback, void *NotUsed, char **zErrMsg)执行一条SQL语句,并且,每返回一个结果,就执行一次 callback 函数,方便我们对查询到的数据进行处理。看一下回调函数callback。必须是static的, 可以是类的成员函数。其中的形参argc, argv, azColName是sqlite_exec帮我们填写的。argc是查询语句返回的字段数目argv是查询到的一条记录的各个字段zaColName是每一列的域名比如这样一张表MYTABLEID NAME ADDRESS AGE1 trulyliu ShangHai 252 sunfyer ShangHai 25执行 select * from MYTABLE当查询到第一条纪录,回调被运行时argc = 4 总共4个字段argv[0] argv[1] argv[2] argv[3] 的值分别是1 trulyliu ShangHai 25zaColName[0] zaColName[1] zaColName[2] zaColName[3] 的值ID NAME ADDRESS AGE第二条记录被查询到时argc = 4 总共4个字段argv[0] argv[1] argv[2] argv[3] 的值分别是1 trulyliu ShangHai 25zaColName[0] zaColName[1] zaColName[2] zaColName[3] 的值ID NAME ADDRESS AGE注意,查询到的这些值都是char*类型,可能需要做类型转换,以满足我们的要求。再来看sqlite3_exec()和callback()都具有的一个形式参数,void *NotUsed,这个参数用处非常大。不过例子把它设成了0, 没有利用上。我们可以把传递一个对象的指针进取,到了callback函数中,再把void * 强制转换成 原来的类型,然后来进行一列操作,比如压栈。下面我来举一个例子。===========================================================class A{public:A:A();typedef{int ID;int AGE;string NAME;string ADDRESS;}Info;private:vectorInfoList; int getDB();static int callback(void *pvoid, int argc, char **argv, char **azColName);}我们的目的是把上面那个表,存储到vectorInfo中。 如果不利用那个void*行参,我们就需要申请全局变量。这样做是比较危险的。下面看看阿朱教我做法。int A::callback(void *pvoid, int argc, char **argv, char **azColName){//!首先判断以下argc, 如果查询到纪录的字段数目有问题,就不用再处理下去了。........//!然后判断argv[0], argv[1], argv[2], argv[3]数据是否有效。如果无效,做相应处理。代码略........//!暂时存储Info tmpInfo;tmpInfo.ID = atoi(argv[0]); //!将字符串转为inttmpInfo.AGE = atoi(argv[3]);tmpInfo.NAME = argv[1];tmpInfo.ADDRESS = argv[2];//!巧妙的一步,讨厌回调函数的朋友, 是不是讨厌的没有理由?全局变量再也不用了A* pA = (A*) pvoid;//!将暂存纪录推入vectorA->InfoList.push_back(tmpInfo);//!完成工作return 0;}int A::getDB(){sqlite3 *db;......sqlite3_open(....);.......//!这里传递的是this指针,当然也可以传&InfoList。那样callback中做一点小变动就行了。sqlite3_exec(db, SqlCMD, callback, this, &zErrMsg);.......sqlite3_close(db);return 0;}A::A(){//!清除列表InfoList.clear();//!读取数据库并将数据放到vectorInfoList中。 getDB();}===========================================================阅读(5864) | 评论(0) | 转发(0) |