运行查询指令的时候,无法查询到信息,是不会进入回调函数的,可以利用这个点判断数据库里面是否有查询的记录。
技术细节稍后更新
—————————-2018.9.8更新————————————
首先回调函数一般是指,自己定义一个函数的功能,然后把函数作为参数传入另一个函数里面,在另一个函数里面会执行我们自己定义的函数,这个我们定义的函数叫回调函数。回调函数的参数需要符合另一个函数的要求,才能被传入、调用。而这另一个函数一般是我们无法直接更改内容的一个黑盒,但是我们可以通过自己定义的回调函数来操控程序。
c/c++的sqlite库中执行SQL命令的函数sqlite3_exec原型如下:
sqlite3_exec(sqlite3* pdb, const char *sql, sqlite_callback func, void *data, char **errmsg);
sqlite3* pdb是指向已经打开的数据库的指针;
const char * sql是需要执行的sql语句,注意在c++中如果是string的话需要传参的时候用c_str()更改一下类型;
sqlite_callback func是一个回调函数,如果不需要回调,可以传实参为NULL,使用select语句时,每产生一条记录都会调用一次回调函数;
void *data将会作为参数传入回调函数,作为回调函数的第一个参数,利用这点可以向回调函数中动态传入数据;
char errmsg保存执行命令时发生的错误,注意errmsg是char类型的,但是错误语句应该是char类型的,那么我们传入实参的时候就一个调用&取一个char类型的变量,这样就好了,sqlite3_exec执行完毕之后错误会保存在这个变量指向的字符串里面;
回调函数:
typedef int(*sqlite3_callback)(void*,int,char**,char**);
void*是exec里面的第四个参数,int是记录的列数,第一个char是一个二维数组,记录查到的值,第二个char保存键名
当使用sqlite3_exe执行select语句时,如果没有查询到记录,是不会报错的,那么怎么知道没有查到记录呢?
如果查到了相关记录,会调用回调函数,查询到的记录条数是0的话,就不会调用,可以利用sqlite3_exec的第四个void *参数,向回调函数里面传入一个变量,在回调函数中改变这个变量的值,在exec执行完毕之后判断变量的值是否被改变,这样就可以知道是否查询到了值。这样可以避免某些错误。
例如我在某个程序中写的代码:
static int callback_sqlite(void * data,int argc,char **argv,char **azColName){ int i=0; #ifdef _DEBUG_ printf("进入回调函数\n"); #endif string keys[]={"word","phonetic","pos","acceptation","orig","trans"}; for(i=0;i<argc;i++){ #ifdef _DEBUG_ printf("内存地址:%p\n",argv); printf("数据库查询中:%s\n",argv[i]); #endif (*(map<string,string>*)data).insert(pair<string,string>(keys[i],argv[i]?string(argv[i]):string("NULL"))); } #ifdef _DEBUG_ printf("退出回调函数\n"); #endif (*(map<string,string>*)data)["isExistWord"]="true"; return 0; } Interpretation inquire_core(sqlite3 * db,string word){ Interpretation tempTransDataObj; char *ErrorInfo=0; int rc; map<string,string> WordData; WordData.insert(pair<string,string>("isExistWord","false")); string sql_cmd="select word,ps,pos,acceptation,orig,trans from words where word=\'"; sql_cmd=sql_cmd+word+"\';"; rc=sqlite3_exec(db,sql_cmd.c_str(),callback_sqlite,(void *)&WordData,&ErrorInfo); if(rc!=SQLITE_OK){ cout<<"SQL ERROR:"<<ErrorInfo<<endl; sqlite3_free(ErrorInfo); exit(0); }else{ #ifdef _DEBUG_ cout<<"查询数据库成功"<<endl; #endif } sqlite3_close(db); map<string,string>::iterator it; it=WordData.find(string("isExistWord")); if(it->second!="true"){ return tempTransDataObj; } …… …… …… }