说明:应用和测试均在以下环境中运行通过
本项目是在VS2005下,C++语言,sqlite3.7.14版本,开发板mini2440,wince6.0
工程先拷贝:Wincesqlite_DLL.lib,Wincesqlite_DLL.dll,sqlite3.h和数据库文件Temp-Humi.db,到对应的工程文件中
sqlite 3.0提供了很多API函数,还有一些数据结构和预定义(#defines). 不过你们可以放心,这些接口使用起来不复杂. 最简单的程序仍然使用三个函数就可以完成: sqlite3_open(),sqlite3_exec(),和 sqlite3_close(). 要是想更好的控制数据库引擎的执行,可以使用提供的sqlite3_prepare()函数把sql语句编译成字节码,然后在使用sqlite3_step()函数来执行编译后的字节码. 以sqlite3_column_开头的一组API函数用来获取查询结果集中的信息. 许多接口函数都是成对出现的,同时有UTF-8和UTF-16两个版本. 并且提供了一组函数用来执行用户自定义的sql函数和文本排序函数.
int sqlite3_open(const char*,sqlite3**);
第一个参数:文件路径,注意wince下只有绝对路劲,关于如何获取wince下的绝对路径可以参考另外一篇文章:
sqlite3_exec 函数依然像它在sqlite2中一样承担着很多的工作.该函数的第二个参数中可以编译和执行零个或多个sql语句. 查询的结果返回给回调函数. 在sqlite3里,sqlite3_exec一般是被准备sql语句接口封装起来使用的。
typedef int (*sqlite_callback)(void*,int,char**,char**);
int sqlite3_exec(sqlite3*,const char *sql,sqlite_callback,void*,char**);
第一个参数不再说了,是前面open函数得到的指针。
第二个参数const char *sql 是一条 sql 语句,以\0结尾。
第三个参数sqlite3_callback 是回调,当这条语句执行之后,sqlite3会去调用你提供的这个函数。
第四个参数void * 是你所提供的指针,你可以传递任何一个指针参数到这里,这个参数最终会传到回调函数里面,这个指针比较重要,可以用来作参数的传递。如果不需要传递指针给回调函数,可以填NULL。
第五个参数char ** errmsg 是错误信息。注意是指针的指针。sqlite3里面有很多固定的错误信息。执行 sqlite3_exec 之后,执行失败时可以查阅这个指针(直接 printf(“%s\n”,errmsg))得到一串字符串信息,这串信息告诉你错在什么地方。sqlite3_exec函数通过修改你传入的指针的指针,把你提供的指针指向错误提示信息,这样sqlite3_exec函数外面就可以通过这个char*得到具体错误提示。
说明:通常sqlite3_callback 和它后面的 void * 这两个位置都可以填 NULL。填NULL表示你不需要回调。比如你做 insert 操作,做 delete 操作,就没有必要使用回调。而当你做 select 时,就要使用回调,因为 sqlite3 把数据查出来,得通过回调告诉你查出了什么数据。
上面介绍的 sqlite3_exec 是使用回调来执行 select 操作。还有一个方法可以直接查询而不需要回调。回调的好处是:代码可以更加整齐,但是用回调很麻烦,你得声明一个函数,如果这个函数是类成员函数,你还不得不把它声明成 static 的(因为C++成员函数实际上隐藏了一个参数:this,C++调用类的成员函数的时候,隐含把类指针当成函数的第一个参数传递进去。结果,这造成跟前面说的 sqlite 回调函数的参数不相符。只有当把成员函数声明成 static 时,它才没有多余的隐含的this参数)。
不使用回调函数,可以通过 sqlite3_get_table 函数查询
int sqlite3_get_table(sqlite3*,char ***resultp,int *nrow,int *ncolumn,char **errmsg );
第一个参数不再多说,看前面的例子。
第二个参数是 sql 语句,跟 sqlite3_exec 里的 sql 是一样的。是一个很普通的以\0结尾的char *字符串。
第三个参数是查询结果,它依然一维数组(不要以为是二维数组,更不要以为是三维数组)。它内存布局是:第一行是字段名称,后面是紧接着是每个字段的值。
第四个参数是查询出多少条记录(即查出多少行)。
第五个参数是多少个字段(多少列)。
第六个参数是错误信息。
工程文件,源代码下载http://download.csdn.net/detail/mjx91282041/4743958
测试代码:
sqlite3 *db;// int rc; char *zErrMsg;//sqlite执行错误返回的字符指针 //打开sqlite的数据库文件, //特别说明:若找不到文件,sqlite会自己创建一个同名db文件 rc = sqlite3_open("Program Files\\WincesqliteTest2\\Temp-Humi.db",&db); if( rc != sqlITE_OK ){ sqlite3_close(db); printf("The sqlite3 database open error!"); } //插入数据,两种格式都行,ID为primary //char *pStr = "INSERT INTO SensorData(ID,SensorID,温度,湿度,Time)values( NULL,1003,31.0,23.5,'20120501421900')" ; char *pStr= "INSERT INTO \"SensorData\" values( NULL,'20120501421900');" ; rc = sqlite3_exec( db,pStr,&zErrMsg ); if (rc==sqlITE_OK) { printf("Insert data to the Temp-Humi.db successed"); }else printf("插入记录失败,错误码:%d,错误原因:%s\n",rc,zErrMsg ); //查询数据库有两种方式,回调函数和非回调函数 //使用回调函数 // rc = sqlite3_exec( db,"select SensorID,time from SensorData",sqliteQueryResultCallBack,NULL,&zErrMsg ); //查询数据,不使用回调函数 char** pResult; int nRow; int nCol; rc = sqlite3_get_table(db,&pResult,&nRow,&nCol,&zErrMsg); if (rc != sqlITE_OK) { sqlite3_close(db); sqlite3_free(zErrMsg); } //网上的显示例子 /* string strOut; int nIndex = nCol; for(int i=0;i<nRow;i++) { for(int j=0;j<nCol;j++) { strOut+=pResult[j]; strOut+=":"; strOut+=pResult[nIndex]; strOut+="\n"; ++nIndex; } } sqlite3_free_table(pResult); cout<<strOut<<endl; */ //理解内存布局后自己写的显示 //pResult的内存布局是:字段名称,后面是紧接着是每个字段的值 int nIndex = nCol; for(int i=0;i<nRow;i++) { for(int j=0;j<nCol;j++) { printf("%s:%s\r\n",pResult[j],pResult[nIndex++]); } } sqlite3_free_table(pResult); // 关闭数据库 sqlite3_close( db );原文链接:https://www.f2er.com/sqlite/201657.html