上一篇介绍的sqlite3_exec 是使用回调来执行对select结果的操作,你得声明一个函数,如果这个函数是类成员函数,你还不得不把它声明成static的(要问为什么?这又是C++基础了。C++成员函数实际上隐藏了一个参数:this,C++调用类的成员函数的时候,隐含把类指针当成函数的第一个参数传递进去。结果,这造成跟前面说的sqlite 回调函数的参数不相符。只有当把成员函数声明成static 时,它才没有多余的隐含的this参数)。
有时候你还是想要非回调的select 查询。这可以通过sqlite3_get_table 函数做到。
- 1 int sqlite3_get_table(
- 2 sqlite3 *db, <span style="color:#009900;">/* An open database */</span>
- 3 const char *zSql, <span style="color:#009900;">/* SQL to be evaluated */</span>
- 4 char ***pazResult, <span style="color:#009900;">/* Results of the query */</span>
- 5 int *pnRow, <span style="color:#009900;">/* Number of result rows written here */</span>
- 6 int *pnColumn, <span style="color:#009900;">/* Number of result columns written here */</span>
- 7 char **pzErrmsg <span style="color:#009900;">/* Error msg written here */</span>
- 8 );
- 9 void sqlite3_free_table(char **result);
第1个参数不再多说,看前面的例子。 第2个参数是sql 语句,跟sqlite3_exec 里的sql 是一样的。是一个很普通的以\0结尾的char*字符串。 第3个参数是查询结果,它依然一维数组(不要以为是二维数组,更不要以为是三维数组)。它内存布局是:字段名称,后面是紧接着是每个字段的值。下面用例子来说事。 第4个参数是查询出多少条记录(即查出多少行,不包括字段名那行)。 第5个参数是多少个字段(多少列)。 第6个参数是错误信息,跟前面一样,这里不多说了。
pazResult返回的字符串数量实际上是(*pnRow+1)*(*pnColumn),因为前(*pnColumn)个是字段名
修改上篇的例子,使用sqlite3_get_table,来去的结果集:
- #include <iostream>
- 2 using namespace std;
- 3 #include "sqlite/sqlite3.h"
- 4 int callback(void*,int,char**,char**);
- 5 int main()
- 6 {
- 7 sqlite3* db;
- 8 int nResult = sqlite3_open("test.db",&db);
- 9 if (nResult != SQLITE_OK)
- 10 {
- 11 cout<<"打开数据库失败:"<<sqlite3_errmsg(db)<<endl;
- 12 return 0;
- 13 }
- 14 else
- 15 {
- 16 cout<<"数据库打开成功"<<endl;
- 17 }
- 18
- 19 char* errmsg;
- 20
- 21 nResult = sqlite3_exec(db,"create table MyTable(id integer primary key autoincrement,name varchar(100))",NULL,NULL,&errmsg);
- 22 if (nResult != SQLITE_OK)
- 23 {
- 24 sqlite3_close(db);
- 25 cout<<errmsg;
- 26 sqlite3_free(errmsg);
- 27 return 0;
- 28 }
- 29 string strSql;
- 30 strSql+="begin;\n";
- 31 for (int i=0;i<100;i++)
- 32 {
- 33 strSql+="insert into MyTable values(null,'heh');\n";
- 34 }
- 35 strSql+="commit;";
- 36 //cout<<strSql<<endl;
- 37
- 38 nResult = sqlite3_exec(db,strSql.c_str(),NULL,NULL,&errmsg);
- 39
- 40 if (nResult != SQLITE_OK)
- 41 {
- 42 sqlite3_close(db);
- 43 cout<<errmsg<<endl;
- 44 sqlite3_free(errmsg);
- 45 return 0;
- 46 }
- 47
- 48 strSql = "select * from MyTable";
- <span style="color:#009900;">49 //nResult = sqlite3_exec(db,strSql.c_str(),callback,NULL,&errmsg);</span>
- 50 char** pResult;
- 51 int nRow;
- 52 int nCol;
- 53 nResult = sqlite3_get_table(db,strSql.c_str(),&pResult,&nRow,&nCol,&errmsg);
- 54 if (nResult != SQLITE_OK)
- 55 {
- 56 sqlite3_close(db);
- 57 cout<<errmsg<<endl;
- 58 sqlite3_free(errmsg);
- 59 return 0;
- 60 }
- 61
- 62 string strOut;
- 63 int nIndex = nCol;
- 64 for(int i=0;i<nRow;i++)
- 65 {
- 66 for(int j=0;j<nCol;j++)
- 67 {
- 68 strOut+=pResult[j];
- 69 strOut+=":";
- 70 strOut+=pResult[nIndex];
- 71 strOut+="\n";
- 72 ++nIndex;
- 73 }
- 74 }
- 75 sqlite3_free_table(pResult);
- 76 cout<<strOut<<endl;
- 77 sqlite3_close(db);
- 78 return 0;
- 79 }
- <span style="color:#009900;">80 /*
- 81 int callback(void* ,int nCount,char** pValue,char** pName)
- 82 {
- 83 string s;
- 84 for(int i=0;i<nCount;i++)
- 85 {
- 86 s+=pName[i];
- 87 s+=":";
- 88 s+=pValue[i];
- 89 s+="\n";
- 90 }
- 91 cout<<s<<endl;
- 92 return 0;
- 93 }*/</span>