上一篇介紹的sqlite3_exec 是使用回調來執行對select結果的操作。還有一個方法可以直接查詢而不需要回調。但是,我個人感覺還是回調好,因為代碼可以更加整齊,只不過用回調很麻煩,你得聲明一個函數,如果這個函數是類成員函數,你還不得不把它聲明成static的(要問為什么?這又是C++基礎了。C++成員函數實際上隱藏了一個參數:this,C++調用類的成員函數的時候,隱含把類指針當成函數的第一個參數傳遞進去。結果,這造成跟前面說的sqlite 回調函數的參數不相符。只有當把成員函數聲明成static 時,它才沒有多余的隱含的this參數)。
雖然回調顯得代碼整齊,但有時候你還是想要非回調的select 查詢。這可以通過sqlite3_get_table 函數做到。
int sqlite3_get_table( sqlite3 *db, /* An open database */ const char *zSql, /* SQL to be evaluated */ char ***pazResult, /* Results of the query */ int *pnRow, /* Number of result rows written here */ int *pnColumn, /* Number of result columns written here */ char **pzErrmsg /* Error msg written here */ ); 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> using namespace std; #include "sqlite/sqlite3.h" int callback(void*,int,char**,char**); int main() { sqlite3* db; int nResult = sqlite3_open("test.db",&db); if (nResult != SQLITE_OK) { cout<<"打開數據庫失敗:"<<sqlite3_errmsg(db)<<endl; return 0; } else { cout<<"數據庫打開成功"<<endl; } char* errmsg; nResult = sqlite3_exec(db,"create table fuck(id integer primary key autoincrement,name varchar(100))",NULL,NULL,&errmsg); if (nResult != SQLITE_OK) { sqlite3_close(db); cout<<errmsg; sqlite3_free(errmsg); return 0; } string strSql; strSql+="begin;\n"; for (int i=0;i<100;i++) { strSql+="insert into fuck values(null,'heh');\n"; } strSql+="commit;"; //cout<<strSql<<endl; nResult = sqlite3_exec(db,strSql.c_str(),NULL,NULL,&errmsg); if (nResult != SQLITE_OK) { sqlite3_close(db); cout<<errmsg<<endl; sqlite3_free(errmsg); return 0; } strSql = "select * from fuck"; //nResult = sqlite3_exec(db,strSql.c_str(),callback,NULL,&errmsg); char** pResult; int nRow; int nCol; nResult = sqlite3_get_table(db,strSql.c_str(),&pResult,&nRow,&nCol,&errmsg); if (nResult != SQLITE_OK) { sqlite3_close(db); cout<<errmsg<<endl; sqlite3_free(errmsg); return 0; } 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; sqlite3_close(db); return 0; } /* int callback(void* ,int nCount,char** pValue,char** pName) { string s; for(int i=0;i<nCount;i++) { s+=pName[i]; s+=":"; s+=pValue[i]; s+="\n"; } cout<<s<<endl; return 0; }*/
修改自 董淳光