標籤:
1.SQL訪問資料庫非常方便,只需簡單的三個函數:
sqlite3_open(char* szDbFileName, sqlite3 ** db)
sqlite3_exec(sqlite3 *db, char* szSqlCMD, callback, 0, char **zErrMsg)
sqlite3_close(sqlite3 *db)
static int callback(void *NotUsed, int argc, char **argv, char **azColName)
2.sqlite3_exec(),執行SQL命令:
int sqlite3_exec( sqlite3* db, /* An open database */ const char *sql, /* SQL to be executed */ sqlite_callback, /* Callback function 回呼函數名*/ void *data /* 1st argument to callback function 傳給回呼函數的第一個參數*/ char **errmsg /* Error msg written here */ );
sqlite3_exec()包含一個回叫(callback)機制,提供了一種從SELECT語句得到結果的方法。
sqlite3_exec()函數第3個參數是一個指向回叫函數的指標,如果提供了回叫函數,SQLite則會在執行SELECT語句時為遇到的每一條記錄都調用回叫函數,即sqlite3_exec()執行一條SQL語句,每返回一個結果,就執行一次sqlite_callback函數,方便我們對查詢到的資料進行處理。
3.callback()即回叫函數,傳給sqlite3_exec的回呼函數,用來顯示查詢結果,對每一條查詢結果調用一次該回呼函數:
typedef int (*sqlite3_callback)( void* data, /* Data provided in the 4th argument of sqlite3_exec() 由sqlite3_exec()的第4個參數傳遞*/ int ncols, /* The number of columns in row 查詢語句返回的欄位數目,即表頭列數*/ char** values, /* An array of strings representing fields in the row 查詢到的一條記錄的各欄位值,包含尋找到的所有資料*/ char** headers /* An array of strings representing column names 對應列的欄位名*/ );
其參數:
data:sqlite3_exec()傳入的第四個參數(this指標),通過data參數,可以傳入一些特殊的指標(如類指標、結構指標),然後在這裡強制轉換成對應的類型(這裡是void*類型,必須強制轉換成該類型才可用)。sqlite3_exec()和callback()都具有這個形式參數,此參數用處巨大,可以傳遞一個對象的指標給callback函數,再把void* 強制轉換成原來的類型,進行一些操作,比如壓棧。
values:是查詢記錄的資料數組指標,指向查詢結果的指標數組, 可以由 sqlite3_column_text() 得到。
headers:是表頭的列名數組指標,指向表頭名的指標數組, 可以由 sqlite3_column_name() 得到。
其傳回值為0或1:
返回零:sqlite3_exec()將繼續執行查詢。 返回非零:sqlite3_exec()將立即中斷查詢,且sqlite3_exec()將返回SQLITE_ABORT。
回呼函數傳參樣本:
TableID NAME ADDRESS AGE1 YSP ShangHai 222 HHB ShangHai 25select * from Table查詢到第一條記錄,回叫函數被調用一次: ncols = 4 (總共4個欄位) values[0]:“1”;values[1]:“YSP”;values[2]:“ShangHai”;values[3]:“22”
headers[0]:“ID”;headers[1]:“NAME”;headers[2]:“ADDRESS”;headers[3]:“AGE”
查詢到第二條記錄,回叫函數被調用第二次:
ncols = 4 (總共4個欄位)
values[0]:“1”;values[1]:HHB;values[2]:ShangHai;values[3]:25
headers[0]:ID;headers[1]:NAME;headers[2]:ADDRESS;headers[3]:AGE
注意:sqlite3_exec()查詢到的值都是char*類型,可能需要做類型轉換,以滿足要求。
如果某列的資料類型不是char*, 則可以對結果執行相關的轉換, 如:用atoi()把結果轉換為整數(integer), 如果是位元據, 則可以直接強制類型轉換, 如:(void*)values[i]。
程式樣本:
#include <stdio.h> #include <stdlib.h> #include "util.h" #pragma comment(lib, "sqlite3.lib") int callback(void* data, int ncols, char** values, char** headers); int main(int argc, char **argv) { sqlite3 *db; int rc; char *sql; char *zErr; char* data; rc = sqlite3_open("test.db", &db); if(rc) { fprintf(stderr, "Can‘t open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); exit(1); } data = "Callback function called"; sql = "insert into episodes (name, cid) values (‘Mackinaw Peaches‘, 1);" "select * from episodes;"; rc = sqlite3_exec(db, sql, callback, data, &zErr); if(rc != SQLITE_OK) { if (zErr != NULL) { fprintf(stderr, "SQL error: %s\n", zErr); sqlite3_free(zErr); } } sqlite3_close(db); return 0; } int callback(void* data, int ncols, char** values, char** headers) { int i; fprintf(stdout, "%s: ", (const char*)data); for(i=0; i < ncols; i++) { fprintf(stdout, "%s=%s ", headers[i], values[i]); } fprintf(stdout, "\n"); return 0; }
說明:對sqlite3_exec()執行結果中查詢到的每條記錄調用callback()函數。
每條記錄的相應欄位值存放於values數組,表頭存放於headers數組,可以完成相應資料處理。
SQLite來源程式分析之回叫機制