wget http://www.sqlite.org/2017/sqlite-autoconf-3160200.tar.gz
tar xvzf sqlite-autoconf-3160200.tar.gz
./configure --host=arm-himix200-linux --prefix=/home/zjucad/wangzhiqiang/toolDir/sqlite-autoconf-3160200/libs
make
make install
按順序執行上述命令後sqlite的連結庫和頭文件等就會出現在prefix目錄下
基本的使用流程
sqlite3_open()->sqlite3_prepare_v2()->sqlite3_step()->sqlite3_column()->sqlite3_finalize()->sqlite3_close()
具體介紹:
int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
打開一個資料庫,第一個參數為資料庫的路徑,注意這裡不能為:memory:,這表示存在內存中,第二個參數為返回,返回這個資料庫的handle,函數返回值是int,成功則返回SQLITE_OK,失敗的話可以通過sqlite3_errmsg()查看錯誤信息。
註:sqlite還有個sqlite3_open_v2()函數,添加一些flag,看著不太常用。
int sqlite3_prepare_v2(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
準備資料庫語句的上下文,相當於編譯sql語句,最後由step函數執行編譯好的語句,ppStmt需要自己首先定義好,最後一個參數基本傳NULL。
註:sqlite還有個sqlite3_prepare()函數,但是現在官方推薦使用v2版本,有錯誤v2版本能夠立即暴露出來。
一般使用sqlite3_prepare_v2()都是和sqlite3_bind_xxx()系列函數一起使用,例如執行插入語句,使用sqlite3_bind_xxx()可以動態綁定某些參數的值,後續給出示例代碼。
int sqlite3_step(sqlite3_stmt*);
執行資料庫語句
int sqlite3_reset(sqlite3_stmt *pStmt);
重置資料庫上下文,當需要重新bind參數時可以使用這個函數,避免多次prepare。
int sqlite3_finalize(sqlite3_stmt *pStmt);
刪除資料庫語句的上下文,調用了sqlite3_prepare_v2()後無論成功失敗都需要調用,避免內存洩漏。
int sqlite3_close(sqlite3 *);
關閉資料庫
在執行查詢操作時,可能結果不止一條,那sqlite3_step()函數就會返回SQLITE_ROW直到所有結果都被查詢到會返回SQLITE_DONE,這裡每次sqlite3_step()返回SQLITE_ROW後都需要再次調用返回下一次查詢的結果。
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
double sqlite3_column_double(sqlite3_stmt*, int iCol);
int sqlite3_column_int(sqlite3_stmt*, int iCol);
sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
int sqlite3_column_type(sqlite3_stmt*, int iCol);
sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
執行查詢語句後需要使用這類函數,獲取查詢到的結果,第二個參數代表第幾列,需要根據資料庫表的每一列具體類型調用相應的函數,可以通過sqlite3_column_type()獲取某一列的類型,通過sqlite3_column_count()函數獲取這次查詢結果共有多少列。
在一些簡單的場景下也可以使用sqlite3的wrapper函數
主要有sqlite3_exec()和sqlite3_get_table()函數,相當於調用了sqlite3_prepare_v2()->sqlite3_step()->sqlite3_finalize()這個流程。
區別是sqlite3_exec()在查詢中需要添加回調函數,sqlite3_get_table()主要用在查詢上,沒有回調,會把查詢到的結果存到一塊地址。
int sqlite3_exec(
sqlite3*, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
void *, /* 1st argument to callback */
char **errmsg /* Error msg written here */
);
注意這裡的最後一個參數是錯誤信息,如果執行函數沒有返回SQLITE_OK,可以查看errmsg處的信息,這塊內存也需要自己手動調用sqlite3_free()來釋放。
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);
sqlite3_get_table()主要用在查詢上,會把查詢到的結果存到一塊地址。由調用者手動調用sqlite3_free_table()釋放內存。
sqlite3-column-text()等函數返回的地址不需要自己free,sqlite會在調用sqlite3_step() or sqlite3_reset() or sqlite3_finalize()時自動釋放
如何設置自增欄位
欄位是integer 的primary key就會自增
CREATE TABLE t1(
a INTEGER PRIMARY KEY,
b INTEGER
);
如上代碼,欄位a就會自增,最大值是9223372036854775807,如果insert超過了這個數量,就會返回SQLITE_FULL錯誤,但90%的資料庫行數可能不會超過這個數量。
sqlite3 *db_;
std::string sql =
"create table if not exists sqlite("
"id INTEGER primary key AUTOINCREMENT,"
"value int64 not null);";
char *err_msg = NULL;
int ret = sqlite3_exec(db_, sql.c_str(), NULL, 0, &err_msg);
if (ret != SQLITE_OK) {
std::cout << "create table error " << err_msg;
sqlite3_free(err_msg);
return false;
}
std::string sql =
"insert into sqlite(value) values(?1)";
sqlite3_stmt *stmt;
int ret = sqlite3_prepare_v2(db_, sql.c_str(), -1, &stmt, NULL);
if (ret != SQLITE_OK) {
std::cout << "prepare sql error " << ret << " " << sqlite3_errcode(db_);
return false;
}
if (sqlite3_bind_int64(stmt, 1, 1) != SQLITE_OK) {
std::cout << "bind timestamp error " << sqlite3_errcode(db_);
return false;
}
if (sqlite3_step(stmt) != SQLITE_DONE) {
std::cout << "step insert fail " << sqlite3_errcode(db_);
return false;
}
sqlite3_finalize(stmt);