C++ sqlite3使用指南
掃描二維碼
隨時隨地手機看文章
我在客戶端開發(fā)時由于需要使用數(shù)據(jù)庫,于是選擇了輕巧的sqlite數(shù)據(jù)庫研究了一下,今天在這里和大家分享下我總結(jié)的sqlite使用文檔。
源碼下載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
按順序執(zhí)行上述命令后sqlite的鏈接庫和頭文件等就會出現(xiàn)在prefix目錄下
api使用基本的使用流程
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 */ ); 打開一個數(shù)據(jù)庫,第一個參數(shù)為數(shù)據(jù)庫的路徑,注意這里不能為:memory:,這表示存在內(nèi)存中,第二個參數(shù)為返回,返回這個數(shù)據(jù)庫的handle,函數(shù)返回值是int,成功則返回SQLITE_OK,失敗的話可以通過sqlite3_errmsg()查看錯誤信息。 注:sqlite還有個sqlite3_open_v2()函數(shù),添加一些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 */ ); 準備數(shù)據(jù)庫語句的上下文,相當于編譯sql語句,最后由step函數(shù)執(zhí)行編譯好的語句,ppStmt需要自己首先定義好,最后一個參數(shù)基本傳NULL。 注:sqlite還有個sqlite3_prepare()函數(shù),但是現(xiàn)在官方推薦使用v2版本,有錯誤v2版本能夠立即暴露出來。
一般使用sqlite3_prepare_v2()都是和sqlite3_bind_xxx()系列函數(shù)一起使用,例如執(zhí)行插入語句,使用sqlite3_bind_xxx()可以動態(tài)綁定某些參數(shù)的值,后續(xù)給出示例代碼。
int sqlite3_step(sqlite3_stmt*); 執(zhí)行數(shù)據(jù)庫語句
int sqlite3_reset(sqlite3_stmt *pStmt); 重置數(shù)據(jù)庫上下文,當需要重新bind參數(shù)時可以使用這個函數(shù),避免多次prepare。
int sqlite3_finalize(sqlite3_stmt *pStmt); 刪除數(shù)據(jù)庫語句的上下文,調(diào)用了sqlite3_prepare_v2()后無論成功失敗都需要調(diào)用,避免內(nèi)存泄漏。
int sqlite3_close(sqlite3 *); 關(guān)閉數(shù)據(jù)庫
在執(zhí)行查詢操作時,可能結(jié)果不止一條,那sqlite3_step()函數(shù)就會返回SQLITE_ROW直到所有結(jié)果都被查詢到會返回SQLITE_DONE,這里每次sqlite3_step()返回SQLITE_ROW后都需要再次調(diào)用返回下一次查詢的結(jié)果。
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); 執(zhí)行查詢語句后需要使用這類函數(shù),獲取查詢到的結(jié)果,第二個參數(shù)代表第幾列,需要根據(jù)數(shù)據(jù)庫表的每一列具體類型調(diào)用相應(yīng)的函數(shù),可以通過sqlite3_column_type()獲取某一列的類型,通過sqlite3_column_count()函數(shù)獲取這次查詢結(jié)果共有多少列。
在一些簡單的場景下也可以使用sqlite3的wrapper函數(shù)
主要有sqlite3_exec()和sqlite3_get_table()函數(shù),相當于調(diào)用了sqlite3_prepare_v2()->sqlite3_step()->sqlite3_finalize()這個流程。
區(qū)別是sqlite3_exec()在查詢中需要添加回調(diào)函數(shù),sqlite3_get_table()主要用在查詢上,沒有回調(diào),會把查詢到的結(jié)果存到一塊地址。
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 */ ); 注意這里的最后一個參數(shù)是錯誤信息,如果執(zhí)行函數(shù)沒有返回SQLITE_OK,可以查看errmsg處的信息,這塊內(nèi)存也需要自己手動調(diào)用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()主要用在查詢上,會把查詢到的結(jié)果存到一塊地址。由調(diào)用者手動調(diào)用sqlite3_free_table()釋放內(nèi)存。
注意事項
-
sqlite3-column-text()等函數(shù)返回的地址不需要自己free,sqlite會在調(diào)用sqlite3_step() or sqlite3_reset() or sqlite3_finalize()時自動釋放
-
如何設(shè)置自增字段
字段是integer 的primary key就會自增CREATE TABLE t1( a INTEGER PRIMARY KEY, b INTEGER );
如上代碼,字段a就會自增,最大值是9223372036854775807,如果insert超過了這個數(shù)量,就會返回SQLITE_FULL錯誤,但90%的數(shù)據(jù)庫行數(shù)可能不會超過這個數(shù)量。
示例代碼
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);





