說明:應用和測試均在以下環境中運行通過
本項目是在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函數和文本排序函數.
1、開啟資料庫函數:
int sqlite3_open(const char*, sqlite3**);
第一個參數:檔案路徑,注意wince下只有絕對路勁,關於如何擷取wince下的絕對路徑可以參考另外一篇文章:
第二個參數:是sqlite3指標的指標,用於擷取開啟的檔案
2、查詢資料庫函數——使用回呼函數
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 把資料查出來,得通過回調告訴你查出了什麼資料。
2、查詢資料庫函數——不使用回呼函數
上面介紹的 sqlite3_exec 是使用回調來執行 select 操作。還有一個方法可以直接查詢而不需要回調。回調的好處是:代碼可以更加整齊,但是用回調很麻煩,你得聲明一個函數,如果這個函數是類成員函數,你還不得不把它聲明成 static 的(因為C++成員函數實際上隱藏了一個參數:this,C++調用類的成員函數的時候,隱含把類指標當成函數的第一個參數傳遞進去。結果,這造成跟前面說的 sqlite 回呼函數的參數不相符。只有當把成員函式宣告成
static 時,它才沒有多餘的隱含的this參數)。
不使用回呼函數,可以通過 sqlite3_get_table 函數查詢
int sqlite3_get_table(sqlite3*, const char *sql, 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, 1003,31.0, 23.5, '20120501421900');" ;rc = sqlite3_exec( db , pStr , 0 , 0 , &zErrMsg );if (rc==SQLITE_OK){printf("Insert data to the Temp-Humi.db successed");}elseprintf("插入記錄失敗,錯誤碼:%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, "select SensorID,time from SensorData",&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 );